diff --git a/3rdparty/ext_poppler/CMakeLists.txt b/3rdparty/ext_poppler/CMakeLists.txt
index 76acb1f1a5..fe0fcbbb90 100644
--- a/3rdparty/ext_poppler/CMakeLists.txt
+++ b/3rdparty/ext_poppler/CMakeLists.txt
@@ -1,13 +1,13 @@
SET(PREFIX_ext_poppler "${EXTPREFIX}" )
ExternalProject_Add( ext_poppler
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
URL https://poppler.freedesktop.org/poppler-0.62.0.tar.xz
URL_MD5 42b801f2defaccb6b6cf1bf783ee1552
PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/no_tests.diff
INSTALL_DIR ${PREFIX_ext_poppler}
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PREFIX_ext_poppler} -DCMAKE_BUILD_TYPE=${GLOBAL_BUILD_TYPE} ${GLOBAL_PROFILE} -DBUILD_GTK_TESTS=OFF -DBUILD_QT5_TESTS=FALSE -BUILD_CPP_TESTS=FALSE -DENABLE_UTILS=FALSE -DENABLE_GLIB=FALSE -DENABLE_LIBOPENJPEG=none
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PREFIX_ext_poppler} -DCMAKE_BUILD_TYPE=${GLOBAL_BUILD_TYPE} ${GLOBAL_PROFILE} -DBUILD_GTK_TESTS=OFF -DBUILD_QT5_TESTS=FALSE -DBUILD_CPP_TESTS=FALSE -DENABLE_UTILS=FALSE -DENABLE_GLIB=FALSE -DENABLE_LIBOPENJPEG=none
UPDATE_COMMAND ""
)
diff --git a/libs/libkis/Krita.cpp b/libs/libkis/Krita.cpp
index fab9fdf42b..bf5ca9cfc2 100644
--- a/libs/libkis/Krita.cpp
+++ b/libs/libkis/Krita.cpp
@@ -1,423 +1,423 @@
/*
* Copyright (c) 2016 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "Krita.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "View.h"
#include "Document.h"
#include "Window.h"
#include "Extension.h"
#include "DockWidgetFactoryBase.h"
#include "Filter.h"
#include "InfoObject.h"
#include "Resource.h"
Krita* Krita::s_instance = 0;
struct Krita::Private {
Private() {}
QList extensions;
bool batchMode {false};
Notifier *notifier{new Notifier()};
};
Krita::Krita(QObject *parent)
: QObject(parent)
, d(new Private)
{
qRegisterMetaType();
connect(KisPart::instance(), SIGNAL(sigWindowAdded(KisMainWindow*)), SLOT(mainWindowAdded(KisMainWindow*)));
}
Krita::~Krita()
{
qDeleteAll(d->extensions);
delete d->notifier;
delete d;
}
QList Krita::actions() const
{
KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow();
if (!mainWindow) {
return QList();
}
KActionCollection *actionCollection = mainWindow->actionCollection();
return actionCollection->actions();
}
QAction *Krita::action(const QString &name) const
{
KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow();
if (!mainWindow) {
return 0;
}
KActionCollection *actionCollection = mainWindow->actionCollection();
QAction *action = actionCollection->action(name);
return action;
}
Document* Krita::activeDocument() const
{
KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow();
if (!mainWindow) {
return 0;
}
KisView *view = mainWindow->activeView();
if (!view) {
return 0;
}
KisDocument *document = view->document();
return new Document(document);
}
void Krita::setActiveDocument(Document* value)
{
Q_FOREACH(KisView *view, KisPart::instance()->views()) {
if (view->document() == value->document().data()) {
view->activateWindow();
break;
}
}
}
bool Krita::batchmode() const
{
return d->batchMode;
}
void Krita::setBatchmode(bool value)
{
d->batchMode = value;
}
QList Krita::documents() const
{
QList ret;
foreach(QPointer doc, KisPart::instance()->documents()) {
ret << new Document(doc);
}
return ret;
}
QStringList Krita::filters() const
{
QStringList ls = KisFilterRegistry::instance()->keys();
std::sort(ls.begin(), ls.end());
return ls;
}
Filter *Krita::filter(const QString &name) const
{
if (!filters().contains(name)) return 0;
Filter *filter = new Filter();
filter->setName(name);
KisFilterSP f = KisFilterRegistry::instance()->value(name);
KisFilterConfigurationSP fc = f->defaultConfiguration();
InfoObject *info = new InfoObject(fc);
filter->setConfiguration(info);
return filter;
}
QStringList Krita::colorModels() const
{
QSet colorModelsIds;
QList ids = KoColorSpaceRegistry::instance()->colorModelsList(KoColorSpaceRegistry::AllColorSpaces);
Q_FOREACH(KoID id, ids) {
colorModelsIds << id.id();
}
return colorModelsIds.toList();
}
QStringList Krita::colorDepths(const QString &colorModel) const
{
QSet colorDepthsIds;
QList ids = KoColorSpaceRegistry::instance()->colorDepthList(colorModel, KoColorSpaceRegistry::AllColorSpaces);
Q_FOREACH(KoID id, ids) {
colorDepthsIds << id.id();
}
return colorDepthsIds.toList();
}
QStringList Krita::filterStrategies() const
{
return KisFilterStrategyRegistry::instance()->keys();
}
QStringList Krita::profiles(const QString &colorModel, const QString &colorDepth) const
{
QSet profileNames;
QString id = KoColorSpaceRegistry::instance()->colorSpaceId(colorModel, colorDepth);
QList profiles = KoColorSpaceRegistry::instance()->profilesFor(id);
Q_FOREACH(const KoColorProfile *profile, profiles) {
profileNames << profile->name();
}
QStringList r = profileNames.toList();
r.sort();
return r;
}
bool Krita::addProfile(const QString &profilePath)
{
KoColorSpaceEngine *iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc");
return iccEngine->addProfile(profilePath);
}
Notifier* Krita::notifier() const
{
return d->notifier;
}
QString Krita::version() const
{
return KritaVersionWrapper::versionString(true);
}
QList Krita::views() const
{
QList ret;
foreach(QPointer view, KisPart::instance()->views()) {
ret << new View(view);
}
return ret;
}
Window *Krita::activeWindow() const
{
KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow();
if (!mainWindow) {
return 0;
}
return new Window(mainWindow);
}
QList Krita::windows() const
{
QList ret;
foreach(QPointer mainWin, KisPart::instance()->mainWindows()) {
ret << new Window(mainWin);
}
return ret;
}
QMap Krita::resources(const QString &type) const
{
QMap resources = QMap ();
if (type.toLower() == "pattern") {
KoResourceServer* server = KoResourceServerProvider::instance()->patternServer();
Q_FOREACH (KoResourceSP res, server->resources()) {
resources[res->name()] = new Resource(res);
}
}
else if (type.toLower() == "gradient") {
KoResourceServer* server = KoResourceServerProvider::instance()->gradientServer();
Q_FOREACH (KoResourceSP res, server->resources()) {
resources[res->name()] = new Resource(res);
}
}
else if (type.toLower() == "brush") {
KisBrushResourceServer* server = KisBrushServer::instance()->brushServer();
Q_FOREACH (KisBrushSP res, server->resources()) {
resources[res->name()] = new Resource(res);
}
}
else if (type.toLower() == "preset") {
KisPaintOpPresetResourceServer* server = KisResourceServerProvider::instance()->paintOpPresetServer();
Q_FOREACH (KisPaintOpPresetSP res, server->resources()) {
resources[res->name()] = new Resource(res);
}
}
else if (type.toLower() == "palette") {
KoResourceServer* server = KoResourceServerProvider::instance()->paletteServer();
Q_FOREACH (KoResourceSP res, server->resources()) {
resources[res->name()] = new Resource(res);
}
}
else if (type.toLower() == "workspace") {
KoResourceServer< KisWorkspaceResource >* server = KisResourceServerProvider::instance()->workspaceServer();
Q_FOREACH (KoResourceSP res, server->resources()) {
resources[res->name()] = new Resource(res);
}
}
return resources;
}
QStringList Krita::recentDocuments() const
{
KConfigGroup grp = KSharedConfig::openConfig()->group(QString("RecentFiles"));
QStringList keys = grp.keyList();
QStringList recentDocuments;
for(int i = 0; i <= keys.filter("File").count(); i++)
recentDocuments << grp.readEntry(QString("File%1").arg(i), QString(""));
return recentDocuments;
}
Document* Krita::createDocument(int width, int height, const QString &name, const QString &colorModel, const QString &colorDepth, const QString &profile, double resolution)
{
KisDocument *document = KisPart::instance()->createDocument();
KisPart::instance()->addDocument(document);
const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, profile);
Q_ASSERT(cs);
QColor qc(Qt::white);
qc.setAlpha(0);
KoColor bgColor(qc, cs);
- if (!document->newImage(name, width, height, cs, bgColor, true, 1, "", double(resolution / 72) )) {
+ if (!document->newImage(name, width, height, cs, bgColor, KisConfig::RASTER_LAYER, 1, "", double(resolution / 72) )) {
return 0;
}
Q_ASSERT(document->image());
return new Document(document);
}
Document* Krita::openDocument(const QString &filename)
{
KisDocument *document = KisPart::instance()->createDocument();
document->setFileBatchMode(this->batchmode());
KisPart::instance()->addDocument(document);
document->openUrl(QUrl::fromLocalFile(filename), KisDocument::DontAddToRecent);
document->setFileBatchMode(false);
return new Document(document);
}
Window* Krita::openWindow()
{
KisMainWindow *mw = KisPart::instance()->createMainWindow();
return new Window(mw);
}
void Krita::addExtension(Extension* extension)
{
d->extensions.append(extension);
}
QList< Extension* > Krita::extensions()
{
return d->extensions;
}
void Krita::writeSetting(const QString &group, const QString &name, const QString &value)
{
KConfigGroup grp = KSharedConfig::openConfig()->group(group);
grp.writeEntry(name, value);
}
QString Krita::readSetting(const QString &group, const QString &name, const QString &defaultValue)
{
KConfigGroup grp = KSharedConfig::openConfig()->group(group);
return grp.readEntry(name, defaultValue);
}
QIcon Krita::icon(QString &iconName) const
{
return KisIconUtils::loadIcon(iconName);
}
void Krita::addDockWidgetFactory(DockWidgetFactoryBase* factory)
{
KoDockRegistry::instance()->add(factory);
}
Krita* Krita::instance()
{
if (!s_instance)
{
s_instance = new Krita;
}
return s_instance;
}
/**
* Scripter.fromVariant(variant)
* variant is a QVariant
* returns instance of QObject-subclass
*
* This is a helper method for PyQt because PyQt cannot cast a variant to a QObject or QWidget
*/
QObject *Krita::fromVariant(const QVariant& v)
{
if (v.canConvert< QWidget* >())
{
QObject* obj = qvariant_cast< QWidget* >(v);
return obj;
}
else if (v.canConvert< QObject* >())
{
QObject* obj = qvariant_cast< QObject* >(v);
return obj;
}
else
return 0;
}
QString Krita::krita_i18n(const QString &text)
{
return i18n(text.toUtf8().constData());
}
void Krita::mainWindowAdded(KisMainWindow *kisWindow)
{
Q_FOREACH(Extension *extension, d->extensions) {
Window window(kisWindow);
extension->createActions(&window);
}
}
diff --git a/libs/libqml/DocumentManager.cpp b/libs/libqml/DocumentManager.cpp
index 9df83a5680..c53b148800 100644
--- a/libs/libqml/DocumentManager.cpp
+++ b/libs/libqml/DocumentManager.cpp
@@ -1,311 +1,311 @@
/* This file is part of the KDE project
* Copyright (C) 2012 Arjen Hiemstra
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "DocumentManager.h"
#include "ProgressProxy.h"
#include "Settings.h"
#include "RecentFileManager.h"
#include
#include
#include
#include
#include
#include
#include
class DocumentManager::Private
{
public:
Private()
: proxy(0)
, document(0)
, settingsManager(0)
, recentFileManager(0)
, newDocWidth(0)
, newDocHeight(0)
, newDocResolution(0)
, importingDocument(false)
, temporaryFile(false)
{ }
ProgressProxy* proxy;
QPointer document;
Settings* settingsManager;
RecentFileManager* recentFileManager;
QString saveAsFilename;
QString openDocumentFilename;
int newDocWidth, newDocHeight; float newDocResolution;
bool importingDocument;
QVariantMap newDocOptions;
bool temporaryFile;
};
DocumentManager *DocumentManager::sm_instance = 0;
KisDocument* DocumentManager::document() const
{
return d->document;
}
ProgressProxy* DocumentManager::progressProxy() const
{
return d->proxy;
}
Settings* DocumentManager::settingsManager() const
{
return d->settingsManager;
}
void DocumentManager::setSettingsManager(Settings* newManager)
{
d->settingsManager = newManager;
}
RecentFileManager* DocumentManager::recentFileManager() const
{
return d->recentFileManager;
}
bool DocumentManager::isTemporaryFile() const
{
return d->temporaryFile;
}
void DocumentManager::newDocument(int width, int height, float resolution)
{
closeDocument();
d->newDocWidth = width;
d->newDocHeight = height;
d->newDocResolution = resolution;
QTimer::singleShot(300, this, SLOT(delayedNewDocument()));
}
void DocumentManager::newDocument(const QVariantMap& options)
{
closeDocument();
d->newDocOptions = options;
QTimer::singleShot(300, this, SLOT(delayedNewDocument()));
}
void DocumentManager::delayedNewDocument()
{
d->document = KisPart::instance()->createDocument();
if (qAppName().contains("sketch")) {
d->document->setFileBatchMode(true);
}
if (d->newDocOptions.isEmpty())
{
const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(0);
QColor qc(Qt::white);
qc.setAlpha(0);
KoColor bgColor(qc, cs);
- d->document->newImage("New Image", d->newDocWidth, d->newDocHeight, KoColorSpaceRegistry::instance()->rgb8(), bgColor, true, 2, "", d->newDocResolution);
+ d->document->newImage("New Image", d->newDocWidth, d->newDocHeight, KoColorSpaceRegistry::instance()->rgb8(), bgColor, KisConfig::RASTER_LAYER, 2, "", d->newDocResolution);
d->document->resetURL();
}
else if (d->newDocOptions.contains("template")) {
QUrl url(d->newDocOptions.value("template").toString().remove("template://"));
bool ok = d->document->loadNativeFormat(url.toLocalFile());
d->document->setModified(false);
d->document->undoStack()->clear();
if (ok) {
QString mimeType = KisMimeDatabase::mimeTypeForFile(url.toLocalFile());
// in case this is a open document template remove the -template from the end
mimeType.remove( QRegExp( "-template$" ) );
d->document->setMimeTypeAfterLoading(mimeType);
d->document->resetURL();
}
}
else
{
QString name = d->newDocOptions.value("name", "New Image").toString();
int width = d->newDocOptions.value("width").toInt();
int height = d->newDocOptions.value("height").toInt();
// internal resolution is pixels per point, not ppi
float res = d->newDocOptions.value("resolution", 72.0f).toFloat() / 72.0f;
QString colorModelId = d->newDocOptions.value("colorModelId").toString();
QString colorDepthId = d->newDocOptions.value("colorDepthId").toString();
QString colorProfileId = d->newDocOptions.value("colorProfileId").toString();
const KoColorSpace* cs;
if(colorModelId.isEmpty() || colorDepthId.isEmpty() || colorProfileId.isEmpty()) {
cs = KoColorSpaceRegistry::instance()->rgb8();
}
else
{
cs = KoColorSpaceRegistry::instance()->colorSpace(colorModelId, colorDepthId, colorProfileId);
}
QColor background = d->newDocOptions.value("backgroundColor", QColor("white")).value();
background.setAlphaF(d->newDocOptions.value("backgroundOpacity", 1.0f).toFloat());
KoColor bg(background, cs);
- d->document->newImage(name, width, height, cs, bg, true, 1, "", res);
+ d->document->newImage(name, width, height, cs, bg, KisConfig::RASTER_LAYER, 1, "", res);
d->document->resetURL();
}
KisPart::instance()->addDocument(d->document);
d->temporaryFile = true;
emit documentChanged();
}
void DocumentManager::openDocument(const QString& document, bool import)
{
closeDocument();
d->openDocumentFilename = document;
d->importingDocument = import;
QTimer::singleShot(300, this, SLOT(delayedOpenDocument()));
}
void DocumentManager::delayedOpenDocument()
{
d->document = KisPart::instance()->createDocument();
if (qAppName().contains("sketch")) {
d->document->setFileBatchMode(true);
}
connect(d->document, SIGNAL(completed()), this, SLOT(onLoadCompleted()));
connect(d->document, SIGNAL(canceled(QString)), this, SLOT(onLoadCanceled(QString)));
// TODO: still needed?
d->document->setModified(false);
if (d->importingDocument)
d->document->importDocument(QUrl::fromLocalFile(d->openDocumentFilename));
else
d->document->openUrl(QUrl::fromLocalFile(d->openDocumentFilename));
// TODO: handle fail of open/import
d->recentFileManager->addRecent(d->openDocumentFilename);
KisPart::instance()->addDocument(d->document);
d->temporaryFile = false;
}
// Separate from openDocument to handle async loading (remote URLs)
void DocumentManager::onLoadCompleted()
{
KisDocument *newdoc = qobject_cast(sender());
disconnect(newdoc, SIGNAL(completed()), this, SLOT(onLoadCompleted()));
disconnect(newdoc, SIGNAL(canceled(QString)), this, SLOT(onLoadCanceled(QString)));
emit documentChanged();
}
void DocumentManager::onLoadCanceled(const QString &/*errMsg*/)
{
// if (!errMsg.isEmpty()) // empty when canceled by user
// QMessageBox::critical(this, i18nc("@title:window", "Krita"), errMsg);
// ... can't delete the document, it's the one who emitted the signal...
KisDocument* newdoc = qobject_cast(sender());
Q_ASSERT(newdoc);
disconnect(newdoc, SIGNAL(completed()), this, SLOT(onLoadCompleted()));
disconnect(newdoc, SIGNAL(canceled(QString)), this, SLOT(onLoadCanceled(QString)));
}
void DocumentManager::closeDocument()
{
if (d->document) {
emit aboutToDeleteDocument();
d->document->closeUrl(false);
//d->document->deleteLater();
d->document = 0;
}
}
bool DocumentManager::save()
{
// if (d->document->save())
// {
// d->recentFileManager->addRecent(d->document->url().toLocalFile());
// d->settingsManager->setCurrentFile(d->document->url().toLocalFile());
// emit documentSaved();
// return true;
// }
return false;
}
void DocumentManager::saveAs(const QString &filename, const QString &mimetype)
{
d->document->setMimeType(mimetype.toLatin1());
d->saveAsFilename = filename;
// Yes. This is a massive hack. Basically, we need to wait a little while, to ensure
// the save call happens late enough for a variety of UI things to happen first.
// A second seems like a long time, but well, we do have file system interaction here,
// so for now, we can get away with it.
QTimer::singleShot(300, this, SLOT(delayedSaveAs()));
}
void DocumentManager::delayedSaveAs()
{
//d->document->saveAs(QUrl::fromLocalFile(d->saveAsFilename));
d->settingsManager->setCurrentFile(d->saveAsFilename);
d->recentFileManager->addRecent(d->saveAsFilename);
emit documentSaved();
}
void DocumentManager::reload()
{
QUrl url = d->document->url();
closeDocument();
d->openDocumentFilename = url.toLocalFile();
QTimer::singleShot(0, this, SLOT(delayedOpenDocument()));
}
void DocumentManager::setTemporaryFile(bool temp)
{
d->temporaryFile = temp;
emit documentSaved();
}
DocumentManager* DocumentManager::instance()
{
if (!sm_instance) {
sm_instance = new DocumentManager(QCoreApplication::instance());
}
return sm_instance;
}
DocumentManager::DocumentManager(QObject* parent)
: QObject(parent), d(new Private)
{
d->proxy = new ProgressProxy(this);
d->recentFileManager = new RecentFileManager(this);
}
DocumentManager::~DocumentManager()
{
delete d;
}
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Black.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Black.otf
index e69de29bb2..ca6aa8b422 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Black.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Black.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BlackIt.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BlackIt.otf
index e69de29bb2..623cad710e 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BlackIt.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BlackIt.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Bold.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Bold.otf
index e69de29bb2..3646cb5849 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Bold.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Bold.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BoldIt.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BoldIt.otf
index e69de29bb2..adb1ae8706 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BoldIt.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-BoldIt.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLight.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLight.otf
index e69de29bb2..74bc5f8fe8 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLight.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLight.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLightIt.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLightIt.otf
index e69de29bb2..7031e12d9e 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLightIt.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-ExtraLightIt.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-It.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-It.otf
index e69de29bb2..767472d35b 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-It.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-It.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Light.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Light.otf
index e69de29bb2..2e6da7c308 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Light.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Light.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-LightIt.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-LightIt.otf
index e69de29bb2..556f475831 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-LightIt.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-LightIt.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Regular.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Regular.otf
index e69de29bb2..b9c6c5d3a9 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Regular.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Regular.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Semibold.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Semibold.otf
index e69de29bb2..0c0636ec48 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Semibold.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-Semibold.otf differ
diff --git a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-SemiboldIt.otf b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-SemiboldIt.otf
index e69de29bb2..b8922caf06 100644
Binary files a/libs/libqml/qmlthemes/default/fonts/SourceSansPro-SemiboldIt.otf and b/libs/libqml/qmlthemes/default/fonts/SourceSansPro-SemiboldIt.otf differ
diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt
index f5c42e403e..dfff101f23 100644
--- a/libs/ui/CMakeLists.txt
+++ b/libs/ui/CMakeLists.txt
@@ -1,594 +1,596 @@
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/qtlockedfile
${EXIV2_INCLUDE_DIR}
)
include_directories(SYSTEM
${EIGEN3_INCLUDE_DIR}
${OCIO_INCLUDE_DIR}
)
add_subdirectory( tests )
if (APPLE)
find_library(FOUNDATION_LIBRARY Foundation)
find_library(APPKIT_LIBRARY AppKit)
endif ()
set(kritaui_LIB_SRCS
canvas/kis_canvas_widget_base.cpp
canvas/kis_canvas2.cpp
canvas/kis_canvas_updates_compressor.cpp
canvas/kis_canvas_controller.cpp
canvas/kis_paintop_transformation_connector.cpp
canvas/kis_display_color_converter.cpp
canvas/kis_display_filter.cpp
canvas/kis_exposure_gamma_correction_interface.cpp
canvas/kis_tool_proxy.cpp
canvas/kis_canvas_decoration.cc
canvas/kis_coordinates_converter.cpp
canvas/kis_grid_manager.cpp
canvas/kis_grid_decoration.cpp
canvas/kis_grid_config.cpp
canvas/kis_prescaled_projection.cpp
canvas/kis_qpainter_canvas.cpp
canvas/kis_projection_backend.cpp
canvas/kis_update_info.cpp
canvas/kis_image_patch.cpp
canvas/kis_image_pyramid.cpp
canvas/kis_infinity_manager.cpp
canvas/kis_change_guides_command.cpp
canvas/kis_guides_decoration.cpp
canvas/kis_guides_manager.cpp
canvas/kis_guides_config.cpp
canvas/kis_snap_config.cpp
canvas/kis_snap_line_strategy.cpp
canvas/KisSnapPointStrategy.cpp
dialogs/kis_about_application.cpp
dialogs/kis_dlg_adj_layer_props.cc
dialogs/kis_dlg_adjustment_layer.cc
dialogs/kis_dlg_filter.cpp
dialogs/kis_dlg_generator_layer.cpp
dialogs/kis_dlg_file_layer.cpp
dialogs/kis_dlg_filter.cpp
dialogs/kis_dlg_stroke_selection_properties.cpp
dialogs/kis_dlg_image_properties.cc
dialogs/kis_dlg_layer_properties.cc
dialogs/kis_dlg_preferences.cc
dialogs/slider_and_spin_box_sync.cpp
dialogs/kis_dlg_blacklist_cleanup.cpp
dialogs/kis_dlg_layer_style.cpp
dialogs/kis_dlg_png_import.cpp
dialogs/kis_dlg_import_image_sequence.cpp
dialogs/kis_delayed_save_dialog.cpp
dialogs/KisSessionManagerDialog.cpp
dialogs/KisNewWindowLayoutDialog.cpp
flake/kis_node_dummies_graph.cpp
flake/kis_dummies_facade_base.cpp
flake/kis_dummies_facade.cpp
flake/kis_node_shapes_graph.cpp
flake/kis_node_shape.cpp
flake/kis_shape_controller.cpp
flake/kis_shape_layer.cc
flake/kis_shape_layer_canvas.cpp
flake/kis_shape_selection.cpp
flake/kis_shape_selection_canvas.cpp
flake/kis_shape_selection_model.cpp
flake/kis_take_all_shapes_command.cpp
brushhud/kis_uniform_paintop_property_widget.cpp
brushhud/kis_brush_hud.cpp
brushhud/kis_round_hud_button.cpp
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
kis_bookmarked_configurations_model.cc
kis_bookmarked_filter_configurations_model.cc
KisPaintopPropertiesBase.cpp
kis_canvas_resource_provider.cpp
kis_derived_resources.cpp
kis_categories_mapper.cpp
kis_categorized_list_model.cpp
kis_categorized_item_delegate.cpp
kis_clipboard.cc
kis_config.cc
kis_control_frame.cpp
kis_composite_ops_model.cc
kis_paint_ops_model.cpp
kis_cursor.cc
kis_cursor_cache.cpp
kis_custom_pattern.cc
kis_file_layer.cpp
kis_change_file_layer_command.h
kis_safe_document_loader.cpp
kis_splash_screen.cpp
kis_filter_manager.cc
kis_filters_model.cc
kis_histogram_view.cc
KisImageBarrierLockerWithFeedback.cpp
kis_image_manager.cc
kis_image_view_converter.cpp
kis_import_catcher.cc
kis_layer_manager.cc
kis_mask_manager.cc
kis_mimedata.cpp
kis_node_commands_adapter.cpp
kis_node_manager.cpp
kis_node_juggler_compressed.cpp
kis_node_selection_adapter.cpp
kis_node_insertion_adapter.cpp
KisNodeDisplayModeAdapter.cpp
kis_node_model.cpp
kis_node_filter_proxy_model.cpp
kis_model_index_converter_base.cpp
kis_model_index_converter.cpp
kis_model_index_converter_show_all.cpp
kis_painting_assistant.cc
kis_painting_assistants_decoration.cpp
KisDecorationsManager.cpp
kis_paintop_box.cc
kis_paintop_option.cpp
kis_paintop_options_model.cpp
kis_paintop_settings_widget.cpp
kis_popup_palette.cpp
kis_png_converter.cpp
kis_preference_set_registry.cpp
KisResourceServerProvider.cpp
KisResourceBundleServerProvider.cpp
KisSelectedShapesProxy.cpp
kis_selection_decoration.cc
kis_selection_manager.cc
KisSelectionActionsAdapter.cpp
kis_statusbar.cc
kis_zoom_manager.cc
kis_favorite_resource_manager.cpp
kis_workspace_resource.cpp
kis_action.cpp
kis_action_manager.cpp
KisActionPlugin.cpp
kis_canvas_controls_manager.cpp
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
opengl/kis_opengl_image_textures.cpp
opengl/kis_texture_tile.cpp
opengl/kis_opengl_shader_loader.cpp
opengl/kis_texture_tile_info_pool.cpp
opengl/KisOpenGLUpdateInfoBuilder.cpp
kis_fps_decoration.cpp
tool/KisToolChangesTracker.cpp
tool/KisToolChangesTrackerData.cpp
tool/kis_selection_tool_helper.cpp
tool/kis_selection_tool_config_widget_helper.cpp
tool/kis_rectangle_constraint_widget.cpp
tool/kis_shape_tool_helper.cpp
tool/kis_tool.cc
tool/kis_delegated_tool_policies.cpp
tool/kis_tool_freehand.cc
tool/kis_speed_smoother.cpp
tool/kis_painting_information_builder.cpp
tool/kis_stabilized_events_sampler.cpp
tool/kis_tool_freehand_helper.cpp
tool/kis_tool_multihand_helper.cpp
tool/kis_figure_painting_tool_helper.cpp
tool/kis_tool_paint.cc
tool/kis_tool_shape.cc
tool/kis_tool_ellipse_base.cpp
tool/kis_tool_rectangle_base.cpp
tool/kis_tool_polyline_base.cpp
tool/kis_tool_utils.cpp
tool/kis_resources_snapshot.cpp
tool/kis_smoothing_options.cpp
tool/KisStabilizerDelayedPaintHelper.cpp
tool/KisStrokeSpeedMonitor.cpp
tool/strokes/freehand_stroke.cpp
tool/strokes/KisStrokeEfficiencyMeasurer.cpp
tool/strokes/kis_painter_based_stroke_strategy.cpp
tool/strokes/kis_filter_stroke_strategy.cpp
tool/strokes/kis_color_picker_stroke_strategy.cpp
tool/strokes/KisFreehandStrokeInfo.cpp
tool/strokes/KisMaskedFreehandStrokePainter.cpp
tool/strokes/KisMaskingBrushRenderer.cpp
tool/strokes/KisMaskingBrushCompositeOpFactory.cpp
tool/strokes/move_stroke_strategy.cpp
tool/KisSelectionToolFactoryBase.cpp
tool/KisToolPaintFactoryBase.cpp
widgets/kis_cmb_composite.cc
widgets/kis_cmb_contour.cpp
widgets/kis_cmb_gradient.cpp
widgets/kis_paintop_list_widget.cpp
widgets/kis_cmb_idlist.cc
widgets/kis_color_space_selector.cc
widgets/kis_advanced_color_space_selector.cc
widgets/kis_cie_tongue_widget.cpp
widgets/kis_tone_curve_widget.cpp
widgets/kis_curve_widget.cpp
widgets/kis_custom_image_widget.cc
widgets/kis_image_from_clipboard_widget.cpp
widgets/kis_double_widget.cc
widgets/kis_filter_selector_widget.cc
widgets/kis_gradient_chooser.cc
widgets/kis_iconwidget.cc
widgets/kis_mask_widgets.cpp
widgets/kis_meta_data_merge_strategy_chooser_widget.cc
widgets/kis_multi_bool_filter_widget.cc
widgets/kis_multi_double_filter_widget.cc
widgets/kis_multi_integer_filter_widget.cc
widgets/kis_multipliers_double_slider_spinbox.cpp
widgets/kis_paintop_presets_popup.cpp
widgets/kis_tool_options_popup.cpp
widgets/kis_paintop_presets_chooser_popup.cpp
widgets/kis_paintop_presets_save.cpp
widgets/kis_paintop_preset_icon_library.cpp
widgets/kis_pattern_chooser.cc
widgets/kis_preset_chooser.cpp
widgets/kis_progress_widget.cpp
widgets/kis_selection_options.cc
widgets/kis_scratch_pad.cpp
widgets/kis_scratch_pad_event_filter.cpp
widgets/kis_preset_selector_strip.cpp
widgets/kis_slider_spin_box.cpp
widgets/KisSelectionPropertySlider.cpp
widgets/kis_size_group.cpp
widgets/kis_size_group_p.cpp
widgets/kis_wdg_generator.cpp
widgets/kis_workspace_chooser.cpp
widgets/kis_categorized_list_view.cpp
widgets/kis_widget_chooser.cpp
widgets/kis_tool_button.cpp
widgets/kis_floating_message.cpp
widgets/kis_lod_availability_widget.cpp
widgets/kis_color_label_selector_widget.cpp
widgets/kis_color_filter_combo.cpp
widgets/kis_elided_label.cpp
widgets/kis_stopgradient_slider_widget.cpp
widgets/kis_preset_live_preview_view.cpp
widgets/KisScreenColorPicker.cpp
widgets/KoDualColorButton.cpp
widgets/KoStrokeConfigWidget.cpp
widgets/KoFillConfigWidget.cpp
-
+ widgets/KisLayerStyleAngleSelector.cpp
+
KisPaletteEditor.cpp
dialogs/KisDlgPaletteEditor.cpp
widgets/KisNewsWidget.cpp
widgets/KisGamutMaskToolbar.cpp
utils/kis_document_aware_spin_box_unit_manager.cpp
input/kis_input_manager.cpp
input/kis_input_manager_p.cpp
input/kis_extended_modifiers_mapper.cpp
input/kis_abstract_input_action.cpp
input/kis_tool_invocation_action.cpp
input/kis_pan_action.cpp
input/kis_alternate_invocation_action.cpp
input/kis_rotate_canvas_action.cpp
input/kis_zoom_action.cpp
input/kis_change_frame_action.cpp
input/kis_gamma_exposure_action.cpp
input/kis_show_palette_action.cpp
input/kis_change_primary_setting_action.cpp
input/kis_abstract_shortcut.cpp
input/kis_native_gesture_shortcut.cpp
input/kis_single_action_shortcut.cpp
input/kis_stroke_shortcut.cpp
input/kis_shortcut_matcher.cpp
input/kis_select_layer_action.cpp
input/KisQtWidgetsTweaker.cpp
input/KisInputActionGroup.cpp
operations/kis_operation.cpp
operations/kis_operation_configuration.cpp
operations/kis_operation_registry.cpp
operations/kis_operation_ui_factory.cpp
operations/kis_operation_ui_widget.cpp
operations/kis_filter_selection_operation.cpp
actions/kis_selection_action_factories.cpp
actions/KisPasteActionFactory.cpp
actions/KisTransformToolActivationCommand.cpp
input/kis_touch_shortcut.cpp
kis_document_undo_store.cpp
kis_gui_context_command.cpp
kis_gui_context_command_p.cpp
input/kis_tablet_debugger.cpp
input/kis_input_profile_manager.cpp
input/kis_input_profile.cpp
input/kis_shortcut_configuration.cpp
input/config/kis_input_configuration_page.cpp
input/config/kis_edit_profiles_dialog.cpp
input/config/kis_input_profile_model.cpp
input/config/kis_input_configuration_page_item.cpp
input/config/kis_action_shortcuts_model.cpp
input/config/kis_input_type_delegate.cpp
input/config/kis_input_mode_delegate.cpp
input/config/kis_input_button.cpp
input/config/kis_input_editor_delegate.cpp
input/config/kis_mouse_input_editor.cpp
input/config/kis_wheel_input_editor.cpp
input/config/kis_key_input_editor.cpp
processing/fill_processing_visitor.cpp
kis_asl_layer_style_serializer.cpp
kis_psd_layer_style_resource.cpp
canvas/kis_mirror_axis.cpp
kis_abstract_perspective_grid.cpp
KisApplication.cpp
KisAutoSaveRecoveryDialog.cpp
KisDetailsPane.cpp
KisDocument.cpp
KisCloneDocumentStroke.cpp
KisNodeDelegate.cpp
kis_node_view_visibility_delegate.cpp
KisNodeToolTip.cpp
KisNodeView.cpp
kis_node_view_color_scheme.cpp
KisImportExportFilter.cpp
KisFilterEntry.cpp
KisImportExportManager.cpp
KisImportExportUtils.cpp
kis_async_action_feedback.cpp
KisMainWindow.cpp
KisOpenPane.cpp
KisPart.cpp
KisPrintJob.cpp
KisTemplate.cpp
KisTemplateCreateDia.cpp
KisTemplateGroup.cpp
KisTemplates.cpp
KisTemplatesPane.cpp
KisTemplateTree.cpp
KisUndoActionsUpdateManager.cpp
KisView.cpp
thememanager.cpp
kis_mainwindow_observer.cpp
KisViewManager.cpp
kis_mirror_manager.cpp
qtlockedfile/qtlockedfile.cpp
qtsingleapplication/qtlocalpeer.cpp
qtsingleapplication/qtsingleapplication.cpp
KisResourceBundle.cpp
KisResourceBundleManifest.cpp
kis_md5_generator.cpp
KisApplicationArguments.cpp
KisNetworkAccessManager.cpp
KisMultiFeedRSSModel.cpp
KisRemoteFileFetcher.cpp
KisSaveGroupVisitor.cpp
KisWindowLayoutResource.cpp
KisWindowLayoutManager.cpp
KisSessionResource.cpp
KisReferenceImagesDecoration.cpp
KisReferenceImage.cpp
flake/KisReferenceImagesLayer.cpp
flake/KisReferenceImagesLayer.h
)
if(WIN32)
set(kritaui_LIB_SRCS
${kritaui_LIB_SRCS}
input/wintab/kis_tablet_support_win.cpp
input/wintab/kis_screen_size_choice_dialog.cpp
qtlockedfile/qtlockedfile_win.cpp
input/wintab/kis_tablet_support_win8.cpp
opengl/kis_opengl_win.cpp
)
endif()
set(kritaui_LIB_SRCS
${kritaui_LIB_SRCS}
kis_animation_frame_cache.cpp
kis_animation_cache_populator.cpp
KisAsyncAnimationRendererBase.cpp
KisAsyncAnimationCacheRenderer.cpp
KisAsyncAnimationFramesSavingRenderer.cpp
dialogs/KisAsyncAnimationRenderDialogBase.cpp
dialogs/KisAsyncAnimationCacheRenderDialog.cpp
dialogs/KisAsyncAnimationFramesSaveDialog.cpp
canvas/kis_animation_player.cpp
kis_animation_importer.cpp
KisSyncedAudioPlayback.cpp
KisFrameDataSerializer.cpp
KisFrameCacheStore.cpp
KisFrameCacheSwapper.cpp
KisAbstractFrameCacheSwapper.cpp
KisInMemoryFrameCacheSwapper.cpp
input/wintab/drawpile_tablettester/tablettester.cpp
input/wintab/drawpile_tablettester/tablettest.cpp
)
if (UNIX)
set(kritaui_LIB_SRCS
${kritaui_LIB_SRCS}
qtlockedfile/qtlockedfile_unix.cpp
)
if(NOT USE_QT_XCB)
set(kritaui_LIB_SRCS
${kritaui_LIB_SRCS}
input/wintab/kis_tablet_support.cpp
)
endif()
if(NOT APPLE AND NOT USE_QT_XCB)
set(kritaui_LIB_SRCS
${kritaui_LIB_SRCS}
input/wintab/qxcbconnection_xi2.cpp
input/wintab/qxcbconnection.cpp
input/wintab/kis_xi2_event_filter.cpp
)
endif()
endif()
if(APPLE)
set(kritaui_LIB_SRCS
${kritaui_LIB_SRCS}
osx.mm
)
endif()
ki18n_wrap_ui(kritaui_LIB_SRCS
widgets/KoFillConfigWidget.ui
widgets/KoStrokeConfigWidget.ui
forms/wdgdlgpngimport.ui
forms/wdgfullscreensettings.ui
forms/wdgautogradient.ui
forms/wdggeneralsettings.ui
forms/wdgperformancesettings.ui
forms/wdggenerators.ui
forms/wdgbookmarkedconfigurationseditor.ui
forms/wdgapplyprofile.ui
forms/wdgcustompattern.ui
forms/wdglayerproperties.ui
forms/wdgcolorsettings.ui
forms/wdgtabletsettings.ui
forms/wdgcolorspaceselector.ui
forms/wdgcolorspaceselectoradvanced.ui
forms/wdgdisplaysettings.ui
forms/kis_previewwidgetbase.ui
forms/kis_matrix_widget.ui
forms/wdgselectionoptions.ui
forms/wdggeometryoptions.ui
forms/wdgnewimage.ui
forms/wdgimageproperties.ui
forms/wdgmaskfromselection.ui
forms/wdgmasksource.ui
forms/wdgfilterdialog.ui
forms/wdgmetadatamergestrategychooser.ui
forms/wdgpaintoppresets.ui
forms/wdgpaintopsettings.ui
forms/wdgdlggeneratorlayer.ui
forms/wdgdlgfilelayer.ui
forms/wdgfilterselector.ui
forms/wdgfilternodecreation.ui
forms/wdgmultipliersdoublesliderspinbox.ui
forms/wdgnodequerypatheditor.ui
forms/wdgpresetselectorstrip.ui
forms/wdgsavebrushpreset.ui
forms/wdgpreseticonlibrary.ui
forms/wdgdlgblacklistcleanup.ui
forms/wdgrectangleconstraints.ui
forms/wdgimportimagesequence.ui
forms/wdgstrokeselectionproperties.ui
forms/KisDetailsPaneBase.ui
forms/KisOpenPaneBase.ui
forms/wdgstopgradienteditor.ui
forms/wdgsessionmanager.ui
forms/wdgnewwindowlayout.ui
forms/KisWelcomePage.ui
forms/WdgDlgPaletteEditor.ui
forms/KisNewsPage.ui
forms/wdgGamutMaskToolbar.ui
brushhud/kis_dlg_brush_hud_config.ui
dialogs/kis_delayed_save_dialog.ui
input/config/kis_input_configuration_page.ui
input/config/kis_edit_profiles_dialog.ui
input/config/kis_input_configuration_page_item.ui
input/config/kis_mouse_input_editor.ui
input/config/kis_wheel_input_editor.ui
input/config/kis_key_input_editor.ui
layerstyles/wdgBevelAndEmboss.ui
layerstyles/wdgblendingoptions.ui
layerstyles/WdgColorOverlay.ui
layerstyles/wdgContour.ui
layerstyles/wdgdropshadow.ui
layerstyles/WdgGradientOverlay.ui
layerstyles/wdgInnerGlow.ui
layerstyles/wdglayerstyles.ui
layerstyles/WdgPatternOverlay.ui
layerstyles/WdgSatin.ui
layerstyles/WdgStroke.ui
layerstyles/wdgstylesselector.ui
layerstyles/wdgTexture.ui
+ layerstyles/wdgKisLayerStyleAngleSelector.ui
wdgsplash.ui
input/wintab/kis_screen_size_choice_dialog.ui
input/wintab/drawpile_tablettester/tablettest.ui
)
QT5_WRAP_CPP(kritaui_HEADERS_MOC KisNodePropertyAction_p.h)
add_library(kritaui SHARED ${kritaui_HEADERS_MOC} ${kritaui_LIB_SRCS} )
generate_export_header(kritaui BASE_NAME kritaui)
target_link_libraries(kritaui KF5::CoreAddons KF5::Completion KF5::I18n KF5::ItemViews Qt5::Network
kritaimpex kritacolor kritaimage kritalibbrush kritawidgets kritawidgetutils kritaresources ${PNG_LIBRARIES} ${EXIV2_LIBRARIES}
)
if (HAVE_QT_MULTIMEDIA)
target_link_libraries(kritaui Qt5::Multimedia)
endif()
if (NOT WIN32 AND NOT APPLE)
target_link_libraries(kritaui ${X11_X11_LIB}
${X11_Xinput_LIB}
${XCB_LIBRARIES})
endif()
if(APPLE)
target_link_libraries(kritaui ${FOUNDATION_LIBRARY})
target_link_libraries(kritaui ${APPKIT_LIBRARY})
endif ()
target_link_libraries(kritaui ${OPENEXR_LIBRARIES})
# Add VSync disable workaround
if(NOT WIN32 AND NOT APPLE)
target_link_libraries(kritaui ${CMAKE_DL_LIBS} Qt5::X11Extras)
endif()
if(X11_FOUND)
target_link_libraries(kritaui Qt5::X11Extras ${X11_LIBRARIES})
endif()
target_include_directories(kritaui
PUBLIC
$
$
$
$
$
$
$
)
set_target_properties(kritaui
PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION}
)
install(TARGETS kritaui ${INSTALL_TARGETS_DEFAULT_ARGS})
if (APPLE)
install(FILES osx.stylesheet DESTINATION ${DATA_INSTALL_DIR}/krita)
endif ()
diff --git a/libs/ui/KisApplicationArguments.cpp b/libs/ui/KisApplicationArguments.cpp
index df58592699..a2029e0f9e 100644
--- a/libs/ui/KisApplicationArguments.cpp
+++ b/libs/ui/KisApplicationArguments.cpp
@@ -1,336 +1,336 @@
/*
* Copyright (c) 2015 Boudewijn Rempt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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 "KisApplicationArguments.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct Q_DECL_HIDDEN KisApplicationArguments::Private
{
Private()
{
}
QStringList filenames;
int dpiX {72};
int dpiY {72};
bool doTemplate {false};
bool exportAs {false};
QString exportFileName;
QString workspace;
QString windowLayout;
QString session;
bool canvasOnly {false};
bool noSplash {false};
bool fullScreen {false};
bool newImage {false};
QString colorModel {"RGBA"};
QString colorDepth {"U8"};
int width {2000};
int height {5000};
};
KisApplicationArguments::KisApplicationArguments()
: d(new Private)
{
}
KisApplicationArguments::~KisApplicationArguments()
{
}
KisApplicationArguments::KisApplicationArguments(const QApplication &app)
: d(new Private)
{
QCommandLineParser parser;
parser.addVersionOption();
parser.addHelpOption();
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("template"), i18n("Open a new document with a template")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("new-image"), i18n("Create a new image on startup.\n"
"Possible colorspace values are:\n"
" * RGBA\n"
" * XYZA\n"
" * LABA\n"
" * CMYKA\n"
" * GRAY\n"
" * YCbCrA\n"
"Possible channel depth arguments are\n"
" * U8 (8 bits integer)\n"
" * U16 (16 bits integer)\n"
" * F16 (16 bits floating point)\n"
" * F32 (32 bits floating point)\n"),
QLatin1String("colorspace,depth,width,height")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("workspace"), i18n("The name of the workspace to open Krita with"), QLatin1String("workspace")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("windowlayout"), i18n("The name of the window layout to open Krita with"), QLatin1String("windowlayout")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("load-session"), i18n("The name of the session to open Krita with"), QLatin1String("load-session"))); // NB: the argument "session" is already used by QGuiApplication
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("canvasonly"), i18n("Start Krita in canvas-only mode")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("nosplash"), i18n("Do not show the splash screen")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("fullscreen"), i18n("Start Krita in full-screen mode")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("dpi"), i18n("Override display DPI"), QLatin1String("dpiX,dpiY")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("export"), i18n("Export to the given filename and exit")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("export-filename"), i18n("Filename for export"), QLatin1String("filename")));
parser.addPositionalArgument(QLatin1String("[file(s)]"), i18n("File(s) or URL(s) to open"));
parser.process(app);
QString dpiValues = parser.value("dpi");
if (!dpiValues.isEmpty()) {
int sep = dpiValues.indexOf(QRegExp("[x, ]"));
bool ok = true;
if (sep != -1) {
d->dpiY = dpiValues.mid(sep + 1).toInt(&ok);
dpiValues.truncate(sep);
}
if (ok) {
d->dpiX = dpiValues.toInt(&ok);
if (ok) {
if (!d->dpiY)
d->dpiY = d->dpiX;
}
}
}
QString newImageValues = parser.value("new-image");
d->newImage = !newImageValues.isEmpty();
if (d->newImage) {
QStringList v = newImageValues.split(",");
if (v.size() != 4) {
d->newImage = false;
qWarning() << "Cannot create a new image: please specify colormodel, depth, width and height.";
}
d->colorModel = v[0].toUpper();
d->colorDepth = v[1].toUpper();
d->width = v[2].toInt();
d->height = v[3].toInt();
}
d->exportFileName = parser.value("export-filename");
d->workspace = parser.value("workspace");
d->windowLayout = parser.value("windowlayout");
d->session = parser.value("load-session");
d->doTemplate = parser.isSet("template");
d->exportAs = parser.isSet("export");
d->canvasOnly = parser.isSet("canvasonly");
d->noSplash = parser.isSet("nosplash");
d->fullScreen = parser.isSet("fullscreen");
const QDir currentDir = QDir::current();
Q_FOREACH (const QString &filename, parser.positionalArguments()) {
d->filenames << currentDir.absoluteFilePath(filename);
}
}
KisApplicationArguments::KisApplicationArguments(const KisApplicationArguments &rhs)
: d(new Private)
{
d->filenames = rhs.filenames();
d->dpiX = rhs.dpiX();
d->dpiY = rhs.dpiY();
d->doTemplate = rhs.doTemplate();
d->exportAs = rhs.exportAs();
d->exportFileName = rhs.exportFileName();
d->canvasOnly = rhs.canvasOnly();
d->workspace = rhs.workspace();
d->windowLayout = rhs.windowLayout();
d->session = rhs.session();
d->noSplash = rhs.noSplash();
d->fullScreen = rhs.fullScreen();
}
void KisApplicationArguments::operator=(const KisApplicationArguments &rhs)
{
d->filenames = rhs.filenames();
d->dpiX = rhs.dpiX();
d->dpiY = rhs.dpiY();
d->doTemplate = rhs.doTemplate();
d->exportAs = rhs.exportAs();
d->exportFileName = rhs.exportFileName();
d->canvasOnly = rhs.canvasOnly();
d->workspace = rhs.workspace();
d->windowLayout = rhs.windowLayout();
d->session = rhs.session();
d->noSplash = rhs.noSplash();
d->fullScreen = rhs.fullScreen();
}
QByteArray KisApplicationArguments::serialize()
{
QByteArray ba;
QBuffer buf(&ba);
buf.open(QIODevice::WriteOnly);
QDataStream ds(&buf);
ds.setVersion(QDataStream::Qt_5_0);
ds << d->filenames.count();
Q_FOREACH (const QString &filename, d->filenames) {
ds << filename;
}
ds << d->dpiX;
ds << d->dpiY;
ds << d->doTemplate;
ds << d->exportAs;
ds << d->exportFileName;
ds << d->workspace;
ds << d->windowLayout;
ds << d->session;
ds << d->canvasOnly;
ds << d->noSplash;
ds << d->fullScreen;
ds << d->newImage;
ds << d->height;
ds << d->width;
ds << d->height;
ds << d->colorModel;
ds << d->colorDepth;
buf.close();
return ba;
}
KisApplicationArguments KisApplicationArguments::deserialize(QByteArray &serialized)
{
KisApplicationArguments args;
QBuffer buf(&serialized);
buf.open(QIODevice::ReadOnly);
QDataStream ds(&buf);
ds.setVersion(QDataStream::Qt_5_0);
int count;
ds >> count;
for(int i = 0; i < count; ++i) {
QString s;
ds >> s;
args.d->filenames << s;
}
ds >> args.d->dpiX;
ds >> args.d->dpiY;
ds >> args.d->doTemplate;
ds >> args.d->exportAs;
ds >> args.d->exportFileName;
ds >> args.d->workspace;
ds >> args.d->windowLayout;
ds >> args.d->session;
ds >> args.d->canvasOnly;
ds >> args.d->noSplash;
ds >> args.d->fullScreen;
ds >> args.d->newImage;
ds >> args.d->height;
ds >> args.d->width;
ds >> args.d->height;
ds >> args.d->colorModel;
ds >> args.d->colorDepth;
buf.close();
return args;
}
QStringList KisApplicationArguments::filenames() const
{
return d->filenames;
}
int KisApplicationArguments::dpiX() const
{
return d->dpiX;
}
int KisApplicationArguments::dpiY() const
{
return d->dpiY;
}
bool KisApplicationArguments::doTemplate() const
{
return d->doTemplate;
}
bool KisApplicationArguments::exportAs() const
{
return d->exportAs;
}
QString KisApplicationArguments::exportFileName() const
{
return d->exportFileName;
}
QString KisApplicationArguments::workspace() const
{
return d->workspace;
}
QString KisApplicationArguments::windowLayout() const
{
return d->windowLayout;
}
QString KisApplicationArguments::session() const
{
return d->session;
}
bool KisApplicationArguments::canvasOnly() const
{
return d->canvasOnly;
}
bool KisApplicationArguments::noSplash() const
{
return d->noSplash;
}
bool KisApplicationArguments::fullScreen() const
{
return d->fullScreen;
}
bool KisApplicationArguments::doNewImage() const
{
return d->newImage;
}
KisDocument *KisApplicationArguments::image() const
{
KisDocument *doc = KisPart::instance()->createDocument();
const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(d->colorModel, d->colorDepth, "");
if (!cs) {
qWarning() << "Could not create the colorspace for the new image. Check the colorspace and depth arguments.";
return 0;
}
- doc->newImage(i18n("Unnamed"), d->width, d->height, cs, KoColor(QColor(Qt::white), cs), false, 1, "", 100.0);
+ doc->newImage(i18n("Unnamed"), d->width, d->height, cs, KoColor(QColor(Qt::white), cs), KisConfig::CANVAS_COLOR, 1, "", 100.0);
return doc;
}
diff --git a/libs/ui/KisDocument.cpp b/libs/ui/KisDocument.cpp
index ee4368393b..a0f8c8cf9a 100644
--- a/libs/ui/KisDocument.cpp
+++ b/libs/ui/KisDocument.cpp
@@ -1,1855 +1,1867 @@
/* This file is part of the Krita project
*
* Copyright (C) 2014 Boudewijn Rempt
*
* 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 "KisMainWindow.h" // XXX: remove
#include // XXX: remove
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#include
+#include
+#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Krita Image
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_layer_utils.h"
// Local
#include "KisViewManager.h"
#include "kis_clipboard.h"
#include "widgets/kis_custom_image_widget.h"
#include "canvas/kis_canvas2.h"
#include "flake/kis_shape_controller.h"
#include "kis_statusbar.h"
#include "widgets/kis_progress_widget.h"
#include "kis_canvas_resource_provider.h"
#include "KisResourceServerProvider.h"
#include "kis_node_manager.h"
#include "KisPart.h"
#include "KisApplication.h"
#include "KisDocument.h"
#include "KisImportExportManager.h"
#include "KisView.h"
#include "kis_grid_config.h"
#include "kis_guides_config.h"
#include "kis_image_barrier_lock_adapter.h"
#include "KisReferenceImagesLayer.h"
#include
#include "kis_config_notifier.h"
#include "kis_async_action_feedback.h"
#include "KisCloneDocumentStroke.h"
// Define the protocol used here for embedded documents' URL
// This used to "store" but QUrl didn't like it,
// so let's simply make it "tar" !
#define STORE_PROTOCOL "tar"
// The internal path is a hack to make QUrl happy and for document children
#define INTERNAL_PROTOCOL "intern"
#define INTERNAL_PREFIX "intern:/"
// Warning, keep it sync in koStore.cc
#include
using namespace std;
namespace {
constexpr int errorMessageTimeout = 5000;
constexpr int successMessageTimeout = 1000;
}
/**********************************************************
*
* KisDocument
*
**********************************************************/
//static
QString KisDocument::newObjectName()
{
static int s_docIFNumber = 0;
QString name; name.setNum(s_docIFNumber++); name.prepend("document_");
return name;
}
class UndoStack : public KUndo2Stack
{
public:
UndoStack(KisDocument *doc)
: KUndo2Stack(doc),
m_doc(doc)
{
}
void setIndex(int idx) override {
KisImageWSP image = this->image();
image->requestStrokeCancellation();
if(image->tryBarrierLock()) {
KUndo2Stack::setIndex(idx);
image->unlock();
}
}
void notifySetIndexChangedOneCommand() override {
KisImageWSP image = this->image();
image->unlock();
/**
* Some very weird commands may emit blocking signals to
* the GUI (e.g. KisGuiContextCommand). Here is the best thing
* we can do to avoid the deadlock
*/
while(!image->tryBarrierLock()) {
QApplication::processEvents();
}
}
void undo() override {
KisImageWSP image = this->image();
image->requestUndoDuringStroke();
if (image->tryUndoUnfinishedLod0Stroke() == UNDO_OK) {
return;
}
if(image->tryBarrierLock()) {
KUndo2Stack::undo();
image->unlock();
}
}
void redo() override {
KisImageWSP image = this->image();
if(image->tryBarrierLock()) {
KUndo2Stack::redo();
image->unlock();
}
}
private:
KisImageWSP image() {
KisImageWSP currentImage = m_doc->image();
Q_ASSERT(currentImage);
return currentImage;
}
private:
KisDocument *m_doc;
};
class Q_DECL_HIDDEN KisDocument::Private
{
public:
Private(KisDocument *q)
: docInfo(new KoDocumentInfo(q)) // deleted by QObject
, importExportManager(new KisImportExportManager(q)) // deleted manually
, autoSaveTimer(new QTimer(q))
, undoStack(new UndoStack(q)) // deleted by QObject
, m_bAutoDetectedMime(false)
, modified(false)
, readwrite(true)
, firstMod(QDateTime::currentDateTime())
, lastMod(firstMod)
, nserver(new KisNameServer(1))
, imageIdleWatcher(2000 /*ms*/)
, globalAssistantsColor(KisConfig(true).defaultAssistantsColor())
, savingLock(&savingMutex)
, batchMode(false)
{
if (QLocale().measurementSystem() == QLocale::ImperialSystem) {
unit = KoUnit::Inch;
} else {
unit = KoUnit::Centimeter;
}
}
Private(const Private &rhs, KisDocument *q)
: docInfo(new KoDocumentInfo(*rhs.docInfo, q))
, unit(rhs.unit)
, importExportManager(new KisImportExportManager(q))
, mimeType(rhs.mimeType)
, outputMimeType(rhs.outputMimeType)
, autoSaveTimer(new QTimer(q))
, undoStack(new UndoStack(q))
, guidesConfig(rhs.guidesConfig)
, m_bAutoDetectedMime(rhs.m_bAutoDetectedMime)
, m_url(rhs.m_url)
, m_file(rhs.m_file)
, modified(rhs.modified)
, readwrite(rhs.readwrite)
, firstMod(rhs.firstMod)
, lastMod(rhs.lastMod)
, nserver(new KisNameServer(*rhs.nserver))
, preActivatedNode(0) // the node is from another hierarchy!
, imageIdleWatcher(2000 /*ms*/)
, assistants(rhs.assistants) // WARNING: assistants should not store pointers to the document!
, globalAssistantsColor(rhs.globalAssistantsColor)
, paletteList(rhs.paletteList)
, gridConfig(rhs.gridConfig)
, savingLock(&savingMutex)
, batchMode(rhs.batchMode)
{
// TODO: clone assistants
}
~Private() {
// Don't delete m_d->shapeController because it's in a QObject hierarchy.
delete nserver;
}
KoDocumentInfo *docInfo = 0;
KoUnit unit;
KisImportExportManager *importExportManager = 0; // The filter-manager to use when loading/saving [for the options]
QByteArray mimeType; // The actual mimetype of the document
QByteArray outputMimeType; // The mimetype to use when saving
QTimer *autoSaveTimer;
QString lastErrorMessage; // see openFile()
QString lastWarningMessage;
int autoSaveDelay = 300; // in seconds, 0 to disable.
bool modifiedAfterAutosave = false;
bool isAutosaving = false;
bool disregardAutosaveFailure = false;
int autoSaveFailureCount = 0;
KUndo2Stack *undoStack = 0;
KisGuidesConfig guidesConfig;
bool m_bAutoDetectedMime = false; // whether the mimetype in the arguments was detected by the part itself
QUrl m_url; // local url - the one displayed to the user.
QString m_file; // Local file - the only one the part implementation should deal with.
QMutex savingMutex;
bool modified = false;
bool readwrite = false;
QDateTime firstMod;
QDateTime lastMod;
KisNameServer *nserver;
KisImageSP image;
KisImageSP savingImage;
KisNodeWSP preActivatedNode;
KisShapeController* shapeController = 0;
KoShapeController* koShapeController = 0;
KisIdleWatcher imageIdleWatcher;
QScopedPointer imageIdleConnection;
QList assistants;
QColor globalAssistantsColor;
KisSharedPtr referenceImagesLayer;
QList paletteList;
KisGridConfig gridConfig;
StdLockableWrapper savingLock;
bool modifiedWhileSaving = false;
QScopedPointer backgroundSaveDocument;
QPointer savingUpdater;
QFuture childSavingFuture;
KritaUtils::ExportFileJob backgroundSaveJob;
bool isRecovered = false;
bool batchMode { false };
void setImageAndInitIdleWatcher(KisImageSP _image) {
image = _image;
imageIdleWatcher.setTrackedImage(image);
if (image) {
imageIdleConnection.reset(
new KisSignalAutoConnection(
&imageIdleWatcher, SIGNAL(startedIdleMode()),
image.data(), SLOT(explicitRegenerateLevelOfDetail())));
}
}
class StrippedSafeSavingLocker;
};
class KisDocument::Private::StrippedSafeSavingLocker {
public:
StrippedSafeSavingLocker(QMutex *savingMutex, KisImageSP image)
: m_locked(false)
, m_image(image)
, m_savingLock(savingMutex)
, m_imageLock(image, true)
{
/**
* Initial try to lock both objects. Locking the image guards
* us from any image composition threads running in the
* background, while savingMutex guards us from entering the
* saving code twice by autosave and main threads.
*
* Since we are trying to lock multiple objects, so we should
* do it in a safe manner.
*/
m_locked = std::try_lock(m_imageLock, m_savingLock) < 0;
if (!m_locked) {
m_image->requestStrokeEnd();
QApplication::processEvents();
// one more try...
m_locked = std::try_lock(m_imageLock, m_savingLock) < 0;
}
}
~StrippedSafeSavingLocker() {
if (m_locked) {
m_imageLock.unlock();
m_savingLock.unlock();
}
}
bool successfullyLocked() const {
return m_locked;
}
private:
bool m_locked;
KisImageSP m_image;
StdLockableWrapper m_savingLock;
KisImageBarrierLockAdapter m_imageLock;
};
KisDocument::KisDocument()
: d(new Private(this))
{
connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
connect(d->undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(slotUndoStackCleanChanged(bool)));
connect(d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
setObjectName(newObjectName());
// preload the krita resources
KisResourceServerProvider::instance();
d->shapeController = new KisShapeController(this, d->nserver),
d->koShapeController = new KoShapeController(0, d->shapeController),
slotConfigChanged();
}
KisDocument::KisDocument(const KisDocument &rhs)
: QObject(),
d(new Private(*rhs.d, this))
{
connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
connect(d->undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(slotUndoStackCleanChanged(bool)));
connect(d->autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
setObjectName(rhs.objectName());
d->shapeController = new KisShapeController(this, d->nserver),
d->koShapeController = new KoShapeController(0, d->shapeController),
slotConfigChanged();
// clone the image with keeping the GUIDs of the layers intact
// NOTE: we expect the image to be locked!
setCurrentImage(rhs.image()->clone(true), false);
if (rhs.d->preActivatedNode) {
// since we clone uuid's, we can use them for lacating new
// nodes. Otherwise we would need to use findSymmetricClone()
d->preActivatedNode =
KisLayerUtils::findNodeByUuid(d->image->root(), rhs.d->preActivatedNode->uuid());
}
}
KisDocument::~KisDocument()
{
// wait until all the pending operations are in progress
waitForSavingToComplete();
/**
* Push a timebomb, which will try to release the memory after
* the document has been deleted
*/
KisPaintDevice::createMemoryReleaseObject()->deleteLater();
d->autoSaveTimer->disconnect(this);
d->autoSaveTimer->stop();
delete d->importExportManager;
// Despite being QObject they needs to be deleted before the image
delete d->shapeController;
delete d->koShapeController;
if (d->image) {
d->image->notifyAboutToBeDeleted();
/**
* WARNING: We should wait for all the internal image jobs to
* finish before entering KisImage's destructor. The problem is,
* while execution of KisImage::~KisImage, all the weak shared
* pointers pointing to the image enter an inconsistent
* state(!). The shared counter is already zero and destruction
* has started, but the weak reference doesn't know about it,
* because KisShared::~KisShared hasn't been executed yet. So all
* the threads running in background and having weak pointers will
* enter the KisImage's destructor as well.
*/
d->image->requestStrokeCancellation();
d->image->waitForDone();
// clear undo commands that can still point to the image
d->undoStack->clear();
d->image->waitForDone();
KisImageWSP sanityCheckPointer = d->image;
Q_UNUSED(sanityCheckPointer);
// The following line trigger the deletion of the image
d->image.clear();
// check if the image has actually been deleted
KIS_SAFE_ASSERT_RECOVER_NOOP(!sanityCheckPointer.isValid());
}
delete d;
}
bool KisDocument::reload()
{
// XXX: reimplement!
return false;
}
KisDocument *KisDocument::clone()
{
return new KisDocument(*this);
}
bool KisDocument::exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration)
{
QFileInfo filePathInfo(job.filePath);
if (filePathInfo.exists() && !filePathInfo.isWritable()) {
slotCompleteSavingDocument(job,
KisImportExportFilter::CreationError,
i18n("%1 cannot be written to. Please save under a different name.", job.filePath));
return false;
}
KisConfig cfg(true);
if (cfg.backupFile() && filePathInfo.exists()) {
KBackup::backupFile(job.filePath);
}
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!job.mimeType.isEmpty(), false);
const QString actionName =
job.flags & KritaUtils::SaveIsExporting ?
i18n("Exporting Document...") :
i18n("Saving Document...");
bool started =
initiateSavingInBackground(actionName,
this, SLOT(slotCompleteSavingDocument(KritaUtils::ExportFileJob,KisImportExportFilter::ConversionStatus,QString)),
job, exportConfiguration);
if (!started) {
emit canceled(QString());
}
return started;
}
bool KisDocument::exportDocument(const QUrl &url, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
{
using namespace KritaUtils;
SaveFlags flags = SaveIsExporting;
if (showWarnings) {
flags |= SaveShowWarnings;
}
return exportDocumentImpl(KritaUtils::ExportFileJob(url.toLocalFile(),
mimeType,
flags),
exportConfiguration);
}
bool KisDocument::saveAs(const QUrl &url, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
{
using namespace KritaUtils;
return exportDocumentImpl(ExportFileJob(url.toLocalFile(),
mimeType,
showWarnings ? SaveShowWarnings : SaveNone),
exportConfiguration);
}
bool KisDocument::save(bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
{
return saveAs(url(), mimeType(), showWarnings, exportConfiguration);
}
QByteArray KisDocument::serializeToNativeByteArray()
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
QScopedPointer filter(KisImportExportManager::filterForMimeType(nativeFormatMimeType(), KisImportExportManager::Export));
filter->setBatchMode(true);
filter->setMimeType(nativeFormatMimeType());
Private::StrippedSafeSavingLocker locker(&d->savingMutex, d->image);
if (!locker.successfullyLocked()) {
return byteArray;
}
d->savingImage = d->image;
if (filter->convert(this, &buffer) != KisImportExportFilter::OK) {
qWarning() << "serializeToByteArray():: Could not export to our native format";
}
return byteArray;
}
void KisDocument::slotCompleteSavingDocument(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage)
{
if (status == KisImportExportFilter::UserCancelled)
return;
const QString fileName = QFileInfo(job.filePath).fileName();
if (status != KisImportExportFilter::OK) {
emit statusBarMessage(i18nc("%1 --- failing file name, %2 --- error message",
"Error during saving %1: %2",
fileName,
exportErrorToUserMessage(status, errorMessage)), errorMessageTimeout);
if (!fileBatchMode()) {
const QString filePath = job.filePath;
QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("Could not save %1\nReason: %2", filePath, exportErrorToUserMessage(status, errorMessage)));
}
} else {
if (!(job.flags & KritaUtils::SaveIsExporting)) {
const QString existingAutoSaveBaseName = localFilePath();
const bool wasRecovered = isRecovered();
setUrl(QUrl::fromLocalFile(job.filePath));
setLocalFilePath(job.filePath);
setMimeType(job.mimeType);
updateEditingTime(true);
if (!d->modifiedWhileSaving) {
/**
* If undo stack is already clean/empty, it doesn't emit any
* signals, so we might forget update document modified state
* (which was set, e.g. while recovering an autosave file)
*/
if (d->undoStack->isClean()) {
setModified(false);
} else {
d->undoStack->setClean();
}
}
setRecovered(false);
removeAutoSaveFiles(existingAutoSaveBaseName, wasRecovered);
}
emit completed();
emit sigSavingFinished();
emit statusBarMessage(i18n("Finished saving %1", fileName), successMessageTimeout);
}
}
QByteArray KisDocument::mimeType() const
{
return d->mimeType;
}
void KisDocument::setMimeType(const QByteArray & mimeType)
{
d->mimeType = mimeType;
}
bool KisDocument::fileBatchMode() const
{
return d->batchMode;
}
void KisDocument::setFileBatchMode(const bool batchMode)
{
d->batchMode = batchMode;
}
KisDocument* KisDocument::lockAndCloneForSaving()
{
// force update of all the asynchronous nodes before cloning
QApplication::processEvents();
KisLayerUtils::forceAllDelayedNodesUpdate(d->image->root());
KisMainWindow *window = KisPart::instance()->currentMainwindow();
if (window) {
if (window->viewManager()) {
if (!window->viewManager()->blockUntilOperationsFinished(d->image)) {
return 0;
}
}
}
Private::StrippedSafeSavingLocker locker(&d->savingMutex, d->image);
if (!locker.successfullyLocked()) {
return 0;
}
return new KisDocument(*this);
}
bool KisDocument::exportDocumentSync(const QUrl &url, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration)
{
Private::StrippedSafeSavingLocker locker(&d->savingMutex, d->image);
if (!locker.successfullyLocked()) {
return false;
}
d->savingImage = d->image;
const QString fileName = url.toLocalFile();
KisImportExportFilter::ConversionStatus status =
d->importExportManager->
exportDocument(fileName, fileName, mimeType, false, exportConfiguration);
d->savingImage = 0;
return status == KisImportExportFilter::OK;
}
bool KisDocument::initiateSavingInBackground(const QString actionName,
const QObject *receiverObject, const char *receiverMethod,
const KritaUtils::ExportFileJob &job,
KisPropertiesConfigurationSP exportConfiguration)
{
return initiateSavingInBackground(actionName, receiverObject, receiverMethod,
job, exportConfiguration, std::unique_ptr());
}
bool KisDocument::initiateSavingInBackground(const QString actionName,
const QObject *receiverObject, const char *receiverMethod,
const KritaUtils::ExportFileJob &job,
KisPropertiesConfigurationSP exportConfiguration,
std::unique_ptr &&optionalClonedDocument)
{
KIS_ASSERT_RECOVER_RETURN_VALUE(job.isValid(), false);
QScopedPointer clonedDocument;
if (!optionalClonedDocument) {
clonedDocument.reset(lockAndCloneForSaving());
} else {
clonedDocument.reset(optionalClonedDocument.release());
}
// we block saving until the current saving is finished!
if (!clonedDocument || !d->savingMutex.tryLock()) {
return false;
}
KIS_ASSERT_RECOVER_RETURN_VALUE(!d->backgroundSaveDocument, false);
KIS_ASSERT_RECOVER_RETURN_VALUE(!d->backgroundSaveJob.isValid(), false);
d->backgroundSaveDocument.reset(clonedDocument.take());
d->backgroundSaveJob = job;
d->modifiedWhileSaving = false;
if (d->backgroundSaveJob.flags & KritaUtils::SaveInAutosaveMode) {
d->backgroundSaveDocument->d->isAutosaving = true;
}
connect(d->backgroundSaveDocument.data(),
SIGNAL(sigBackgroundSavingFinished(KisImportExportFilter::ConversionStatus,QString)),
this,
SLOT(slotChildCompletedSavingInBackground(KisImportExportFilter::ConversionStatus,QString)));
connect(this, SIGNAL(sigCompleteBackgroundSaving(KritaUtils::ExportFileJob,KisImportExportFilter::ConversionStatus,QString)),
receiverObject, receiverMethod, Qt::UniqueConnection);
bool started =
d->backgroundSaveDocument->startExportInBackground(actionName,
job.filePath,
job.filePath,
job.mimeType,
job.flags & KritaUtils::SaveShowWarnings,
exportConfiguration);
if (!started) {
// the state should have been deinitialized in slotChildCompletedSavingInBackground()
KIS_SAFE_ASSERT_RECOVER (!d->backgroundSaveDocument && !d->backgroundSaveJob.isValid()) {
d->backgroundSaveDocument.take()->deleteLater();
d->savingMutex.unlock();
d->backgroundSaveJob = KritaUtils::ExportFileJob();
}
}
return started;
}
void KisDocument::slotChildCompletedSavingInBackground(KisImportExportFilter::ConversionStatus status, const QString &errorMessage)
{
KIS_SAFE_ASSERT_RECOVER(!d->savingMutex.tryLock()) {
d->savingMutex.unlock();
return;
}
KIS_SAFE_ASSERT_RECOVER_RETURN(d->backgroundSaveDocument);
if (d->backgroundSaveJob.flags & KritaUtils::SaveInAutosaveMode) {
d->backgroundSaveDocument->d->isAutosaving = false;
}
d->backgroundSaveDocument.take()->deleteLater();
d->savingMutex.unlock();
KIS_SAFE_ASSERT_RECOVER_RETURN(d->backgroundSaveJob.isValid());
const KritaUtils::ExportFileJob job = d->backgroundSaveJob;
d->backgroundSaveJob = KritaUtils::ExportFileJob();
emit sigCompleteBackgroundSaving(job, status, errorMessage);
}
void KisDocument::slotAutoSaveImpl(std::unique_ptr &&optionalClonedDocument)
{
if (!d->modified || !d->modifiedAfterAutosave) return;
const QString autoSaveFileName = generateAutoSaveFileName(localFilePath());
emit statusBarMessage(i18n("Autosaving... %1", autoSaveFileName), successMessageTimeout);
const bool hadClonedDocument = bool(optionalClonedDocument);
bool started = false;
if (d->image->isIdle() || hadClonedDocument) {
started = initiateSavingInBackground(i18n("Autosaving..."),
this, SLOT(slotCompleteAutoSaving(KritaUtils::ExportFileJob,KisImportExportFilter::ConversionStatus,QString)),
KritaUtils::ExportFileJob(autoSaveFileName, nativeFormatMimeType(), KritaUtils::SaveIsExporting | KritaUtils::SaveInAutosaveMode),
0,
std::move(optionalClonedDocument));
} else {
emit statusBarMessage(i18n("Autosaving postponed: document is busy..."), errorMessageTimeout);
}
if (!started && !hadClonedDocument && d->autoSaveFailureCount >= 3) {
KisCloneDocumentStroke *stroke = new KisCloneDocumentStroke(this);
connect(stroke, SIGNAL(sigDocumentCloned(KisDocument*)),
this, SLOT(slotInitiateAsyncAutosaving(KisDocument*)),
Qt::BlockingQueuedConnection);
KisStrokeId strokeId = d->image->startStroke(stroke);
d->image->endStroke(strokeId);
setInfiniteAutoSaveInterval();
} else if (!started) {
setEmergencyAutoSaveInterval();
} else {
d->modifiedAfterAutosave = false;
}
}
void KisDocument::slotAutoSave()
{
slotAutoSaveImpl(std::unique_ptr());
}
void KisDocument::slotInitiateAsyncAutosaving(KisDocument *clonedDocument)
{
slotAutoSaveImpl(std::unique_ptr(clonedDocument));
}
void KisDocument::slotCompleteAutoSaving(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage)
{
Q_UNUSED(job);
const QString fileName = QFileInfo(job.filePath).fileName();
if (status != KisImportExportFilter::OK) {
setEmergencyAutoSaveInterval();
emit statusBarMessage(i18nc("%1 --- failing file name, %2 --- error message",
"Error during autosaving %1: %2",
fileName,
exportErrorToUserMessage(status, errorMessage)), errorMessageTimeout);
} else {
KisConfig cfg(true);
d->autoSaveDelay = cfg.autoSaveInterval();
if (!d->modifiedWhileSaving) {
d->autoSaveTimer->stop(); // until the next change
d->autoSaveFailureCount = 0;
} else {
setNormalAutoSaveInterval();
}
emit statusBarMessage(i18n("Finished autosaving %1", fileName), successMessageTimeout);
}
}
bool KisDocument::startExportInBackground(const QString &actionName,
const QString &location,
const QString &realLocation,
const QByteArray &mimeType,
bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration)
{
d->savingImage = d->image;
KisMainWindow *window = KisPart::instance()->currentMainwindow();
if (window) {
if (window->viewManager()) {
d->savingUpdater = window->viewManager()->createThreadedUpdater(actionName);
d->importExportManager->setUpdater(d->savingUpdater);
}
}
KisImportExportFilter::ConversionStatus initializationStatus;
d->childSavingFuture =
d->importExportManager->exportDocumentAsyc(location,
realLocation,
mimeType,
initializationStatus,
showWarnings,
exportConfiguration);
if (initializationStatus != KisImportExportFilter::ConversionStatus::OK) {
if (d->savingUpdater) {
d->savingUpdater->cancel();
}
d->savingImage.clear();
emit sigBackgroundSavingFinished(initializationStatus, this->errorMessage());
return false;
}
typedef QFutureWatcher StatusWatcher;
StatusWatcher *watcher = new StatusWatcher();
watcher->setFuture(d->childSavingFuture);
connect(watcher, SIGNAL(finished()), SLOT(finishExportInBackground()));
connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()));
return true;
}
void KisDocument::finishExportInBackground()
{
KIS_SAFE_ASSERT_RECOVER(d->childSavingFuture.isFinished()) {
emit sigBackgroundSavingFinished(KisImportExportFilter::InternalError, "");
return;
}
KisImportExportFilter::ConversionStatus status =
d->childSavingFuture.result();
const QString errorMessage = this->errorMessage();
d->savingImage.clear();
d->childSavingFuture = QFuture();
d->lastErrorMessage.clear();
if (d->savingUpdater) {
d->savingUpdater->setProgress(100);
}
emit sigBackgroundSavingFinished(status, errorMessage);
}
void KisDocument::setReadWrite(bool readwrite)
{
d->readwrite = readwrite;
setNormalAutoSaveInterval();
Q_FOREACH (KisMainWindow *mainWindow, KisPart::instance()->mainWindows()) {
mainWindow->setReadWrite(readwrite);
}
}
void KisDocument::setAutoSaveDelay(int delay)
{
if (isReadWrite() && delay > 0) {
d->autoSaveTimer->start(delay * 1000);
} else {
d->autoSaveTimer->stop();
}
}
void KisDocument::setNormalAutoSaveInterval()
{
setAutoSaveDelay(d->autoSaveDelay);
d->autoSaveFailureCount = 0;
}
void KisDocument::setEmergencyAutoSaveInterval()
{
const int emergencyAutoSaveInterval = 10; /* sec */
setAutoSaveDelay(emergencyAutoSaveInterval);
d->autoSaveFailureCount++;
}
void KisDocument::setInfiniteAutoSaveInterval()
{
setAutoSaveDelay(-1);
}
KoDocumentInfo *KisDocument::documentInfo() const
{
return d->docInfo;
}
bool KisDocument::isModified() const
{
return d->modified;
}
QPixmap KisDocument::generatePreview(const QSize& size)
{
KisImageSP image = d->image;
if (d->savingImage) image = d->savingImage;
if (image) {
QRect bounds = image->bounds();
QSize newSize = bounds.size();
newSize.scale(size, Qt::KeepAspectRatio);
QPixmap px = QPixmap::fromImage(image->convertToQImage(newSize, 0));
if (px.size() == QSize(0,0)) {
px = QPixmap(newSize);
QPainter gc(&px);
QBrush checkBrush = QBrush(KisCanvasWidgetBase::createCheckersImage(newSize.width() / 5));
gc.fillRect(px.rect(), checkBrush);
gc.end();
}
return px;
}
return QPixmap(size);
}
QString KisDocument::generateAutoSaveFileName(const QString & path) const
{
QString retval;
// Using the extension allows to avoid relying on the mime magic when opening
const QString extension (".kra");
QRegularExpression autosavePattern("^\\..+-autosave.kra$");
QFileInfo fi(path);
QString dir = fi.absolutePath();
QString filename = fi.fileName();
if (path.isEmpty() || autosavePattern.match(filename).hasMatch()) {
// Never saved?
#ifdef Q_OS_WIN
// On Windows, use the temp location (https://bugs.kde.org/show_bug.cgi?id=314921)
retval = QString("%1%2.%3-%4-%5-autosave%6").arg(QDir::tempPath()).arg(QDir::separator()).arg("krita").arg(qApp->applicationPid()).arg(objectName()).arg(extension);
#else
// On Linux, use a temp file in $HOME then. Mark it with the pid so two instances don't overwrite each other's autosave file
retval = QString("%1%2.%3-%4-%5-autosave%6").arg(QDir::homePath()).arg(QDir::separator()).arg("krita").arg(qApp->applicationPid()).arg(objectName()).arg(extension);
#endif
} else {
retval = QString("%1%2.%3-autosave%4").arg(dir).arg(QDir::separator()).arg(filename).arg(extension);
}
//qDebug() << "generateAutoSaveFileName() for path" << path << ":" << retval;
return retval;
}
bool KisDocument::importDocument(const QUrl &_url)
{
bool ret;
dbgUI << "url=" << _url.url();
// open...
ret = openUrl(_url);
// reset url & m_file (kindly? set by KisParts::openUrl()) to simulate a
// File --> Import
if (ret) {
dbgUI << "success, resetting url";
resetURL();
setTitleModified();
}
return ret;
}
bool KisDocument::openUrl(const QUrl &_url, OpenFlags flags)
{
if (!_url.isLocalFile()) {
return false;
}
dbgUI << "url=" << _url.url();
d->lastErrorMessage.clear();
// Reimplemented, to add a check for autosave files and to improve error reporting
if (!_url.isValid()) {
d->lastErrorMessage = i18n("Malformed URL\n%1", _url.url()); // ## used anywhere ?
return false;
}
QUrl url(_url);
bool autosaveOpened = false;
if (url.isLocalFile() && !fileBatchMode()) {
QString file = url.toLocalFile();
QString asf = generateAutoSaveFileName(file);
if (QFile::exists(asf)) {
KisApplication *kisApp = static_cast(qApp);
kisApp->hideSplashScreen();
//dbgUI <<"asf=" << asf;
// ## TODO compare timestamps ?
int res = QMessageBox::warning(0,
i18nc("@title:window", "Krita"),
i18n("An autosaved file exists for this document.\nDo you want to open the autosaved file instead?"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Yes);
switch (res) {
case QMessageBox::Yes :
url.setPath(asf);
autosaveOpened = true;
break;
case QMessageBox::No :
QFile::remove(asf);
break;
default: // Cancel
return false;
}
}
}
bool ret = openUrlInternal(url);
if (autosaveOpened || flags & RecoveryFile) {
setReadWrite(true); // enable save button
setModified(true);
setRecovered(true);
}
else {
if (!(flags & DontAddToRecent)) {
KisPart::instance()->addRecentURLToAllMainWindows(_url);
}
if (ret) {
// Detect readonly local-files; remote files are assumed to be writable
QFileInfo fi(url.toLocalFile());
setReadWrite(fi.isWritable());
}
setRecovered(false);
}
return ret;
}
class DlgLoadMessages : public KoDialog {
public:
DlgLoadMessages(const QString &title, const QString &message, const QStringList &warnings) {
setWindowTitle(title);
setWindowIcon(KisIconUtils::loadIcon("warning"));
QWidget *page = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(page);
QHBoxLayout *hlayout = new QHBoxLayout();
QLabel *labelWarning= new QLabel();
labelWarning->setPixmap(KisIconUtils::loadIcon("warning").pixmap(32, 32));
hlayout->addWidget(labelWarning);
hlayout->addWidget(new QLabel(message));
layout->addLayout(hlayout);
QTextBrowser *browser = new QTextBrowser();
QString warning = "";
if (warnings.size() == 1) {
warning += " Reason:
";
}
else {
warning += " Reasons:
";
}
warning += "";
Q_FOREACH(const QString &w, warnings) {
warning += "\n- " + w + "
";
}
warning += "
";
browser->setHtml(warning);
browser->setMinimumHeight(200);
browser->setMinimumWidth(400);
layout->addWidget(browser);
setMainWidget(page);
setButtons(KoDialog::Ok);
resize(minimumSize());
}
};
bool KisDocument::openFile()
{
//dbgUI <<"for" << localFilePath();
if (!QFile::exists(localFilePath())) {
QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("File %1 does not exist.", localFilePath()));
return false;
}
QString filename = localFilePath();
QString typeName = mimeType();
if (typeName.isEmpty()) {
typeName = KisMimeDatabase::mimeTypeForFile(filename);
}
//qDebug() << "mimetypes 4:" << typeName;
// Allow to open backup files, don't keep the mimetype application/x-trash.
if (typeName == "application/x-trash") {
QString path = filename;
while (path.length() > 0) {
path.chop(1);
typeName = KisMimeDatabase::mimeTypeForFile(path);
//qDebug() << "\t" << path << typeName;
if (!typeName.isEmpty()) {
break;
}
}
//qDebug() << "chopped" << filename << "to" << path << "Was trash, is" << typeName;
}
dbgUI << localFilePath() << "type:" << typeName;
KisMainWindow *window = KisPart::instance()->currentMainwindow();
if (window && window->viewManager()) {
KoUpdaterPtr updater = window->viewManager()->createUnthreadedUpdater(i18n("Opening document"));
d->importExportManager->setUpdater(updater);
}
KisImportExportFilter::ConversionStatus status;
status = d->importExportManager->importDocument(localFilePath(), typeName);
if (status != KisImportExportFilter::OK) {
QString msg = KisImportExportFilter::conversionStatusString(status);
if (!msg.isEmpty()) {
DlgLoadMessages dlg(i18nc("@title:window", "Krita"),
i18n("Could not open %2.\nReason: %1.", msg, prettyPathOrUrl()),
errorMessage().split("\n") + warningMessage().split("\n"));
dlg.exec();
}
return false;
}
else if (!warningMessage().isEmpty()) {
DlgLoadMessages dlg(i18nc("@title:window", "Krita"),
i18n("There were problems opening %1.", prettyPathOrUrl()),
warningMessage().split("\n"));
dlg.exec();
setUrl(QUrl());
}
setMimeTypeAfterLoading(typeName);
emit sigLoadingFinished();
undoStack()->clear();
return true;
}
// shared between openFile and koMainWindow's "create new empty document" code
void KisDocument::setMimeTypeAfterLoading(const QString& mimeType)
{
d->mimeType = mimeType.toLatin1();
d->outputMimeType = d->mimeType;
}
bool KisDocument::loadNativeFormat(const QString & file_)
{
return openUrl(QUrl::fromLocalFile(file_));
}
void KisDocument::setModified(bool mod)
{
if (mod) {
updateEditingTime(false);
}
if (d->isAutosaving) // ignore setModified calls due to autosaving
return;
if ( !d->readwrite && d->modified ) {
errKrita << "Can't set a read-only document to 'modified' !" << endl;
return;
}
//dbgUI<<" url:" << url.path();
//dbgUI<<" mod="<docInfo->aboutInfo("editing-time").toInt() + d->firstMod.secsTo(d->lastMod)));
d->firstMod = now;
} else if (firstModDelta > 60 || forceStoreElapsed) {
d->docInfo->setAboutInfo("editing-time", QString::number(d->docInfo->aboutInfo("editing-time").toInt() + firstModDelta));
d->firstMod = now;
}
d->lastMod = now;
}
QString KisDocument::prettyPathOrUrl() const
{
QString _url(url().toDisplayString());
#ifdef Q_OS_WIN
if (url().isLocalFile()) {
_url = QDir::toNativeSeparators(_url);
}
#endif
return _url;
}
// Get caption from document info (title(), in about page)
QString KisDocument::caption() const
{
QString c;
const QString _url(url().fileName());
// if URL is empty...it is probably an unsaved file
if (_url.isEmpty()) {
c = " [" + i18n("Not Saved") + "] ";
} else {
c = _url; // Fall back to document URL
}
return c;
}
void KisDocument::setTitleModified()
{
emit titleModified(caption(), isModified());
}
QDomDocument KisDocument::createDomDocument(const QString& tagName, const QString& version) const
{
return createDomDocument("krita", tagName, version);
}
//static
QDomDocument KisDocument::createDomDocument(const QString& appName, const QString& tagName, const QString& version)
{
QDomImplementation impl;
QString url = QString("http://www.calligra.org/DTD/%1-%2.dtd").arg(appName).arg(version);
QDomDocumentType dtype = impl.createDocumentType(tagName,
QString("-//KDE//DTD %1 %2//EN").arg(appName).arg(version),
url);
// The namespace URN doesn't need to include the version number.
QString namespaceURN = QString("http://www.calligra.org/DTD/%1").arg(appName);
QDomDocument doc = impl.createDocument(namespaceURN, tagName, dtype);
doc.insertBefore(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""), doc.documentElement());
return doc;
}
bool KisDocument::isNativeFormat(const QByteArray& mimetype) const
{
if (mimetype == nativeFormatMimeType())
return true;
return extraNativeMimeTypes().contains(mimetype);
}
void KisDocument::setErrorMessage(const QString& errMsg)
{
d->lastErrorMessage = errMsg;
}
QString KisDocument::errorMessage() const
{
return d->lastErrorMessage;
}
void KisDocument::setWarningMessage(const QString& warningMsg)
{
d->lastWarningMessage = warningMsg;
}
QString KisDocument::warningMessage() const
{
return d->lastWarningMessage;
}
void KisDocument::removeAutoSaveFiles(const QString &autosaveBaseName, bool wasRecovered)
{
//qDebug() << "removeAutoSaveFiles";
// Eliminate any auto-save file
QString asf = generateAutoSaveFileName(autosaveBaseName); // the one in the current dir
//qDebug() << "\tfilename:" << asf << "exists:" << QFile::exists(asf);
if (QFile::exists(asf)) {
//qDebug() << "\tremoving autosavefile" << asf;
QFile::remove(asf);
}
asf = generateAutoSaveFileName(QString()); // and the one in $HOME
//qDebug() << "Autsavefile in $home" << asf;
if (QFile::exists(asf)) {
//qDebug() << "\tremoving autsavefile 2" << asf;
QFile::remove(asf);
}
QRegularExpression autosavePattern("^\\..+-autosave.kra$");
if (wasRecovered &&
!autosaveBaseName.isEmpty() &&
autosavePattern.match(QFileInfo(autosaveBaseName).fileName()).hasMatch() &&
QFile::exists(autosaveBaseName)) {
QFile::remove(autosaveBaseName);
}
}
KoUnit KisDocument::unit() const
{
return d->unit;
}
void KisDocument::setUnit(const KoUnit &unit)
{
if (d->unit != unit) {
d->unit = unit;
emit unitChanged(unit);
}
}
KUndo2Stack *KisDocument::undoStack()
{
return d->undoStack;
}
KisImportExportManager *KisDocument::importExportManager() const
{
return d->importExportManager;
}
void KisDocument::addCommand(KUndo2Command *command)
{
if (command)
d->undoStack->push(command);
}
void KisDocument::beginMacro(const KUndo2MagicString & text)
{
d->undoStack->beginMacro(text);
}
void KisDocument::endMacro()
{
d->undoStack->endMacro();
}
void KisDocument::slotUndoStackCleanChanged(bool value)
{
setModified(!value);
}
void KisDocument::slotConfigChanged()
{
KisConfig cfg(true);
d->undoStack->setUndoLimit(cfg.undoStackLimit());
d->autoSaveDelay = cfg.autoSaveInterval();
setNormalAutoSaveInterval();
}
void KisDocument::clearUndoHistory()
{
d->undoStack->clear();
}
KisGridConfig KisDocument::gridConfig() const
{
return d->gridConfig;
}
void KisDocument::setGridConfig(const KisGridConfig &config)
{
d->gridConfig = config;
}
QList &KisDocument::paletteList()
{
return d->paletteList;
}
void KisDocument::setPaletteList(const QList &paletteList)
{
d->paletteList = paletteList;
}
const KisGuidesConfig& KisDocument::guidesConfig() const
{
return d->guidesConfig;
}
void KisDocument::setGuidesConfig(const KisGuidesConfig &data)
{
if (d->guidesConfig == data) return;
d->guidesConfig = data;
emit sigGuidesConfigChanged(d->guidesConfig);
}
void KisDocument::resetURL() {
setUrl(QUrl());
setLocalFilePath(QString());
}
KoDocumentInfoDlg *KisDocument::createDocumentInfoDialog(QWidget *parent, KoDocumentInfo *docInfo) const
{
return new KoDocumentInfoDlg(parent, docInfo);
}
bool KisDocument::isReadWrite() const
{
return d->readwrite;
}
QUrl KisDocument::url() const
{
return d->m_url;
}
bool KisDocument::closeUrl(bool promptToSave)
{
if (promptToSave) {
if ( isReadWrite() && isModified()) {
Q_FOREACH (KisView *view, KisPart::instance()->views()) {
if (view && view->document() == this) {
if (!view->queryClose()) {
return false;
}
}
}
}
}
// Not modified => ok and delete temp file.
d->mimeType = QByteArray();
// It always succeeds for a read-only part,
// but the return value exists for reimplementations
// (e.g. pressing cancel for a modified read-write part)
return true;
}
void KisDocument::setUrl(const QUrl &url)
{
d->m_url = url;
}
QString KisDocument::localFilePath() const
{
return d->m_file;
}
void KisDocument::setLocalFilePath( const QString &localFilePath )
{
d->m_file = localFilePath;
}
bool KisDocument::openUrlInternal(const QUrl &url)
{
if ( !url.isValid() )
return false;
if (d->m_bAutoDetectedMime) {
d->mimeType = QByteArray();
d->m_bAutoDetectedMime = false;
}
QByteArray mimetype = d->mimeType;
if ( !closeUrl() )
return false;
d->mimeType = mimetype;
setUrl(url);
d->m_file.clear();
if (d->m_url.isLocalFile()) {
d->m_file = d->m_url.toLocalFile();
bool ret;
// set the mimetype only if it was not already set (for example, by the host application)
if (d->mimeType.isEmpty()) {
// get the mimetype of the file
// using findByUrl() to avoid another string -> url conversion
QString mime = KisMimeDatabase::mimeTypeForFile(d->m_url.toLocalFile());
d->mimeType = mime.toLocal8Bit();
d->m_bAutoDetectedMime = true;
}
setUrl(d->m_url);
ret = openFile();
if (ret) {
emit completed();
} else {
emit canceled(QString());
}
return ret;
}
return false;
}
bool KisDocument::newImage(const QString& name,
qint32 width, qint32 height,
const KoColorSpace* cs,
- const KoColor &bgColor, bool backgroundAsLayer,
+ const KoColor &bgColor, KisConfig::BackgroundStyle bgStyle,
int numberOfLayers,
const QString &description, const double imageResolution)
{
Q_ASSERT(cs);
KisImageSP image;
- KisPaintLayerSP layer;
if (!cs) return false;
QApplication::setOverrideCursor(Qt::BusyCursor);
image = new KisImage(createUndoStore(), width, height, cs, name);
Q_CHECK_PTR(image);
connect(image, SIGNAL(sigImageModified()), this, SLOT(setImageModified()), Qt::UniqueConnection);
image->setResolution(imageResolution, imageResolution);
image->assignImageProfile(cs->profile());
documentInfo()->setAboutInfo("title", name);
documentInfo()->setAboutInfo("abstract", description);
- layer = new KisPaintLayer(image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8, cs);
- Q_CHECK_PTR(layer);
+ KisLayerSP layer;
+ if (bgStyle == KisConfig::RASTER_LAYER || bgStyle == KisConfig::FILL_LAYER) {
+ KoColor strippedAlpha = bgColor;
+ strippedAlpha.setOpacity(OPACITY_OPAQUE_U8);
+
+ if (bgStyle == KisConfig::RASTER_LAYER) {
+ layer = new KisPaintLayer(image.data(), "Background", OPACITY_OPAQUE_U8, cs);;
+ layer->paintDevice()->setDefaultPixel(strippedAlpha);
+ } else if (bgStyle == KisConfig::FILL_LAYER) {
+ KisFilterConfigurationSP filter_config = KisGeneratorRegistry::instance()->get("color")->defaultConfiguration();
+ filter_config->setProperty("color", strippedAlpha.toQColor());
+ layer = new KisGeneratorLayer(image.data(), "Background Fill", filter_config, image->globalSelection());
+ }
- if (backgroundAsLayer) {
- image->setDefaultProjectionColor(KoColor(cs));
+ layer->setOpacity(bgColor.opacityU8());
- if (bgColor.opacityU8() == OPACITY_OPAQUE_U8) {
- layer->paintDevice()->setDefaultPixel(bgColor);
- } else {
- // Hack: with a semi-transparent background color, the projection isn't composited right if we just set the default pixel
- KisFillPainter painter;
- painter.begin(layer->paintDevice());
- painter.fillRect(0, 0, width, height, bgColor, bgColor.opacityU8());
+ if (numberOfLayers > 1) {
+ //Lock bg layer if others are present.
+ layer->setUserLocked(true);
}
- } else {
+ }
+ else { // KisConfig::CANVAS_COLOR (needs an unlocked starting layer).
image->setDefaultProjectionColor(bgColor);
+ layer = new KisPaintLayer(image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8, cs);
}
- layer->setDirty(QRect(0, 0, width, height));
+ Q_CHECK_PTR(layer);
image->addNode(layer.data(), image->rootLayer().data());
+ layer->setDirty(QRect(0, 0, width, height));
+
setCurrentImage(image);
for(int i = 1; i < numberOfLayers; ++i) {
KisPaintLayerSP layer = new KisPaintLayer(image, image->nextLayerName(), OPACITY_OPAQUE_U8, cs);
image->addNode(layer, image->root(), i);
layer->setDirty(QRect(0, 0, width, height));
}
KisConfig cfg(false);
cfg.defImageWidth(width);
cfg.defImageHeight(height);
cfg.defImageResolution(imageResolution);
cfg.defColorModel(image->colorSpace()->colorModelId().id());
cfg.setDefaultColorDepth(image->colorSpace()->colorDepthId().id());
cfg.defColorProfile(image->colorSpace()->profile()->name());
QApplication::restoreOverrideCursor();
return true;
}
bool KisDocument::isSaving() const
{
const bool result = d->savingMutex.tryLock();
if (result) {
d->savingMutex.unlock();
}
return !result;
}
void KisDocument::waitForSavingToComplete()
{
if (isSaving()) {
KisAsyncActionFeedback f(i18nc("progress dialog message when the user closes the document that is being saved", "Waiting for saving to complete..."), 0);
f.waitForMutex(&d->savingMutex);
}
}
KoShapeControllerBase *KisDocument::shapeController() const
{
return d->shapeController;
}
KoShapeLayer* KisDocument::shapeForNode(KisNodeSP layer) const
{
return d->shapeController->shapeForNode(layer);
}
QList KisDocument::assistants() const
{
return d->assistants;
}
void KisDocument::setAssistants(const QList &value)
{
d->assistants = value;
}
KisSharedPtr KisDocument::referenceImagesLayer() const
{
return d->referenceImagesLayer.data();
}
void KisDocument::setReferenceImagesLayer(KisSharedPtr layer, bool updateImage)
{
if (d->referenceImagesLayer) {
d->referenceImagesLayer->disconnect(this);
}
if (updateImage) {
if (layer) {
d->image->addNode(layer);
} else {
d->image->removeNode(d->referenceImagesLayer);
}
}
d->referenceImagesLayer = layer;
if (d->referenceImagesLayer) {
connect(d->referenceImagesLayer, SIGNAL(sigUpdateCanvas(QRectF)),
this, SIGNAL(sigReferenceImagesChanged()));
}
}
void KisDocument::setPreActivatedNode(KisNodeSP activatedNode)
{
d->preActivatedNode = activatedNode;
}
KisNodeSP KisDocument::preActivatedNode() const
{
return d->preActivatedNode;
}
KisImageWSP KisDocument::image() const
{
return d->image;
}
KisImageSP KisDocument::savingImage() const
{
return d->savingImage;
}
void KisDocument::setCurrentImage(KisImageSP image, bool forceInitialUpdate)
{
if (d->image) {
// Disconnect existing sig/slot connections
d->image->setUndoStore(new KisDumbUndoStore());
d->image->disconnect(this);
d->shapeController->setImage(0);
d->image = 0;
}
if (!image) return;
d->setImageAndInitIdleWatcher(image);
d->image->setUndoStore(new KisDocumentUndoStore(this));
d->shapeController->setImage(image);
setModified(false);
connect(d->image, SIGNAL(sigImageModified()), this, SLOT(setImageModified()), Qt::UniqueConnection);
if (forceInitialUpdate) {
d->image->initialRefreshGraph();
}
}
void KisDocument::hackPreliminarySetImage(KisImageSP image)
{
KIS_SAFE_ASSERT_RECOVER_RETURN(!d->image);
d->setImageAndInitIdleWatcher(image);
d->shapeController->setImage(image);
}
void KisDocument::setImageModified()
{
setModified(true);
}
KisUndoStore* KisDocument::createUndoStore()
{
return new KisDocumentUndoStore(this);
}
bool KisDocument::isAutosaving() const
{
return d->isAutosaving;
}
QString KisDocument::exportErrorToUserMessage(KisImportExportFilter::ConversionStatus status, const QString &errorMessage)
{
return errorMessage.isEmpty() ? KisImportExportFilter::conversionStatusString(status) : errorMessage;
}
void KisDocument::setAssistantsGlobalColor(QColor color)
{
d->globalAssistantsColor = color;
}
QColor KisDocument::assistantsGlobalColor()
{
return d->globalAssistantsColor;
}
QRectF KisDocument::documentBounds() const
{
QRectF bounds = d->image->bounds();
if (d->referenceImagesLayer) {
bounds |= d->referenceImagesLayer->boundingImageRect();
}
return bounds;
}
diff --git a/libs/ui/KisDocument.h b/libs/ui/KisDocument.h
index a661ecaef5..bc2caef234 100644
--- a/libs/ui/KisDocument.h
+++ b/libs/ui/KisDocument.h
@@ -1,655 +1,656 @@
/* This file is part of the Krita project
*
* Copyright (C) 2014 Boudewijn Rempt
*
* 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 KISDOCUMENT_H
#define KISDOCUMENT_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#include
#include "kritaui_export.h"
#include
class QString;
class KUndo2Command;
class KoUnit;
class KoColor;
class KoColorSpace;
class KoShapeControllerBase;
class KoShapeLayer;
class KoStore;
class KoOdfReadStore;
class KoDocumentInfo;
class KoDocumentInfoDlg;
class KisImportExportManager;
class KisUndoStore;
class KisPart;
class KisGridConfig;
class KisGuidesConfig;
class QDomDocument;
class KisReferenceImagesLayer;
#define KIS_MIME_TYPE "application/x-krita"
/**
* The %Calligra document class
*
* This class provides some functionality each %Calligra document should have.
*
* @short The %Calligra document class
*/
class KRITAUI_EXPORT KisDocument : public QObject, public KoDocumentBase
{
Q_OBJECT
protected:
explicit KisDocument();
/**
* @brief KisDocument makes a deep copy of the document \p rhs.
* The caller *must* ensure that the image is properly
* locked and is in consistent state before asking for
* cloning.
* @param rhs the source document to copy from
*/
explicit KisDocument(const KisDocument &rhs);
public:
enum OpenFlag {
None = 0,
DontAddToRecent = 0x1,
RecoveryFile = 0x2
};
Q_DECLARE_FLAGS(OpenFlags, OpenFlag)
/**
* Destructor.
*
* The destructor does not delete any attached KisView objects and it does not
* delete the attached widget as returned by widget().
*/
~KisDocument() override;
/**
* @brief reload Reloads the document from the original url
* @return the result of loading the document
*/
bool reload();
/**
* @brief creates a clone of the document and returns it. Please make sure that you
* hold all the necessary locks on the image before asking for a clone!
*/
KisDocument* clone();
/**
* @brief openUrl Open an URL
* @param url The URL to open
* @param flags Control specific behavior
* @return success status
*/
bool openUrl(const QUrl &url, OpenFlags flags = None);
/**
* Opens the document given by @p url, without storing the URL
* in the KisDocument.
* Call this instead of openUrl() to implement KisMainWindow's
* File --> Import feature.
*
* @note This will call openUrl(). To differentiate this from an ordinary
* Open operation (in any reimplementation of openUrl() or openFile())
* call isImporting().
*/
bool importDocument(const QUrl &url);
/**
* Saves the document as @p url without changing the state of the
* KisDocument (URL, modified flag etc.). Call this instead of
* KisParts::ReadWritePart::saveAs() to implement KisMainWindow's
* File --> Export feature.
*/
bool exportDocument(const QUrl &url, const QByteArray &mimeType, bool showWarnings = false, KisPropertiesConfigurationSP exportConfiguration = 0);
bool exportDocumentSync(const QUrl &url, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration = 0);
private:
bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration);
public:
/**
* @brief Sets whether the document can be edited or is read only.
*
* This recursively applied to all child documents and
* KisView::updateReadWrite is called for every attached
* view.
*/
void setReadWrite(bool readwrite = true);
/**
* To be preferred when a document exists. It is fast when calling
* it multiple times since it caches the result that readNativeFormatMimeType()
* delivers.
* This comes from the X-KDE-NativeMimeType key in the .desktop file.
*/
static QByteArray nativeFormatMimeType() { return KIS_MIME_TYPE; }
/// Checks whether a given mimetype can be handled natively.
bool isNativeFormat(const QByteArray& mimetype) const;
/// Returns a list of the mimetypes considered "native", i.e. which can
/// be saved by KisDocument without a filter, in *addition* to the main one
static QStringList extraNativeMimeTypes() { return QStringList() << KIS_MIME_TYPE; }
/**
* Returns the actual mimetype of the document
*/
QByteArray mimeType() const override;
/**
* @brief Sets the mime type for the document.
*
* When choosing "save as" this is also the mime type
* selected by default.
*/
void setMimeType(const QByteArray & mimeType) override;
/**
* @return true if file operations should inhibit the option dialog
*/
bool fileBatchMode() const;
/**
* @param batchMode if true, do not show the option dialog for file operations.
*/
void setFileBatchMode(const bool batchMode);
/**
* Sets the error message to be shown to the user (use i18n()!)
* when loading or saving fails.
* If you asked the user about something and they chose "Cancel",
*/
void setErrorMessage(const QString& errMsg);
/**
* Return the last error message. Usually KisDocument takes care of
* showing it; this method is mostly provided for non-interactive use.
*/
QString errorMessage() const;
/**
* Sets the warning message to be shown to the user (use i18n()!)
* when loading or saving fails.
*/
void setWarningMessage(const QString& warningMsg);
/**
* Return the last warning message set by loading or saving. Warnings
* mean that the document could not be completely loaded, but the errors
* were not absolutely fatal.
*/
QString warningMessage() const;
/**
* @brief Generates a preview picture of the document
* @note The preview is used in the File Dialog and also to create the Thumbnail
*/
QPixmap generatePreview(const QSize& size);
/**
* Tells the document that its title has been modified, either because
* the modified status changes (this is done by setModified() ) or
* because the URL or the document-info's title changed.
*/
void setTitleModified();
/**
* @brief Sets the document to empty.
*
* Used after loading a template
* (which is not empty, but not the user's input).
*
* @see isEmpty()
*/
void setEmpty(bool empty = true);
/**
* Return a correctly created QDomDocument for this KisDocument,
* including processing instruction, complete DOCTYPE tag (with systemId and publicId), and root element.
* @param tagName the name of the tag for the root element
* @param version the DTD version (usually the application's version).
*/
QDomDocument createDomDocument(const QString& tagName, const QString& version) const;
/**
* Return a correctly created QDomDocument for an old (1.3-style) %Calligra document,
* including processing instruction, complete DOCTYPE tag (with systemId and publicId), and root element.
* This static method can be used e.g. by filters.
* @param appName the app's instance name, e.g. words, kspread, kpresenter etc.
* @param tagName the name of the tag for the root element, e.g. DOC for words/kpresenter.
* @param version the DTD version (usually the application's version).
*/
static QDomDocument createDomDocument(const QString& appName, const QString& tagName, const QString& version);
/**
* Loads a document in the native format from a given URL.
* Reimplement if your native format isn't XML.
*
* @param file the file to load - usually KReadOnlyPart::m_file or the result of a filter
*/
bool loadNativeFormat(const QString & file);
/**
* Set standard autosave interval that is set by a config file
*/
void setNormalAutoSaveInterval();
/**
* Set emergency interval that autosave uses when the image is busy,
* by default it is 10 sec
*/
void setEmergencyAutoSaveInterval();
/**
* Disable autosave
*/
void setInfiniteAutoSaveInterval();
/**
* @return the information concerning this document.
* @see KoDocumentInfo
*/
KoDocumentInfo *documentInfo() const;
/**
* Performs a cleanup of unneeded backup files
*/
void removeAutoSaveFiles(const QString &autosaveBaseName, bool wasRecovered);
/**
* Returns true if this document or any of its internal child documents are modified.
*/
bool isModified() const override;
/**
* @return caption of the document
*
* Caption is of the form "[title] - [url]",
* built out of the document info (title) and pretty-printed
* document URL.
* If the title is not present, only the URL it returned.
*/
QString caption() const;
/**
* Sets the document URL to empty URL
* KParts doesn't allow this, but %Calligra apps have e.g. templates
* After using loadNativeFormat on a template, one wants
* to set the url to QUrl()
*/
void resetURL();
/**
* @internal (public for KisMainWindow)
*/
void setMimeTypeAfterLoading(const QString& mimeType);
/**
* Returns the unit used to display all measures/distances.
*/
KoUnit unit() const;
/**
* Sets the unit used to display all measures/distances.
*/
void setUnit(const KoUnit &unit);
KisGridConfig gridConfig() const;
void setGridConfig(const KisGridConfig &config);
/// returns the guides data for this document.
const KisGuidesConfig& guidesConfig() const;
void setGuidesConfig(const KisGuidesConfig &data);
QList &paletteList();
void setPaletteList(const QList &paletteList);
void clearUndoHistory();
/**
* Sets the modified flag on the document. This means that it has
* to be saved or not before deleting it.
*/
void setModified(bool _mod);
void setRecovered(bool value);
bool isRecovered() const;
void updateEditingTime(bool forceStoreElapsed);
/**
* Returns the global undo stack
*/
KUndo2Stack *undoStack();
/**
* @brief importExportManager gives access to the internal import/export manager
* @return the document's import/export manager
*/
KisImportExportManager *importExportManager() const;
/**
* @brief serializeToNativeByteArray daves the document into a .kra file wtitten
* to a memory-based byte-array
* @return a byte array containing the .kra file
*/
QByteArray serializeToNativeByteArray();
/**
* @brief isInSaving shown if the document has any (background) saving process or not
* @return true if there is some saving in action
*/
bool isInSaving() const;
public Q_SLOTS:
/**
* Adds a command to the undo stack and executes it by calling the redo() function.
* @param command command to add to the undo stack
*/
void addCommand(KUndo2Command *command);
/**
* Begins recording of a macro command. At the end endMacro needs to be called.
* @param text command description
*/
void beginMacro(const KUndo2MagicString &text);
/**
* Ends the recording of a macro command.
*/
void endMacro();
Q_SIGNALS:
/**
* This signal is emitted when the unit is changed by setUnit().
* It is common to connect views to it, in order to change the displayed units
* (e.g. in the rulers)
*/
void unitChanged(const KoUnit &unit);
/**
* Emitted e.g. at the beginning of a save operation
* This is emitted by KisDocument and used by KisView to display a statusbar message
*/
void statusBarMessage(const QString& text, int timeout = 0);
/**
* Emitted e.g. at the end of a save operation
* This is emitted by KisDocument and used by KisView to clear the statusbar message
*/
void clearStatusBarMessage();
/**
* Emitted when the document is modified
*/
void modified(bool);
void titleModified(const QString &caption, bool isModified);
void sigLoadingFinished();
void sigSavingFinished();
void sigGuidesConfigChanged(const KisGuidesConfig &config);
void sigBackgroundSavingFinished(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void sigCompleteBackgroundSaving(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void sigReferenceImagesChanged();
private Q_SLOTS:
void finishExportInBackground();
void slotChildCompletedSavingInBackground(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void slotCompleteAutoSaving(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void slotCompleteSavingDocument(const KritaUtils::ExportFileJob &job, KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
void slotInitiateAsyncAutosaving(KisDocument *clonedDocument);
private:
friend class KisPart;
friend class SafeSavingLocker;
bool initiateSavingInBackground(const QString actionName,
const QObject *receiverObject, const char *receiverMethod,
const KritaUtils::ExportFileJob &job,
KisPropertiesConfigurationSP exportConfiguration,
std::unique_ptr &&optionalClonedDocument);
bool initiateSavingInBackground(const QString actionName,
const QObject *receiverObject, const char *receiverMethod,
const KritaUtils::ExportFileJob &job,
KisPropertiesConfigurationSP exportConfiguration);
bool startExportInBackground(const QString &actionName, const QString &location,
const QString &realLocation,
const QByteArray &mimeType,
bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration);
/**
* Activate/deactivate/configure the autosave feature.
* @param delay in seconds, 0 to disable
*/
void setAutoSaveDelay(int delay);
/**
* Generate a name for the document.
*/
QString newObjectName();
QString generateAutoSaveFileName(const QString & path) const;
/**
* Loads a document
*
* Applies a filter if necessary, and calls loadNativeFormat in any case
* You should not have to reimplement, except for very special cases.
*
* NOTE: this method also creates a new KisView instance!
*
* This method is called from the KReadOnlyPart::openUrl method.
*/
bool openFile();
public:
bool isAutosaving() const override;
public:
QString localFilePath() const override;
void setLocalFilePath( const QString &localFilePath );
KoDocumentInfoDlg* createDocumentInfoDialog(QWidget *parent, KoDocumentInfo *docInfo) const;
bool isReadWrite() const;
QUrl url() const override;
void setUrl(const QUrl &url) override;
bool closeUrl(bool promptToSave = true);
bool saveAs(const QUrl &url, const QByteArray &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfigration = 0);
/**
* Create a new image that has this document as a parent and
* replace the current image with this image.
*/
- bool newImage(const QString& name, qint32 width, qint32 height, const KoColorSpace * cs, const KoColor &bgColor, bool backgroundAsLayer,
+ bool newImage(const QString& name, qint32 width, qint32 height, const KoColorSpace * cs, const KoColor &bgColor, KisConfig::BackgroundStyle bgStyle,
int numberOfLayers, const QString &imageDescription, const double imageResolution);
bool isSaving() const;
void waitForSavingToComplete();
KisImageWSP image() const;
/**
* @brief savingImage provides a detached, shallow copy of the original image that must be used when saving.
* Any strokes in progress will not be applied to this image, so the result might be missing some data. On
* the other hand, it won't block.
*
* @return a shallow copy of the original image, or 0 is saving is not in progress
*/
KisImageSP savingImage() const;
/**
* Set the current image to the specified image and turn undo on.
*/
void setCurrentImage(KisImageSP image, bool forceInitialUpdate = true);
/**
* Set the image of the document preliminary, before the document
* has completed loading. Some of the document items (shapes) may want
* to access image properties (bounds and resolution), so we should provide
* it to them even before the entire image is loaded.
*
* Right now, the only use by KoShapeRegistry::createShapeFromOdf(), remove
* after it is deprecated.
*/
void hackPreliminarySetImage(KisImageSP image);
KisUndoStore* createUndoStore();
/**
* The shape controller matches internal krita image layers with
* the flake shape hierarchy.
*/
KoShapeControllerBase * shapeController() const;
KoShapeLayer* shapeForNode(KisNodeSP layer) const;
/**
* Set the list of nodes that was marked as currently active. Used *only*
* for saving loading. Never use it for tools or processing.
*/
void setPreActivatedNode(KisNodeSP activatedNode);
/**
* @return the node that was set as active during loading. Used *only*
* for saving loading. Never use it for tools or processing.
*/
KisNodeSP preActivatedNode() const;
/// @return the list of assistants associated with this document
QList assistants() const;
/// @replace the current list of assistants with @param value
void setAssistants(const QList &value);
void setAssistantsGlobalColor(QColor color);
QColor assistantsGlobalColor();
/**
* Get existing reference images layer or null if none exists.
*/
KisSharedPtr referenceImagesLayer() const;
void setReferenceImagesLayer(KisSharedPtr layer, bool updateImage);
bool save(bool showWarnings, KisPropertiesConfigurationSP exportConfiguration);
/**
* Return the bounding box of the image and associated elements (e.g. reference images)
*/
QRectF documentBounds() const;
Q_SIGNALS:
void completed();
void canceled(const QString &);
private Q_SLOTS:
void setImageModified();
void slotAutoSave();
void slotUndoStackCleanChanged(bool value);
void slotConfigChanged();
private:
/**
* @brief try to clone the image. This method handles all the locking for you. If locking
* has failed, no cloning happens
* @return cloned document on success, null otherwise
*/
KisDocument *lockAndCloneForSaving();
QString exportErrorToUserMessage(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
QString prettyPathOrUrl() const;
bool openUrlInternal(const QUrl &url);
void slotAutoSaveImpl(std::unique_ptr &&optionalClonedDocument);
class Private;
Private *const d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KisDocument::OpenFlags)
Q_DECLARE_METATYPE(KisDocument*)
#endif
diff --git a/libs/ui/KisWelcomePageWidget.cpp b/libs/ui/KisWelcomePageWidget.cpp
index b5f41f2df1..255a8e5e77 100644
--- a/libs/ui/KisWelcomePageWidget.cpp
+++ b/libs/ui/KisWelcomePageWidget.cpp
@@ -1,271 +1,276 @@
/* 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
+
#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"
#include "kis_config.h"
KisWelcomePageWidget::KisWelcomePageWidget(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
recentDocumentsListView->setDragEnabled(false);
recentDocumentsListView->viewport()->setAutoFillBackground(false);
recentDocumentsListView->setSpacing(2);
// set up URLs that go to web browser
manualLink->setText(QString("").append(i18n("User Manual")).append(""));
manualLink->setTextFormat(Qt::RichText);
manualLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
manualLink->setOpenExternalLinks(true);
gettingStartedLink->setText(QString("").append(i18n("Getting Started")).append(""));
gettingStartedLink->setTextFormat(Qt::RichText);
gettingStartedLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
gettingStartedLink->setOpenExternalLinks(true);
supportKritaLink->setText(QString("").append(i18n("Support Krita")).append(""));
supportKritaLink->setTextFormat(Qt::RichText);
supportKritaLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
supportKritaLink->setOpenExternalLinks(true);
userCommunityLink->setText(QString("").append(i18n("User Community")).append(""));
userCommunityLink->setTextFormat(Qt::RichText);
userCommunityLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
userCommunityLink->setOpenExternalLinks(true);
kritaWebsiteLink->setText(QString("").append(i18n("Krita Website")).append(""));
kritaWebsiteLink->setTextFormat(Qt::RichText);
kritaWebsiteLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
kritaWebsiteLink->setOpenExternalLinks(true);
sourceCodeLink->setText(QString("").append(i18n("Source Code")).append(""));
sourceCodeLink->setTextFormat(Qt::RichText);
sourceCodeLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
sourceCodeLink->setOpenExternalLinks(true);
poweredByKDELink->setText(QString("").append(i18n("Powered by KDE")).append(""));
poweredByKDELink->setTextFormat(Qt::RichText);
poweredByKDELink->setTextInteractionFlags(Qt::TextBrowserInteraction);
poweredByKDELink->setOpenExternalLinks(true);
kdeIcon->setIconSize(QSize(20, 20));
kdeIcon->setIcon(KisIconUtils::loadIcon(QStringLiteral("kde")).pixmap(20));
connect(chkShowNews, SIGNAL(toggled(bool)), newsWidget, SLOT(toggleNews(bool)));
// configure the News area
KisConfig cfg(true);
bool m_getNews = cfg.readEntry("FetchNews", false);
chkShowNews->setChecked(m_getNews);
}
KisWelcomePageWidget::~KisWelcomePageWidget()
{
}
void KisWelcomePageWidget::setMainWindow(KisMainWindow* mainWin)
{
if (mainWin) {
m_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(")"));
}
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()));
connect(clearRecentFilesLink, SIGNAL(clicked(bool)), this, SLOT(slotClearRecentFiles()));
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"));
}
void KisWelcomePageWidget::populateRecentDocuments()
{
m_recentFilesModel.clear(); // clear existing data before it gets re-populated
// grab recent files data
int numRecentFiles = m_mainWindow->recentFilesUrls().length() > 5 ? 5 : m_mainWindow->recentFilesUrls().length(); // grab at most 5
for (int i = 0; i < numRecentFiles; i++ ) {
QStandardItem *recentItem = new QStandardItem(1,2); // 1 row, 1 column
recentItem->setIcon(KisIconUtils::loadIcon("document-export"));
- QString recentFileUrlPath = m_mainWindow->recentFilesUrls().at(i).toString();
+ QString recentFileUrlPath = m_mainWindow->recentFilesUrls().at(i).toLocalFile();
QString fileName = recentFileUrlPath.split("/").last();
if (m_thumbnailMap.contains(recentFileUrlPath)) {
recentItem->setIcon(m_thumbnailMap[recentFileUrlPath]);
}
else {
- if (recentFileUrlPath.endsWith("ora") || recentFileUrlPath.endsWith("kra")) {
- 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);
- img.setDevicePixelRatio(devicePixelRatioF());
- recentItem->setIcon(QIcon(QPixmap::fromImage(img)));
+ if (QFileInfo(recentFileUrlPath).exists()) {
+ if (recentFileUrlPath.endsWith("ora") || recentFileUrlPath.endsWith("kra")) {
+ QScopedPointer store(KoStore::createStore(QUrl::fromLocalFile(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);
+ img.setDevicePixelRatio(devicePixelRatioF());
+ recentItem->setIcon(QIcon(QPixmap::fromImage(img)));
+ }
}
}
- }
- else {
- QImage img(QUrl(recentFileUrlPath).toLocalFile());
- img.setDevicePixelRatio(devicePixelRatioF());
- if (!img.isNull()) {
- recentItem->setIcon(QIcon(QPixmap::fromImage(img.scaledToWidth(48))));
+ else {
+ QImage img;
+ img.setDevicePixelRatio(devicePixelRatioF());
+ img.load(recentFileUrlPath);
+ if (!img.isNull()) {
+ recentItem->setIcon(QIcon(QPixmap::fromImage(img.scaledToWidth(48))));
+ }
}
+ m_thumbnailMap[recentFileUrlPath] = recentItem->icon();
}
- m_thumbnailMap[recentFileUrlPath] = recentItem->icon();
}
// set the recent object with the data
recentItem->setText(fileName); // what to display for the item
recentItem->setToolTip(recentFileUrlPath);
m_recentFilesModel.appendRow(recentItem);
}
// hide clear and Recent files title if there are none
bool hasRecentFiles = m_mainWindow->recentFilesUrls().length() > 0;
recentDocumentsLabel->setVisible(hasRecentFiles);
clearRecentFilesLink->setVisible(hasRecentFiles);
recentDocumentsListView->setIconSize(QSize(48, 48));
recentDocumentsListView->setModel(&m_recentFilesModel);
}
void KisWelcomePageWidget::recentDocumentClicked(QModelIndex index)
{
QString fileUrl = index.data(Qt::ToolTipRole).toString();
- m_mainWindow->openDocument(QUrl(fileUrl), KisMainWindow::None );
+ m_mainWindow->openDocument(QUrl::fromLocalFile(fileUrl), KisMainWindow::None );
}
void KisWelcomePageWidget::slotNewFileClicked()
{
m_mainWindow->slotFileNew();
}
void KisWelcomePageWidget::slotOpenFileClicked()
{
m_mainWindow->slotFileOpen();
}
void KisWelcomePageWidget::slotClearRecentFiles()
{
m_mainWindow->clearRecentFiles();
populateRecentDocuments();
}
diff --git a/libs/ui/dialogs/kis_dlg_layer_style.cpp b/libs/ui/dialogs/kis_dlg_layer_style.cpp
index 453ffc9a11..a715da7b9f 100644
--- a/libs/ui/dialogs/kis_dlg_layer_style.cpp
+++ b/libs/ui/dialogs/kis_dlg_layer_style.cpp
@@ -1,1447 +1,1338 @@
/*
* Copyright (c) 2014 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_dlg_layer_style.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
-
#include
#include
#include
#include "kis_config.h"
#include "kis_cmb_contour.h"
#include "kis_cmb_gradient.h"
#include "KisResourceServerProvider.h"
#include "kis_psd_layer_style_resource.h"
#include "kis_psd_layer_style.h"
#include "kis_signals_blocker.h"
#include "kis_signal_compressor.h"
#include "kis_canvas_resource_provider.h"
#include
-
KoAbstractGradientSP fetchGradientLazy(KoAbstractGradientSP gradient,
KisCanvasResourceProvider *resourceProvider)
{
if (!gradient) {
gradient = resourceProvider->currentGradient();
}
return gradient;
}
KisDlgLayerStyle::KisDlgLayerStyle(KisPSDLayerStyleSP layerStyle, KisCanvasResourceProvider *resourceProvider, QWidget *parent)
: KoDialog(parent)
, m_layerStyle(layerStyle)
, m_initialLayerStyle(layerStyle->clone())
, m_isSwitchingPredefinedStyle(false)
, m_sanityLayerStyleDirty(false)
{
setCaption(i18n("Layer Styles"));
setButtons(Ok | Cancel);
setDefaultButton(Ok);
m_configChangedCompressor =
new KisSignalCompressor(1000, KisSignalCompressor::POSTPONE, this);
connect(m_configChangedCompressor, SIGNAL(timeout()), SIGNAL(configChanged()));
QWidget *page = new QWidget(this);
wdgLayerStyles.setupUi(page);
setMainWidget(page);
wdgLayerStyles.chkPreview->setVisible(false);
connect(wdgLayerStyles.lstStyleSelector, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(notifyGuiConfigChanged()));
m_stylesSelector = new StylesSelector(this);
connect(m_stylesSelector, SIGNAL(styleSelected(KisPSDLayerStyleSP)), SLOT(notifyPredefinedStyleSelected(KisPSDLayerStyleSP)));
wdgLayerStyles.stylesStack->addWidget(m_stylesSelector);
m_blendingOptions = new BlendingOptions(this);
wdgLayerStyles.stylesStack->addWidget(m_blendingOptions);
m_dropShadow = new DropShadow(DropShadow::DropShadowMode, this);
wdgLayerStyles.stylesStack->addWidget(m_dropShadow);
connect(m_dropShadow, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_innerShadow = new DropShadow(DropShadow::InnerShadowMode, this);
wdgLayerStyles.stylesStack->addWidget(m_innerShadow);
connect(m_innerShadow, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_outerGlow = new InnerGlow(InnerGlow::OuterGlowMode, resourceProvider, this);
wdgLayerStyles.stylesStack->addWidget(m_outerGlow);
connect(m_outerGlow, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_innerGlow = new InnerGlow(InnerGlow::InnerGlowMode, resourceProvider, this);
wdgLayerStyles.stylesStack->addWidget(m_innerGlow);
connect(m_innerGlow, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_contour = new Contour(this);
m_texture = new Texture(this);
m_bevelAndEmboss = new BevelAndEmboss(m_contour, m_texture, this);
wdgLayerStyles.stylesStack->addWidget(m_bevelAndEmboss);
wdgLayerStyles.stylesStack->addWidget(m_contour);
wdgLayerStyles.stylesStack->addWidget(m_texture);
connect(m_bevelAndEmboss, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_satin = new Satin(this);
wdgLayerStyles.stylesStack->addWidget(m_satin);
connect(m_satin, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_colorOverlay = new ColorOverlay(this);
wdgLayerStyles.stylesStack->addWidget(m_colorOverlay);
connect(m_colorOverlay, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_gradientOverlay = new GradientOverlay(resourceProvider, this);
wdgLayerStyles.stylesStack->addWidget(m_gradientOverlay);
connect(m_gradientOverlay, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_patternOverlay = new PatternOverlay(this);
wdgLayerStyles.stylesStack->addWidget(m_patternOverlay);
connect(m_patternOverlay, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
m_stroke = new Stroke(resourceProvider, this);
wdgLayerStyles.stylesStack->addWidget(m_stroke);
connect(m_stroke, SIGNAL(configChanged()), SLOT(notifyGuiConfigChanged()));
KisConfig cfg(true);
wdgLayerStyles.stylesStack->setCurrentIndex(cfg.readEntry("KisDlgLayerStyle::current", 1));
wdgLayerStyles.lstStyleSelector->setCurrentRow(cfg.readEntry("KisDlgLayerStyle::current", 1));
connect(wdgLayerStyles.lstStyleSelector,
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
notifyPredefinedStyleSelected(layerStyle);
connect(m_dropShadow, SIGNAL(globalAngleChanged(int)), SLOT(syncGlobalAngle(int)));
connect(m_innerShadow, SIGNAL(globalAngleChanged(int)), SLOT(syncGlobalAngle(int)));
connect(m_bevelAndEmboss, SIGNAL(globalAngleChanged(int)), SLOT(syncGlobalAngle(int)));
connect(wdgLayerStyles.btnNewStyle, SIGNAL(clicked()), SLOT(slotNewStyle()));
connect(wdgLayerStyles.btnLoadStyle, SIGNAL(clicked()), SLOT(slotLoadStyle()));
connect(wdgLayerStyles.btnSaveStyle, SIGNAL(clicked()), SLOT(slotSaveStyle()));
connect(wdgLayerStyles.chkMasterFxSwitch, SIGNAL(toggled(bool)), SLOT(slotMasterFxSwitchChanged(bool)));
connect(this, SIGNAL(accepted()), SLOT(slotNotifyOnAccept()));
connect(this, SIGNAL(rejected()), SLOT(slotNotifyOnReject()));
}
KisDlgLayerStyle::~KisDlgLayerStyle()
{
}
void KisDlgLayerStyle::slotMasterFxSwitchChanged(bool value)
{
wdgLayerStyles.lstStyleSelector->setEnabled(value);
wdgLayerStyles.stylesStack->setEnabled(value);
wdgLayerStyles.btnNewStyle->setEnabled(value);
wdgLayerStyles.btnLoadStyle->setEnabled(value);
wdgLayerStyles.btnSaveStyle->setEnabled(value);
notifyGuiConfigChanged();
}
void KisDlgLayerStyle::notifyGuiConfigChanged()
{
if (m_isSwitchingPredefinedStyle) return;
m_configChangedCompressor->start();
m_layerStyle->setUuid(QUuid::createUuid());
m_sanityLayerStyleDirty = true;
m_stylesSelector->notifyExternalStyleChanged(m_layerStyle->name(), m_layerStyle->uuid());
}
void KisDlgLayerStyle::notifyPredefinedStyleSelected(KisPSDLayerStyleSP style)
{
m_isSwitchingPredefinedStyle = true;
setStyle(style);
m_isSwitchingPredefinedStyle = false;
m_configChangedCompressor->start();
}
void KisDlgLayerStyle::slotNotifyOnAccept()
{
if (m_configChangedCompressor->isActive()) {
m_configChangedCompressor->stop();
emit configChanged();
}
}
void KisDlgLayerStyle::slotNotifyOnReject()
{
notifyPredefinedStyleSelected(m_initialLayerStyle);
m_configChangedCompressor->stop();
emit configChanged();
}
bool checkCustomNameAvailable(const QString &name)
{
const QString customName = "CustomStyles.asl";
KoResourceServer *server = KisResourceServerProvider::instance()->layerStyleCollectionServer();
KoResourceSP resource = server->resourceByName(customName);
if (!resource) return true;
KisPSDLayerStyleCollectionResourceSP collection = resource.dynamicCast();
Q_FOREACH (KisPSDLayerStyleSP style, collection->layerStyles()) {
if (style->name() == name) {
return false;
}
}
return true;
}
QString selectAvailableStyleName(const QString &name)
{
QString finalName = name;
if (checkCustomNameAvailable(finalName)) {
return finalName;
}
int i = 0;
do {
finalName = QString("%1%2").arg(name).arg(i++);
} while (!checkCustomNameAvailable(finalName));
return finalName;
}
void KisDlgLayerStyle::slotNewStyle()
{
QString styleName =
QInputDialog::getText(this,
i18nc("@title:window", "Enter new style name"),
i18nc("@label:textbox", "Name:"),
QLineEdit::Normal, i18nc("Default name for a new style", "New Style"));
KisPSDLayerStyleSP style = this->style();
style->setName(selectAvailableStyleName(styleName));
m_stylesSelector->addNewStyle(style->clone());
}
void KisDlgLayerStyle::slotLoadStyle()
{
QString filename; // default value?
KoFileDialog dialog(this, KoFileDialog::OpenFile, "layerstyle");
dialog.setCaption(i18n("Select ASL file"));
dialog.setMimeTypeFilters(QStringList() << "application/x-photoshop-style-library", "application/x-photoshop-style-library");
filename = dialog.filename();
m_stylesSelector->loadCollection(filename);
wdgLayerStyles.lstStyleSelector->setCurrentRow(0);
}
void KisDlgLayerStyle::slotSaveStyle()
{
QString filename; // default value?
KoFileDialog dialog(this, KoFileDialog::SaveFile, "layerstyle");
dialog.setCaption(i18n("Select ASL file"));
dialog.setMimeTypeFilters(QStringList() << "application/x-photoshop-style-library", "application/x-photoshop-style-library");
filename = dialog.filename();
QScopedPointer collection(
new KisPSDLayerStyleCollectionResource(filename));
KisPSDLayerStyleSP newStyle = style()->clone();
newStyle->setName(QFileInfo(filename).baseName());
KisPSDLayerStyleCollectionResource::StylesVector vector = collection->layerStyles();
vector << newStyle;
collection->setLayerStyles(vector);
collection->save();
}
void KisDlgLayerStyle::changePage(QListWidgetItem *current, QListWidgetItem *previous)
{
if (!current) {
current = previous;
}
wdgLayerStyles.stylesStack->setCurrentIndex(wdgLayerStyles.lstStyleSelector->row(current));
}
void KisDlgLayerStyle::setStyle(KisPSDLayerStyleSP style)
{
// we may self-assign style is some cases
if (style != m_layerStyle) {
*m_layerStyle = *style;
}
m_sanityLayerStyleDirty = false;
{
KisSignalsBlocker b(m_stylesSelector);
m_stylesSelector->notifyExternalStyleChanged(m_layerStyle->name(), m_layerStyle->uuid());
}
QListWidgetItem *item;
item = wdgLayerStyles.lstStyleSelector->item(2);
item->setCheckState(m_layerStyle->dropShadow()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(3);
item->setCheckState(m_layerStyle->innerShadow()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(4);
item->setCheckState(m_layerStyle->outerGlow()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(5);
item->setCheckState(m_layerStyle->innerGlow()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(6);
item->setCheckState(m_layerStyle->bevelAndEmboss()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(7);
item->setCheckState(m_layerStyle->bevelAndEmboss()->contourEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(8);
item->setCheckState(m_layerStyle->bevelAndEmboss()->textureEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(9);
item->setCheckState(m_layerStyle->satin()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(10);
item->setCheckState(m_layerStyle->colorOverlay()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(11);
item->setCheckState(m_layerStyle->gradientOverlay()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(12);
item->setCheckState(m_layerStyle->patternOverlay()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
item = wdgLayerStyles.lstStyleSelector->item(13);
item->setCheckState(m_layerStyle->stroke()->effectEnabled() ? Qt::Checked : Qt::Unchecked);
m_dropShadow->setShadow(m_layerStyle->dropShadow());
m_innerShadow->setShadow(m_layerStyle->innerShadow());
m_outerGlow->setConfig(m_layerStyle->outerGlow());
m_innerGlow->setConfig(m_layerStyle->innerGlow());
m_bevelAndEmboss->setBevelAndEmboss(m_layerStyle->bevelAndEmboss());
m_satin->setSatin(m_layerStyle->satin());
m_colorOverlay->setColorOverlay(m_layerStyle->colorOverlay());
m_gradientOverlay->setGradientOverlay(m_layerStyle->gradientOverlay());
m_patternOverlay->setPatternOverlay(m_layerStyle->patternOverlay());
m_stroke->setStroke(m_layerStyle->stroke());
wdgLayerStyles.chkMasterFxSwitch->setChecked(m_layerStyle->isEnabled());
slotMasterFxSwitchChanged(m_layerStyle->isEnabled());
}
KisPSDLayerStyleSP KisDlgLayerStyle::style() const
{
m_layerStyle->setEnabled(wdgLayerStyles.chkMasterFxSwitch->isChecked());
m_layerStyle->dropShadow()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(2)->checkState() == Qt::Checked);
m_layerStyle->innerShadow()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(3)->checkState() == Qt::Checked);
m_layerStyle->outerGlow()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(4)->checkState() == Qt::Checked);
m_layerStyle->innerGlow()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(5)->checkState() == Qt::Checked);
m_layerStyle->bevelAndEmboss()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(6)->checkState() == Qt::Checked);
m_layerStyle->bevelAndEmboss()->setContourEnabled(wdgLayerStyles.lstStyleSelector->item(7)->checkState() == Qt::Checked);
m_layerStyle->bevelAndEmboss()->setTextureEnabled(wdgLayerStyles.lstStyleSelector->item(8)->checkState() == Qt::Checked);
m_layerStyle->satin()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(9)->checkState() == Qt::Checked);
m_layerStyle->colorOverlay()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(10)->checkState() == Qt::Checked);
m_layerStyle->gradientOverlay()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(11)->checkState() == Qt::Checked);
m_layerStyle->patternOverlay()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(12)->checkState() == Qt::Checked);
m_layerStyle->stroke()->setEffectEnabled(wdgLayerStyles.lstStyleSelector->item(13)->checkState() == Qt::Checked);
m_dropShadow->fetchShadow(m_layerStyle->dropShadow());
m_innerShadow->fetchShadow(m_layerStyle->innerShadow());
m_outerGlow->fetchConfig(m_layerStyle->outerGlow());
m_innerGlow->fetchConfig(m_layerStyle->innerGlow());
m_bevelAndEmboss->fetchBevelAndEmboss(m_layerStyle->bevelAndEmboss());
m_satin->fetchSatin(m_layerStyle->satin());
m_colorOverlay->fetchColorOverlay(m_layerStyle->colorOverlay());
m_gradientOverlay->fetchGradientOverlay(m_layerStyle->gradientOverlay());
m_patternOverlay->fetchPatternOverlay(m_layerStyle->patternOverlay());
m_stroke->fetchStroke(m_layerStyle->stroke());
m_sanityLayerStyleDirty = false;
m_stylesSelector->notifyExternalStyleChanged(m_layerStyle->name(), m_layerStyle->uuid());
return m_layerStyle;
}
void KisDlgLayerStyle::syncGlobalAngle(int angle)
{
KisPSDLayerStyleSP style = this->style();
if (style->dropShadow()->useGlobalLight()) {
style->dropShadow()->setAngle(angle);
}
if (style->innerShadow()->useGlobalLight()) {
style->innerShadow()->setAngle(angle);
}
if (style->bevelAndEmboss()->useGlobalLight()) {
style->bevelAndEmboss()->setAngle(angle);
}
setStyle(style);
}
/********************************************************************/
/***** Styles Selector **********************************************/
/********************************************************************/
class StyleItem : public QListWidgetItem {
public:
StyleItem(KisPSDLayerStyleSP style)
: QListWidgetItem(style->name())
, m_style(style)
{
}
public:
KisPSDLayerStyleSP m_style;
};
StylesSelector::StylesSelector(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
connect(ui.cmbStyleCollections, SIGNAL(activated(QString)), this, SLOT(loadStyles(QString)));
connect(ui.listStyles, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(selectStyle(QListWidgetItem*,QListWidgetItem*)));
refillCollections();
if (ui.cmbStyleCollections->count()) {
ui.cmbStyleCollections->setCurrentIndex(0);
loadStyles(ui.cmbStyleCollections->currentText());
}
}
void StylesSelector::refillCollections()
{
QString previousCollection = ui.cmbStyleCollections->currentText();
ui.cmbStyleCollections->clear();
Q_FOREACH (KoResourceSP res, KisResourceServerProvider::instance()->layerStyleCollectionServer()->resources()) {
ui.cmbStyleCollections->addItem(res->name());
}
if (!previousCollection.isEmpty()) {
KisSignalsBlocker blocker(this);
int index = ui.cmbStyleCollections->findText(previousCollection);
ui.cmbStyleCollections->setCurrentIndex(index);
}
}
void StylesSelector::notifyExternalStyleChanged(const QString &name, const QUuid &uuid)
{
int currentIndex = -1;
for (int i = 0; i < ui.listStyles->count(); i++ ) {
StyleItem *item = dynamic_cast(ui.listStyles->item(i));
QString itemName = item->m_style->name();
if (itemName == name) {
bool isDirty = item->m_style->uuid() != uuid;
if (isDirty) {
itemName += "*";
}
currentIndex = i;
}
item->setText(itemName);
}
ui.listStyles->setCurrentRow(currentIndex);
}
void StylesSelector::loadStyles(const QString &name)
{
ui.listStyles->clear();
KoResourceSP res = KisResourceServerProvider::instance()->layerStyleCollectionServer()->resourceByName(name);
KisPSDLayerStyleCollectionResourceSP collection = res.dynamicCast();
if (collection) {
Q_FOREACH (KisPSDLayerStyleSP style, collection->layerStyles()) {
// XXX: also use the preview image, when we have one
ui.listStyles->addItem(new StyleItem(style));
}
}
}
void StylesSelector::selectStyle(QListWidgetItem *current, QListWidgetItem* /*previous*/)
{
StyleItem *item = dynamic_cast(current);
if (item) {
emit styleSelected(item->m_style);
}
}
void StylesSelector::loadCollection(const QString &fileName)
{
if (!QFileInfo(fileName).exists()) {
warnKrita << "Loaded style collection doesn't exist!";
return;
}
KisPSDLayerStyleCollectionResourceSP collection = KisPSDLayerStyleCollectionResourceSP(new KisPSDLayerStyleCollectionResource(fileName));
collection->load();
KoResourceServer *server = KisResourceServerProvider::instance()->layerStyleCollectionServer();
collection->setFilename(server->saveLocation() + QDir::separator() + collection->name());
server->addResource(collection);
refillCollections();
int index = ui.cmbStyleCollections->findText(collection->name());
ui.cmbStyleCollections->setCurrentIndex(index);
loadStyles(collection->name());
}
void StylesSelector::addNewStyle(KisPSDLayerStyleSP style)
{
KoResourceServer *server = KisResourceServerProvider::instance()->layerStyleCollectionServer();
// NOTE: not translatable, since it is a key!
const QString customName = "CustomStyles.asl";
const QString saveLocation = server->saveLocation();
const QString fullFilename = saveLocation + customName;
KoResourceSP resource = server->resourceByName(customName);
KisPSDLayerStyleCollectionResourceSP collection;
if (!resource) {
collection = KisPSDLayerStyleCollectionResourceSP(new KisPSDLayerStyleCollectionResource(""));
collection->setName(customName);
collection->setFilename(fullFilename);
KisPSDLayerStyleCollectionResource::StylesVector vector;
vector << style;
collection->setLayerStyles(vector);
server->addResource(collection);
}
else {
collection = resource.dynamicCast();
KisPSDLayerStyleCollectionResource::StylesVector vector;
vector = collection->layerStyles();
vector << style;
collection->setLayerStyles(vector);
collection->save();
}
refillCollections();
// select in gui
int index = ui.cmbStyleCollections->findText(customName);
KIS_ASSERT_RECOVER_RETURN(index >= 0);
ui.cmbStyleCollections->setCurrentIndex(index);
loadStyles(customName);
notifyExternalStyleChanged(style->name(), style->uuid());
}
/********************************************************************/
/***** Bevel and Emboss *********************************************/
/********************************************************************/
BevelAndEmboss::BevelAndEmboss(Contour *contour, Texture *texture, QWidget *parent)
: QWidget(parent)
, m_contour(contour)
, m_texture(texture)
{
ui.setupUi(this);
// Structure
ui.intDepth->setRange(0, 100);
ui.intDepth->setSuffix(i18n(" %"));
ui.intSize->setRange(0, 250);
ui.intSize->setSuffix(i18n(" px"));
ui.intSoften->setRange(0, 18);
ui.intSoften->setSuffix(i18n(" px"));
connect(ui.cmbStyle, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbTechnique, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intDepth, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbDirection, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intSize, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intSoften, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
// Shading
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intOpacity2->setRange(0, 100);
ui.intOpacity2->setSuffix(i18n(" %"));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SLOT(slotDialAngleChanged(int)));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SLOT(slotIntAngleChanged(int)));
- connect(ui.chkUseGlobalLight, SIGNAL(toggled(bool)), SLOT(slotGlobalLightToggled()));
+ ui.angleSelector->enableGlobalLight(true);
+ connect(ui.angleSelector, SIGNAL(globalAngleChanged(int)), SIGNAL(globalAngleChanged(int)));
+ connect(ui.angleSelector, SIGNAL(configChanged()), SIGNAL(configChanged()));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.chkUseGlobalLight, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.intAltitude, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbContour, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.chkAntiAliased, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.cmbHighlightMode, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.bnHighlightColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbShadowMode, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.bnShadowColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
connect(ui.intOpacity2, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
// Contour
m_contour->ui.intRange->setRange(1, 100);
m_contour->ui.intRange->setSuffix(i18n(" %"));
connect(m_contour->ui.cmbContour, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(m_contour->ui.chkAntiAliased, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(m_contour->ui.intRange, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
// Texture
m_texture->ui.intScale->setRange(0, 100);
m_texture->ui.intScale->setSuffix(i18n(" %"));
m_texture->ui.intDepth->setRange(-1000, 1000);
m_texture->ui.intDepth->setSuffix(i18n(" %"));
connect(m_texture->ui.patternChooser, SIGNAL(resourceSelected(KoResourceSP )), SIGNAL(configChanged()));
connect(m_texture->ui.intScale, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(m_texture->ui.intDepth, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(m_texture->ui.chkInvert, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(m_texture->ui.chkLinkWithLayer, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
}
void BevelAndEmboss::setBevelAndEmboss(const psd_layer_effects_bevel_emboss *bevelAndEmboss)
{
ui.cmbStyle->setCurrentIndex((int)bevelAndEmboss->style());
ui.cmbTechnique->setCurrentIndex((int)bevelAndEmboss->technique());
ui.intDepth->setValue(bevelAndEmboss->depth());
ui.cmbDirection->setCurrentIndex((int)bevelAndEmboss->direction());
ui.intSize->setValue(bevelAndEmboss->size());
ui.intSoften->setValue(bevelAndEmboss->soften());
- ui.dialAngle->setValue(bevelAndEmboss->angle());
- ui.intAngle->setValue(bevelAndEmboss->angle());
- ui.chkUseGlobalLight->setChecked(bevelAndEmboss->useGlobalLight());
+ ui.angleSelector->setValue(bevelAndEmboss->angle());
+ ui.angleSelector->setUseGlobalLight(bevelAndEmboss->useGlobalLight());
+
ui.intAltitude->setValue(bevelAndEmboss->altitude());
// FIXME: curve editing
// ui.cmbContour;
ui.chkAntiAliased->setChecked(bevelAndEmboss->glossAntiAliased());
ui.cmbHighlightMode->selectCompositeOp(KoID(bevelAndEmboss->highlightBlendMode()));
KoColor highlightshadow(KoColorSpaceRegistry::instance()->rgb8());
highlightshadow.fromQColor(bevelAndEmboss->highlightColor());
ui.bnHighlightColor->setColor(highlightshadow);
ui.intOpacity->setValue(bevelAndEmboss->highlightOpacity());
ui.cmbShadowMode->selectCompositeOp(KoID(bevelAndEmboss->shadowBlendMode()));
highlightshadow.fromQColor(bevelAndEmboss->shadowColor());
ui.bnShadowColor->setColor(highlightshadow);
ui.intOpacity2->setValue(bevelAndEmboss->shadowOpacity());
// FIXME: curve editing
// m_contour->ui.cmbContour;
m_contour->ui.chkAntiAliased->setChecked(bevelAndEmboss->antiAliased());
m_contour->ui.intRange->setValue(bevelAndEmboss->contourRange());
m_texture->ui.patternChooser->setCurrentPattern(bevelAndEmboss->texturePattern());
m_texture->ui.intScale->setValue(bevelAndEmboss->textureScale());
m_texture->ui.intDepth->setValue(bevelAndEmboss->textureDepth());
m_texture->ui.chkInvert->setChecked(bevelAndEmboss->textureInvert());
m_texture->ui.chkLinkWithLayer->setChecked(bevelAndEmboss->textureAlignWithLayer());
}
void BevelAndEmboss::fetchBevelAndEmboss(psd_layer_effects_bevel_emboss *bevelAndEmboss) const
{
bevelAndEmboss->setStyle((psd_bevel_style)ui.cmbStyle->currentIndex());
bevelAndEmboss->setTechnique((psd_technique_type)ui.cmbTechnique->currentIndex());
bevelAndEmboss->setDepth(ui.intDepth->value());
bevelAndEmboss->setDirection((psd_direction)ui.cmbDirection->currentIndex());
bevelAndEmboss->setSize(ui.intSize->value());
bevelAndEmboss->setSoften(ui.intSoften->value());
- bevelAndEmboss->setAngle(ui.dialAngle->value());
- bevelAndEmboss->setUseGlobalLight(ui.chkUseGlobalLight->isChecked());
+ bevelAndEmboss->setAngle(ui.angleSelector->value());
+ bevelAndEmboss->setUseGlobalLight(ui.angleSelector->useGlobalLight());
bevelAndEmboss->setAltitude(ui.intAltitude->value());
bevelAndEmboss->setGlossAntiAliased(ui.chkAntiAliased->isChecked());
bevelAndEmboss->setHighlightBlendMode(ui.cmbHighlightMode->selectedCompositeOp().id());
bevelAndEmboss->setHighlightColor(ui.bnHighlightColor->color().toQColor());
bevelAndEmboss->setHighlightOpacity(ui.intOpacity->value());
bevelAndEmboss->setShadowBlendMode(ui.cmbShadowMode->selectedCompositeOp().id());
bevelAndEmboss->setShadowColor(ui.bnShadowColor->color().toQColor());
bevelAndEmboss->setShadowOpacity(ui.intOpacity2->value());
// FIXME: curve editing
bevelAndEmboss->setAntiAliased(m_contour->ui.chkAntiAliased->isChecked());
bevelAndEmboss->setContourRange(m_contour->ui.intRange->value());
bevelAndEmboss->setTexturePattern(m_texture->ui.patternChooser->currentResource().staticCast());
bevelAndEmboss->setTextureScale(m_texture->ui.intScale->value());
bevelAndEmboss->setTextureDepth(m_texture->ui.intDepth->value());
bevelAndEmboss->setTextureInvert(m_texture->ui.chkInvert->isChecked());
bevelAndEmboss->setTextureAlignWithLayer(m_texture->ui.chkLinkWithLayer->isChecked());
}
-void BevelAndEmboss::slotDialAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.intAngle);
- ui.intAngle->setValue(value);
-
- if (ui.chkUseGlobalLight->isChecked()) {
- emit globalAngleChanged(value);
- }
-}
-
-void BevelAndEmboss::slotIntAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.dialAngle);
- ui.dialAngle->setValue(value);
-
- if (ui.chkUseGlobalLight->isChecked()) {
- emit globalAngleChanged(value);
- }
-}
-
-void BevelAndEmboss::slotGlobalLightToggled()
-{
- if (ui.chkUseGlobalLight->isChecked()) {
- emit globalAngleChanged(ui.intAngle->value());
- }
-}
/********************************************************************/
/***** Texture *********************************************/
/********************************************************************/
Texture::Texture(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
/********************************************************************/
/***** Contour *********************************************/
/********************************************************************/
Contour::Contour(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
/********************************************************************/
/***** Blending Options *********************************************/
/********************************************************************/
BlendingOptions::BlendingOptions(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
// FIXME: Blend options are not implemented yet
ui.grpBlendingOptions->setTitle(QString("%1 (%2)").arg(ui.grpBlendingOptions->title()).arg(i18n("Not Implemented Yet")));
ui.grpBlendingOptions->setEnabled(false);
}
/********************************************************************/
/***** Color Overlay *********************************************/
/********************************************************************/
ColorOverlay::ColorOverlay(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.bnColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
}
void ColorOverlay::setColorOverlay(const psd_layer_effects_color_overlay *colorOverlay)
{
ui.cmbCompositeOp->selectCompositeOp(KoID(colorOverlay->blendMode()));
ui.intOpacity->setValue(colorOverlay->opacity());
KoColor color(KoColorSpaceRegistry::instance()->rgb8());
color.fromQColor(colorOverlay->color());
ui.bnColor->setColor(color);
}
void ColorOverlay::fetchColorOverlay(psd_layer_effects_color_overlay *colorOverlay) const
{
colorOverlay->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
colorOverlay->setOpacity(ui.intOpacity->value());
colorOverlay->setColor(ui.bnColor->color().toQColor());
}
/********************************************************************/
/***** Drop Shadow **************************************************/
/********************************************************************/
DropShadow::DropShadow(Mode mode, QWidget *parent)
: QWidget(parent),
m_mode(mode)
{
ui.setupUi(this);
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intDistance->setRange(0, 500);
ui.intDistance->setSuffix(i18n(" px"));
ui.intDistance->setExponentRatio(3.0);
ui.intSpread->setRange(0, 100);
ui.intSpread->setSuffix(i18n(" %"));
ui.intSize->setRange(0, 250);
ui.intSize->setSuffix(i18n(" px"));
ui.intNoise->setRange(0, 100);
ui.intNoise->setSuffix(i18n(" %"));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SLOT(slotDialAngleChanged(int)));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SLOT(slotIntAngleChanged(int)));
- connect(ui.chkUseGlobalLight, SIGNAL(toggled(bool)), SLOT(slotGlobalLightToggled()));
+ ui.angleSelector->enableGlobalLight(true);
+ connect(ui.angleSelector, SIGNAL(globalAngleChanged(int)), SIGNAL(globalAngleChanged(int)));
+ connect(ui.angleSelector, SIGNAL(configChanged()), SIGNAL(configChanged()));
// connect everything to configChanged() signal
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.bnColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.chkUseGlobalLight, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
-
connect(ui.intDistance, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intSpread, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intSize, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbContour, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.chkAntiAliased, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.intNoise, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.chkLayerKnocksOutDropShadow, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
if (m_mode == InnerShadowMode) {
ui.chkLayerKnocksOutDropShadow->setVisible(false);
ui.grpMain->setTitle(i18n("Inner Shadow"));
ui.lblSpread->setText(i18n("Choke:"));
}
}
-void DropShadow::slotDialAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.intAngle);
- ui.intAngle->setValue(value);
-
- if (ui.chkUseGlobalLight->isChecked()) {
- emit globalAngleChanged(value);
- }
-}
-
-void DropShadow::slotIntAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.dialAngle);
- ui.dialAngle->setValue(value);
-
- if (ui.chkUseGlobalLight->isChecked()) {
- emit globalAngleChanged(value);
- }
-}
-
-void DropShadow::slotGlobalLightToggled()
-{
- if (ui.chkUseGlobalLight->isChecked()) {
- emit globalAngleChanged(ui.intAngle->value());
- }
-}
-
void DropShadow::setShadow(const psd_layer_effects_shadow_common *shadow)
{
ui.cmbCompositeOp->selectCompositeOp(KoID(shadow->blendMode()));
ui.intOpacity->setValue(shadow->opacity());
KoColor color(KoColorSpaceRegistry::instance()->rgb8());
color.fromQColor(shadow->color());
ui.bnColor->setColor(color);
- ui.dialAngle->setValue(shadow->angle());
- ui.intAngle->setValue(shadow->angle());
- ui.chkUseGlobalLight->setChecked(shadow->useGlobalLight());
+ ui.angleSelector->setValue(shadow->angle());
+ ui.angleSelector->setUseGlobalLight(shadow->useGlobalLight());
ui.intDistance->setValue(shadow->distance());
ui.intSpread->setValue(shadow->spread());
ui.intSize->setValue(shadow->size());
// FIXME: curve editing
// ui.cmbContour;
ui.chkAntiAliased->setChecked(shadow->antiAliased());
ui.intNoise->setValue(shadow->noise());
if (m_mode == DropShadowMode) {
const psd_layer_effects_drop_shadow *realDropShadow = dynamic_cast(shadow);
KIS_ASSERT_RECOVER_NOOP(realDropShadow);
ui.chkLayerKnocksOutDropShadow->setChecked(shadow->knocksOut());
}
}
void DropShadow::fetchShadow(psd_layer_effects_shadow_common *shadow) const
{
shadow->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
shadow->setOpacity(ui.intOpacity->value());
shadow->setColor(ui.bnColor->color().toQColor());
- shadow->setAngle(ui.dialAngle->value());
- shadow->setUseGlobalLight(ui.chkUseGlobalLight->isChecked());
+ shadow->setAngle(ui.angleSelector->value());
+ shadow->setUseGlobalLight(ui.angleSelector->useGlobalLight());
shadow->setDistance(ui.intDistance->value());
shadow->setSpread(ui.intSpread->value());
shadow->setSize(ui.intSize->value());
// FIXME: curve editing
// ui.cmbContour;
shadow->setAntiAliased(ui.chkAntiAliased->isChecked());
shadow->setNoise(ui.intNoise->value());
if (m_mode == DropShadowMode) {
psd_layer_effects_drop_shadow *realDropShadow = dynamic_cast(shadow);
KIS_ASSERT_RECOVER_NOOP(realDropShadow);
realDropShadow->setKnocksOut(ui.chkLayerKnocksOutDropShadow->isChecked());
}
}
class GradientPointerConverter
{
public:
static KoAbstractGradientSP resourceToStyle(KoAbstractGradientSP gradient) {
return gradient ? KoAbstractGradientSP(gradient->clone()) : KoAbstractGradientSP();
}
static KoAbstractGradientSP styleToResource(KoAbstractGradientSP gradient) {
if (!gradient) return 0;
KoResourceServer *server = KoResourceServerProvider::instance()->gradientServer();
KoAbstractGradientSP resource = server->resourceByMD5(gradient->md5());
if (!resource) {
KoAbstractGradientSP clone = gradient->clone();
clone->setName(findAvailableName(gradient->name()));
server->addResource(clone, false);
resource = clone;
}
return resource;
}
private:
static QString findAvailableName(const QString &name) {
KoResourceServer *server = KoResourceServerProvider::instance()->gradientServer();
QString newName = name;
int i = 0;
while (server->resourceByName(newName)) {
newName = QString("%1%2").arg(name).arg(i++);
}
return newName;
}
};
/********************************************************************/
/***** Gradient Overlay *********************************************/
/********************************************************************/
GradientOverlay::GradientOverlay(KisCanvasResourceProvider *resourceProvider, QWidget *parent)
: QWidget(parent),
m_resourceProvider(resourceProvider)
{
ui.setupUi(this);
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intScale->setRange(0, 100);
ui.intScale->setSuffix(i18n(" %"));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SLOT(slotDialAngleChanged(int)));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SLOT(slotIntAngleChanged(int)));
+ connect(ui.angleSelector, SIGNAL(configChanged()), SIGNAL(configChanged()));
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbGradient, SIGNAL(gradientChanged(KoAbstractGradient*)), SIGNAL(configChanged()));
connect(ui.chkReverse, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.cmbStyle, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.chkAlignWithLayer, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intScale, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
}
void GradientOverlay::setGradientOverlay(const psd_layer_effects_gradient_overlay *config)
{
ui.cmbCompositeOp->selectCompositeOp(KoID(config->blendMode()));
ui.intOpacity->setValue(config->opacity());
KoAbstractGradientSP gradient = fetchGradientLazy(GradientPointerConverter::styleToResource(config->gradient()), m_resourceProvider);
if (gradient) {
ui.cmbGradient->setGradient(gradient);
}
ui.chkReverse->setChecked(config->reverse());
ui.cmbStyle->setCurrentIndex((int)config->style());
ui.chkAlignWithLayer->setCheckable(config->alignWithLayer());
- ui.dialAngle->setValue(config->angle());
- ui.intAngle->setValue(config->angle());
+ ui.angleSelector->setValue(config->angle());
ui.intScale->setValue(config->scale());
}
void GradientOverlay::fetchGradientOverlay(psd_layer_effects_gradient_overlay *config) const
{
config->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
config->setOpacity(ui.intOpacity->value());
config->setGradient(GradientPointerConverter::resourceToStyle(ui.cmbGradient->gradient()));
config->setReverse(ui.chkReverse->isChecked());
config->setStyle((psd_gradient_style)ui.cmbStyle->currentIndex());
config->setAlignWithLayer(ui.chkAlignWithLayer->isChecked());
- config->setAngle(ui.dialAngle->value());
+ config->setAngle(ui.angleSelector->value());
config->setScale(ui.intScale->value());
}
-void GradientOverlay::slotDialAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.intAngle);
- ui.intAngle->setValue(value);
-}
-
-void GradientOverlay::slotIntAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.dialAngle);
- ui.dialAngle->setValue(value);
-}
/********************************************************************/
/***** Innner Glow *********************************************/
/********************************************************************/
InnerGlow::InnerGlow(Mode mode, KisCanvasResourceProvider *resourceProvider, QWidget *parent)
: QWidget(parent),
m_mode(mode),
m_resourceProvider(resourceProvider)
{
ui.setupUi(this);
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intNoise->setRange(0, 100);
ui.intNoise->setSuffix(i18n(" %"));
ui.intChoke->setRange(0, 100);
ui.intChoke->setSuffix(i18n(" %"));
ui.intSize->setRange(0, 250);
ui.intSize->setSuffix(i18n(" px"));
ui.intRange->setRange(1, 100);
ui.intRange->setSuffix(i18n(" %"));
ui.intJitter->setRange(0, 100);
ui.intJitter->setSuffix(i18n(" %"));
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intNoise, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.radioColor, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.bnColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
connect(ui.radioGradient, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.cmbGradient, SIGNAL(gradientChanged(KoAbstractGradient*)), SIGNAL(configChanged()));
connect(ui.cmbTechnique, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbSource, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intChoke, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intSize, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbContour, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.chkAntiAliased, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.intRange, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intJitter, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
if (m_mode == OuterGlowMode) {
ui.cmbSource->hide();
ui.lblSource->hide();
ui.lblChoke->setText(i18nc("layer styles parameter", "Spread:"));
}
}
void InnerGlow::setConfig(const psd_layer_effects_glow_common *config)
{
ui.cmbCompositeOp->selectCompositeOp(KoID(config->blendMode()));
ui.intOpacity->setValue(config->opacity());
ui.intNoise->setValue(config->noise());
ui.radioColor->setChecked(config->fillType() == psd_fill_solid_color);
KoColor color(KoColorSpaceRegistry::instance()->rgb8());
color.fromQColor(config->color());
ui.bnColor->setColor(color);
ui.radioGradient->setChecked(config->fillType() == psd_fill_gradient);
KoAbstractGradientSP gradient = fetchGradientLazy(GradientPointerConverter::styleToResource(config->gradient()), m_resourceProvider);
if (gradient) {
ui.cmbGradient->setGradient(gradient);
}
ui.cmbTechnique->setCurrentIndex((int)config->technique());
ui.intChoke->setValue(config->spread());
ui.intSize->setValue(config->size());
if (m_mode == InnerGlowMode) {
const psd_layer_effects_inner_glow *iglow =
dynamic_cast(config);
KIS_ASSERT_RECOVER_RETURN(iglow);
ui.cmbSource->setCurrentIndex(iglow->source() == psd_glow_edge);
}
// FIXME: Curve editing
//ui.cmbContour;
ui.chkAntiAliased->setChecked(config->antiAliased());
ui.intRange->setValue(config->range());
ui.intJitter->setValue(config->jitter());
}
void InnerGlow::fetchConfig(psd_layer_effects_glow_common *config) const
{
config->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
config->setOpacity(ui.intOpacity->value());
config->setNoise(ui.intNoise->value());
if (ui.radioColor->isChecked()) {
config->setFillType(psd_fill_solid_color);
}
else {
config->setFillType(psd_fill_gradient);
}
config->setColor(ui.bnColor->color().toQColor());
config->setGradient(GradientPointerConverter::resourceToStyle(ui.cmbGradient->gradient()));
config->setTechnique((psd_technique_type)ui.cmbTechnique->currentIndex());
config->setSpread(ui.intChoke->value());
config->setSize(ui.intSize->value());
if (m_mode == InnerGlowMode) {
psd_layer_effects_inner_glow *iglow =
dynamic_cast(config);
KIS_ASSERT_RECOVER_RETURN(iglow);
iglow->setSource((psd_glow_source)ui.cmbSource->currentIndex());
}
// FIXME: Curve editing
//ui.cmbContour;
config->setAntiAliased(ui.chkAntiAliased->isChecked());
config->setRange(ui.intRange->value());
config->setJitter(ui.intJitter->value());
}
/********************************************************************/
/***** Pattern Overlay *********************************************/
/********************************************************************/
PatternOverlay::PatternOverlay(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intScale->setRange(0, 100);
ui.intScale->setSuffix(i18n(" %"));
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.patternChooser, SIGNAL(resourceSelected(KoResourceSP )), SIGNAL(configChanged()));
connect(ui.chkLinkWithLayer, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.intScale, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
}
void PatternOverlay::setPatternOverlay(const psd_layer_effects_pattern_overlay *pattern)
{
ui.cmbCompositeOp->selectCompositeOp(KoID(pattern->blendMode()));
ui.intOpacity->setValue(pattern->opacity());
ui.patternChooser->setCurrentPattern(pattern->pattern());
ui.chkLinkWithLayer->setChecked(pattern->alignWithLayer());
ui.intScale->setValue(pattern->scale());
}
void PatternOverlay::fetchPatternOverlay(psd_layer_effects_pattern_overlay *pattern) const
{
pattern->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
pattern->setOpacity(ui.intOpacity->value());
pattern->setPattern(ui.patternChooser->currentResource().staticCast());
pattern->setAlignWithLayer(ui.chkLinkWithLayer->isChecked());
pattern->setScale(ui.intScale->value());
}
/********************************************************************/
/***** Satin *********************************************/
/********************************************************************/
Satin::Satin(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intDistance->setRange(0, 250);
ui.intDistance->setSuffix(i18n(" px"));
ui.intSize->setRange(0, 250);
ui.intSize->setSuffix(i18n(" px"));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SLOT(slotDialAngleChanged(int)));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SLOT(slotIntAngleChanged(int)));
-
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.bnColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
+ connect(ui.angleSelector, SIGNAL(configChanged()), SIGNAL(configChanged()));
connect(ui.intDistance, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.intSize, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbContour, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.chkAntiAliased, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.chkInvert, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
}
-void Satin::slotDialAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.intAngle);
- ui.intAngle->setValue(value);
-}
-
-void Satin::slotIntAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.dialAngle);
- ui.dialAngle->setValue(value);
-}
-
void Satin::setSatin(const psd_layer_effects_satin *satin)
{
ui.cmbCompositeOp->selectCompositeOp(KoID(satin->blendMode()));
KoColor color(KoColorSpaceRegistry::instance()->rgb8());
color.fromQColor(satin->color());
ui.bnColor->setColor(color);
ui.intOpacity->setValue(satin->opacity());
- ui.dialAngle->setValue(satin->angle());
- ui.intAngle->setValue(satin->angle());
+ ui.angleSelector->setValue(satin->angle());
ui.intDistance->setValue(satin->distance());
ui.intSize->setValue(satin->size());
// FIXME: Curve editing
//ui.cmbContour;
ui.chkAntiAliased->setChecked(satin->antiAliased());
ui.chkInvert->setChecked(satin->invert());
}
void Satin::fetchSatin(psd_layer_effects_satin *satin) const
{
satin->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
satin->setOpacity(ui.intOpacity->value());
satin->setColor(ui.bnColor->color().toQColor());
- satin->setAngle(ui.dialAngle->value());
+ satin->setAngle(ui.angleSelector->value());
satin->setDistance(ui.intDistance->value());
satin->setSize(ui.intSize->value());
// FIXME: curve editing
// ui.cmbContour;
satin->setAntiAliased(ui.chkAntiAliased->isChecked());
satin->setInvert(ui.chkInvert->isChecked());
}
/********************************************************************/
/***** Stroke *********************************************/
/********************************************************************/
Stroke::Stroke(KisCanvasResourceProvider *resourceProvider, QWidget *parent)
: QWidget(parent),
m_resourceProvider(resourceProvider)
{
ui.setupUi(this);
ui.intSize->setRange(0, 250);
ui.intSize->setSuffix(i18n(" px"));
ui.intOpacity->setRange(0, 100);
ui.intOpacity->setSuffix(i18n(" %"));
ui.intScale->setRange(0, 100);
ui.intScale->setSuffix(i18n(" %"));
ui.intScale_2->setRange(0, 100);
ui.intScale_2->setSuffix(i18n(" %"));
connect(ui.cmbFillType, SIGNAL(currentIndexChanged(int)), ui.fillStack, SLOT(setCurrentIndex(int)));
connect(ui.intSize, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbPosition, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbCompositeOp, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.intOpacity, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.cmbFillType, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.bnColor, SIGNAL(changed(KoColor)), SIGNAL(configChanged()));
connect(ui.cmbGradient, SIGNAL(gradientChanged(KoAbstractGradient*)), SIGNAL(configChanged()));
connect(ui.chkReverse, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.cmbStyle, SIGNAL(currentIndexChanged(int)), SIGNAL(configChanged()));
connect(ui.chkAlignWithLayer, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
- connect(ui.dialAngle, SIGNAL(valueChanged(int)), SLOT(slotDialAngleChanged(int)));
- connect(ui.intAngle, SIGNAL(valueChanged(int)), SLOT(slotIntAngleChanged(int)));
connect(ui.intScale, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
connect(ui.patternChooser, SIGNAL(resourceSelected(KoResourceSP )), SIGNAL(configChanged()));
+ connect(ui.angleSelector, SIGNAL(configChanged()), SIGNAL(configChanged()));
+
connect(ui.chkLinkWithLayer, SIGNAL(toggled(bool)), SIGNAL(configChanged()));
connect(ui.intScale_2, SIGNAL(valueChanged(int)), SIGNAL(configChanged()));
// cold initialization
ui.fillStack->setCurrentIndex(ui.cmbFillType->currentIndex());
}
-void Stroke::slotDialAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.intAngle);
- ui.intAngle->setValue(value);
-}
-
-void Stroke::slotIntAngleChanged(int value)
-{
- KisSignalsBlocker b(ui.dialAngle);
- ui.dialAngle->setValue(value);
-}
-
-
void Stroke::setStroke(const psd_layer_effects_stroke *stroke)
{
ui.intSize->setValue(stroke->size());
ui.cmbPosition->setCurrentIndex((int)stroke->position());
ui.cmbCompositeOp->selectCompositeOp(KoID(stroke->blendMode()));
ui.intOpacity->setValue(stroke->opacity());
ui.cmbFillType->setCurrentIndex((int)stroke->fillType());
KoColor color(KoColorSpaceRegistry::instance()->rgb8());
color.fromQColor(stroke->color());
ui.bnColor->setColor(color);
KoAbstractGradientSP gradient = fetchGradientLazy(GradientPointerConverter::styleToResource(stroke->gradient()), m_resourceProvider);
if (gradient) {
ui.cmbGradient->setGradient(gradient);
}
ui.chkReverse->setChecked(stroke->antiAliased());
ui.cmbStyle->setCurrentIndex((int)stroke->style());
ui.chkAlignWithLayer->setCheckable(stroke->alignWithLayer());
- ui.dialAngle->setValue(stroke->angle());
- ui.intAngle->setValue(stroke->angle());
+ ui.angleSelector->setValue(stroke->angle());
ui.intScale->setValue(stroke->scale());
ui.patternChooser->setCurrentPattern(stroke->pattern());
ui.chkLinkWithLayer->setChecked(stroke->alignWithLayer());
ui.intScale_2->setValue(stroke->scale());
}
void Stroke::fetchStroke(psd_layer_effects_stroke *stroke) const
{
stroke->setSize(ui.intSize->value());
stroke->setPosition((psd_stroke_position)ui.cmbPosition->currentIndex());
stroke->setBlendMode(ui.cmbCompositeOp->selectedCompositeOp().id());
stroke->setOpacity(ui.intOpacity->value());
stroke->setFillType((psd_fill_type)ui.cmbFillType->currentIndex());
stroke->setColor(ui.bnColor->color().toQColor());
stroke->setGradient(GradientPointerConverter::resourceToStyle(ui.cmbGradient->gradient()));
stroke->setReverse(ui.chkReverse->isChecked());
stroke->setStyle((psd_gradient_style)ui.cmbStyle->currentIndex());
stroke->setAlignWithLayer(ui.chkAlignWithLayer->isChecked());
- stroke->setAngle(ui.dialAngle->value());
+ stroke->setAngle(ui.angleSelector->value());
stroke->setScale(ui.intScale->value());
stroke->setPattern(ui.patternChooser->currentResource().staticCast());
stroke->setAlignWithLayer(ui.chkLinkWithLayer->isChecked());
stroke->setScale(ui.intScale->value());
}
diff --git a/libs/ui/dialogs/kis_dlg_layer_style.h b/libs/ui/dialogs/kis_dlg_layer_style.h
index 98a561e53b..0101b62933 100644
--- a/libs/ui/dialogs/kis_dlg_layer_style.h
+++ b/libs/ui/dialogs/kis_dlg_layer_style.h
@@ -1,323 +1,299 @@
/*
* Copyright (c) 2014 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_DLG_LAYER_STYLE_H
#define KIS_DLG_LAYER_STYLE_H
#include
#include
#include "kis_types.h"
#include
#include "ui_wdglayerstyles.h"
#include "ui_wdgBevelAndEmboss.h"
#include "ui_wdgblendingoptions.h"
#include "ui_WdgColorOverlay.h"
#include "ui_wdgContour.h"
#include "ui_wdgdropshadow.h"
#include "ui_WdgGradientOverlay.h"
#include "ui_wdgInnerGlow.h"
#include "ui_WdgPatternOverlay.h"
#include "ui_WdgSatin.h"
#include "ui_WdgStroke.h"
#include "ui_wdgstylesselector.h"
#include "ui_wdgTexture.h"
#include
class QListWidgetItem;
class KisSignalCompressor;
class KisCanvasResourceProvider;
class Contour : public QWidget {
Q_OBJECT
public:
Contour(QWidget *parent);
Ui::WdgContour ui;
};
class Texture : public QWidget {
Q_OBJECT
public:
Texture(QWidget *parent);
Ui::WdgTexture ui;
};
class BevelAndEmboss : public QWidget {
Q_OBJECT
public:
BevelAndEmboss(Contour *contour, Texture *texture, QWidget *parent);
void setBevelAndEmboss(const psd_layer_effects_bevel_emboss *bevelAndEmboss);
void fetchBevelAndEmboss(psd_layer_effects_bevel_emboss *bevelAndEmboss) const;
-private Q_SLOTS:
- void slotDialAngleChanged(int value);
- void slotIntAngleChanged(int value);
-
- void slotGlobalLightToggled();
-
Q_SIGNALS:
void configChanged();
void globalAngleChanged(int value);
private:
Contour *m_contour;
Texture *m_texture;
Ui::WdgBevelAndEmboss ui;
};
class BlendingOptions : public QWidget {
Q_OBJECT
public:
BlendingOptions(QWidget *parent);
Q_SIGNALS:
void configChanged();
private:
Ui::WdgBlendingOptions ui;
};
class ColorOverlay : public QWidget {
Q_OBJECT
public:
ColorOverlay(QWidget *parent);
void setColorOverlay(const psd_layer_effects_color_overlay *colorOverlay);
void fetchColorOverlay(psd_layer_effects_color_overlay *colorOverlay) const;
Q_SIGNALS:
void configChanged();
private:
Ui::WdgColorOverlay ui;
};
class DropShadow : public QWidget {
Q_OBJECT
public:
enum Mode {
DropShadowMode,
InnerShadowMode
};
public:
DropShadow(Mode mode, QWidget *parent);
void setShadow(const psd_layer_effects_shadow_common *shadow);
void fetchShadow(psd_layer_effects_shadow_common *shadow) const;
-private Q_SLOTS:
- void slotDialAngleChanged(int value);
- void slotIntAngleChanged(int value);
-
- void slotGlobalLightToggled();
-
Q_SIGNALS:
void configChanged();
void globalAngleChanged(int value);
private:
Ui::WdgDropShadow ui;
Mode m_mode;
};
class GradientOverlay : public QWidget {
Q_OBJECT
public:
GradientOverlay(KisCanvasResourceProvider *resourceProvider, QWidget *parent);
void setGradientOverlay(const psd_layer_effects_gradient_overlay *gradient);
void fetchGradientOverlay(psd_layer_effects_gradient_overlay *gradient) const;
-private Q_SLOTS:
- void slotDialAngleChanged(int value);
- void slotIntAngleChanged(int value);
-
Q_SIGNALS:
void configChanged();
private:
Ui::WdgGradientOverlay ui;
KisCanvasResourceProvider *m_resourceProvider;
};
class InnerGlow : public QWidget {
Q_OBJECT
public:
enum Mode {
InnerGlowMode = 0,
OuterGlowMode
};
public:
InnerGlow(Mode mode, KisCanvasResourceProvider *resourceProvider, QWidget *parent);
void setConfig(const psd_layer_effects_glow_common *innerGlow);
void fetchConfig(psd_layer_effects_glow_common *innerGlow) const;
Q_SIGNALS:
void configChanged();
private:
Ui::WdgInnerGlow ui;
Mode m_mode;
KisCanvasResourceProvider *m_resourceProvider;
};
class PatternOverlay : public QWidget {
Q_OBJECT
public:
PatternOverlay(QWidget *parent);
void setPatternOverlay(const psd_layer_effects_pattern_overlay *pattern);
void fetchPatternOverlay(psd_layer_effects_pattern_overlay *pattern) const;
Q_SIGNALS:
void configChanged();
private:
Ui::WdgPatternOverlay ui;
};
class Satin : public QWidget {
Q_OBJECT
public:
Satin(QWidget *parent);
void setSatin(const psd_layer_effects_satin *satin);
void fetchSatin(psd_layer_effects_satin *satin) const;
-private Q_SLOTS:
- void slotDialAngleChanged(int value);
- void slotIntAngleChanged(int value);
-
Q_SIGNALS:
void configChanged();
private:
Ui::WdgSatin ui;
};
class Stroke : public QWidget {
Q_OBJECT
public:
Stroke(KisCanvasResourceProvider *resourceProvider, QWidget *parent);
void setStroke(const psd_layer_effects_stroke *stroke);
void fetchStroke(psd_layer_effects_stroke *stroke) const;
-private Q_SLOTS:
- void slotDialAngleChanged(int value);
- void slotIntAngleChanged(int value);
-
Q_SIGNALS:
void configChanged();
private:
Ui::WdgStroke ui;
KisCanvasResourceProvider *m_resourceProvider;
};
class StylesSelector : public QWidget {
Q_OBJECT
public:
StylesSelector(QWidget *parent);
void notifyExternalStyleChanged(const QString &name, const QUuid &uuid);
void addNewStyle(KisPSDLayerStyleSP style);
void loadCollection(const QString &fileName);
private Q_SLOTS:
void loadStyles(const QString &name);
void selectStyle(QListWidgetItem *previous, QListWidgetItem* current);
Q_SIGNALS:
void styleSelected(KisPSDLayerStyleSP style);
private:
void refillCollections();
private:
Ui::WdgStylesSelector ui;
};
class KisDlgLayerStyle : public KoDialog
{
Q_OBJECT
public:
explicit KisDlgLayerStyle(KisPSDLayerStyleSP layerStyle, KisCanvasResourceProvider *resourceProvider, QWidget *parent = 0);
~KisDlgLayerStyle() override;
KisPSDLayerStyleSP style() const;
Q_SIGNALS:
void configChanged();
public Q_SLOTS:
void slotMasterFxSwitchChanged(bool value);
void syncGlobalAngle(int angle);
void notifyGuiConfigChanged();
void notifyPredefinedStyleSelected(KisPSDLayerStyleSP style);
void changePage(QListWidgetItem *, QListWidgetItem*);
void slotNotifyOnAccept();
void slotNotifyOnReject();
// Sets all the widgets to the contents of the given style
void setStyle(KisPSDLayerStyleSP style);
void slotLoadStyle();
void slotSaveStyle();
void slotNewStyle();
private:
KisPSDLayerStyleSP m_layerStyle;
KisPSDLayerStyleSP m_initialLayerStyle;
Ui::WdgStylesDialog wdgLayerStyles;
BevelAndEmboss *m_bevelAndEmboss;
BlendingOptions *m_blendingOptions;
ColorOverlay *m_colorOverlay;
Contour *m_contour;
DropShadow *m_dropShadow;
GradientOverlay *m_gradientOverlay;
InnerGlow *m_innerGlow;
DropShadow *m_innerShadow;
InnerGlow *m_outerGlow;
PatternOverlay * m_patternOverlay;
Satin *m_satin;
Stroke *m_stroke;
StylesSelector *m_stylesSelector;
Texture *m_texture;
KisSignalCompressor *m_configChangedCompressor;
bool m_isSwitchingPredefinedStyle;
/**
* Used for debugging purposes only to track if m_layerStyle is in
* sync with what is stored in the GUI
*/
mutable bool m_sanityLayerStyleDirty;
};
#endif // KIS_DLG_LAYER_STYLE_H
diff --git a/libs/ui/forms/wdgnewimage.ui b/libs/ui/forms/wdgnewimage.ui
index 4aca85cf9b..8ae7a727e9 100644
--- a/libs/ui/forms/wdgnewimage.ui
+++ b/libs/ui/forms/wdgnewimage.ui
@@ -1,663 +1,685 @@
WdgNewImage
0
0
600
- 462
+ 491
0
0
600
0
16777215
16777215
New Image
-
0
0
- 0
+ 1
0
0
Dimensions
-
0
0
Color
-
-
-
0
140
16777215
16777215
Image Size
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
false
false
-
-
P&redefined:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
cmbPredefined
-
0
0
-
Save As:
-
0
0
-
Save the current dimensions
&Save
-
-
-
Landscape
...
true
true
true
-
2
1.000000000000000
100000000.000000000000000
-
&Height:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
doubleHeight
-
0
1.000000000000000
9999.000000000000000
-
Resolution:
-
1.000000000000000
100000000.000000000000000
-
-
-
pixels-per-inch
ppi
-
W&idth:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
doubleWidth
-
Portrait
...
true
true
true
true
-
-
Qt::Horizontal
QSizePolicy::Expanding
191
61
-
Clipboard
-
75
75
250
250
QFrame::StyledPanel
TextLabel
-
Qt::Vertical
20
40
0
0
Content
-
Layers:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- Ima&ge Background Opacity:
+ Background Opacity:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
sliderOpacity
-
0
0
+
+ Number of layers that the image will start with, including optional background layer.
+
1
200
2
-
- Image Bac&kground Color:
+ Bac&kground Color:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
cmbColor
-
Background:
Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
-
&Description:
Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
txtDescription
-
0
0
16777215
100
-
-
-
+
+
+ Use background color and opacity to create a background raster layer.
+
- As fi&rst layer
+ As &raster layer
-
+
+ Use background color and opacity as the base canvas color. This can be reconfigured in `Image > Properties.`
+
As can&vas color
+ -
+
+
+ Use background color and opacity to create a background fill layer. The color for this layer can be reconfigured in the layer's properties.
+
+
+ As &fill layer
+
+
+
-
0
0
50
0
- Reset the image background color in the Image Properties dialog
+
-
QFrame::NoFrame
QFrame::Plain
0
0
0
0
-
-
Qt::Vertical
20
40
-
&Name:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
txtName
-
+
+
+
untitled-1
label_4
lblBackgroundStyle
txtDescription
lblDescription
intNumLayers
opacityPanel
lblColor
cmbColor
lblOpacity
lblName
txtName
-
Qt::Vertical
QSizePolicy::Expanding
10
10
-
This document...
true
-
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
KisIntParseSpinBox
QSpinBox
KisColorButton
QPushButton
KisDoubleSliderSpinBox
QWidget
1
KisColorSpaceSelector
QWidget
widgets/kis_color_space_selector.h
1
KisDoubleParseSpinBox
QDoubleSpinBox
kis_double_parse_spin_box.h
tabWidget
cmbPredefined
txtPredefinedName
bnSaveAsPredefined
doubleWidth
doubleHeight
doubleResolution
cmbWidthUnit
cmbHeightUnit
bnLandscape
bnPortrait
intNumLayers
cmbColor
- radioBackgroundAsLayer
+ radioBackgroundAsRaster
radioBackgroundAsProjection
txtDescription
diff --git a/libs/ui/input/kis_input_manager.cpp b/libs/ui/input/kis_input_manager.cpp
index 1aa0e0bc29..9b255abecd 100644
--- a/libs/ui/input/kis_input_manager.cpp
+++ b/libs/ui/input/kis_input_manager.cpp
@@ -1,688 +1,693 @@
/* This file is part of the KDE project
*
* Copyright (C) 2012 Arjen Hiemstra
* Copyright (C) 2015 Michael Abrahams
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_input_manager.h"
#include
#include
#include
#include
#include
#include
#include
#include "kis_tool_proxy.h"
#include
#include
#include
#include
#include
#include
#include "kis_abstract_input_action.h"
#include "kis_tool_invocation_action.h"
#include "kis_pan_action.h"
#include "kis_alternate_invocation_action.h"
#include "kis_rotate_canvas_action.h"
#include "kis_zoom_action.h"
#include "kis_show_palette_action.h"
#include "kis_change_primary_setting_action.h"
#include "kis_shortcut_matcher.h"
#include "kis_stroke_shortcut.h"
#include "kis_single_action_shortcut.h"
#include "kis_touch_shortcut.h"
#include "kis_input_profile.h"
#include "kis_input_profile_manager.h"
#include "kis_shortcut_configuration.h"
#include
#include
#include "kis_extended_modifiers_mapper.h"
#include "kis_input_manager_p.h"
template
uint qHash(QPointer value) {
return reinterpret_cast(value.data());
}
KisInputManager::KisInputManager(QObject *parent)
: QObject(parent), d(new Private(this))
{
d->setupActions();
connect(KoToolManager::instance(), SIGNAL(aboutToChangeTool(KoCanvasController*)), SLOT(slotAboutToChangeTool()));
connect(KoToolManager::instance(), SIGNAL(changedTool(KoCanvasController*,int)), SLOT(slotToolChanged()));
connect(&d->moveEventCompressor, SIGNAL(timeout()), SLOT(slotCompressedMoveEvent()));
QApplication::instance()->
installEventFilter(new Private::ProximityNotifier(d, this));
}
KisInputManager::~KisInputManager()
{
delete d;
}
void KisInputManager::addTrackedCanvas(KisCanvas2 *canvas)
{
d->canvasSwitcher.addCanvas(canvas);
}
void KisInputManager::removeTrackedCanvas(KisCanvas2 *canvas)
{
d->canvasSwitcher.removeCanvas(canvas);
}
void KisInputManager::toggleTabletLogger()
{
KisTabletDebugger::instance()->toggleDebugging();
}
void KisInputManager::attachPriorityEventFilter(QObject *filter, int priority)
{
Private::PriorityList::iterator begin = d->priorityEventFilter.begin();
Private::PriorityList::iterator it = begin;
Private::PriorityList::iterator end = d->priorityEventFilter.end();
it = std::find_if(begin, end,
[filter] (const Private::PriorityPair &a) { return a.second == filter; });
if (it != end) return;
it = std::find_if(begin, end,
[priority] (const Private::PriorityPair &a) { return a.first > priority; });
d->priorityEventFilter.insert(it, qMakePair(priority, filter));
d->priorityEventFilterSeqNo++;
}
void KisInputManager::detachPriorityEventFilter(QObject *filter)
{
Private::PriorityList::iterator it = d->priorityEventFilter.begin();
Private::PriorityList::iterator end = d->priorityEventFilter.end();
it = std::find_if(it, end,
[filter] (const Private::PriorityPair &a) { return a.second == filter; });
if (it != end) {
d->priorityEventFilter.erase(it);
}
}
void KisInputManager::setupAsEventFilter(QObject *receiver)
{
if (d->eventsReceiver) {
d->eventsReceiver->removeEventFilter(this);
}
d->eventsReceiver = receiver;
if (d->eventsReceiver) {
d->eventsReceiver->installEventFilter(this);
}
}
void KisInputManager::stopIgnoringEvents()
{
d->allowMouseEvents();
}
#if defined (__clang__)
#pragma GCC diagnostic ignored "-Wswitch"
#endif
bool KisInputManager::eventFilter(QObject* object, QEvent* event)
{
if (object != d->eventsReceiver) return false;
if (d->eventEater.eventFilter(object, event)) return false;
if (!d->matcher.hasRunningShortcut()) {
int savedPriorityEventFilterSeqNo = d->priorityEventFilterSeqNo;
for (auto it = d->priorityEventFilter.begin(); it != d->priorityEventFilter.end(); /*noop*/) {
const QPointer &filter = it->second;
if (filter.isNull()) {
it = d->priorityEventFilter.erase(it);
d->priorityEventFilterSeqNo++;
savedPriorityEventFilterSeqNo++;
continue;
}
if (filter->eventFilter(object, event)) return true;
/**
* If the filter removed itself from the filters list or
* added something there, just exit the loop
*/
if (d->priorityEventFilterSeqNo != savedPriorityEventFilterSeqNo) {
return true;
}
++it;
}
// KoToolProxy needs to pre-process some events to ensure the
// global shortcuts (not the input manager's ones) are not
// executed, in particular, this line will accept events when the
// tool is in text editing, preventing shortcut triggering
if (d->toolProxy) {
d->toolProxy->processEvent(event);
}
}
// Continue with the actual switch statement...
return eventFilterImpl(event);
}
template
bool KisInputManager::compressMoveEventCommon(Event *event)
{
/**
* We construct a copy of this event object, so we must ensure it
* has a correct type.
*/
static_assert(std::is_same::value ||
std::is_same::value,
"event should be a mouse or a tablet event");
bool retval = false;
/**
* Compress the events if the tool doesn't need high resolution input
*/
+// See https://bugreports.qt.io/browse/QTBUG-72488
+#if QT_VERSION < QT_VERSION_CHECK(5, 11, 3)
if ((event->type() == QEvent::MouseMove ||
event->type() == QEvent::TabletMove) &&
(!d->matcher.supportsHiResInputEvents() ||
d->testingCompressBrushEvents)) {
d->compressedMoveEvent.reset(new Event(*event));
d->moveEventCompressor.start();
/**
* On Linux Qt eats the rest of unneeded events if we
* ignore the first of the chunk of tablet events. So
* generally we should never activate this feature. Only
* for testing purposes!
*/
if (d->testingAcceptCompressedTabletEvents) {
event->setAccepted(true);
}
retval = true;
} else {
+#endif
slotCompressedMoveEvent();
retval = d->handleCompressedTabletEvent(event);
+#if QT_VERSION < QT_VERSION_CHECK(5, 11, 3)
}
+#endif
return retval;
}
bool KisInputManager::eventFilterImpl(QEvent * event)
{
bool retval = false;
if (event->type() != QEvent::Wheel) {
d->accumulatedScrollDelta = 0;
}
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonDblClick: {
d->debugEvent(event);
//Block mouse press events on Genius tablets
if (d->tabletActive) break;
if (d->ignoringQtCursorEvents()) break;
if (d->touchHasBlockedPressEvents) break;
QMouseEvent *mouseEvent = static_cast(event);
if (d->tryHidePopupPalette()) {
retval = true;
} else {
//Make sure the input actions know we are active.
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.buttonPressed(mouseEvent->button(), mouseEvent);
}
//Reset signal compressor to prevent processing events before press late
d->resetCompressor();
event->setAccepted(retval);
break;
}
case QEvent::MouseButtonRelease: {
d->debugEvent(event);
if (d->ignoringQtCursorEvents()) break;
if (d->touchHasBlockedPressEvents) break;
QMouseEvent *mouseEvent = static_cast(event);
retval = d->matcher.buttonReleased(mouseEvent->button(), mouseEvent);
event->setAccepted(retval);
break;
}
case QEvent::ShortcutOverride: {
d->debugEvent(event);
QKeyEvent *keyEvent = static_cast(event);
Qt::Key key = KisExtendedModifiersMapper::workaroundShiftAltMetaHell(keyEvent);
if (!keyEvent->isAutoRepeat()) {
retval = d->matcher.keyPressed(key);
} else {
retval = d->matcher.autoRepeatedKeyPressed(key);
}
/**
* Workaround for temporary switching of tools by
* KoCanvasControllerWidget. We don't need this switch because
* we handle it ourselves.
*/
retval |= !d->forwardAllEventsToTool &&
(keyEvent->key() == Qt::Key_Space ||
keyEvent->key() == Qt::Key_Escape);
break;
}
case QEvent::KeyRelease: {
d->debugEvent(event);
QKeyEvent *keyEvent = static_cast(event);
if (!keyEvent->isAutoRepeat()) {
Qt::Key key = KisExtendedModifiersMapper::workaroundShiftAltMetaHell(keyEvent);
retval = d->matcher.keyReleased(key);
}
break;
}
case QEvent::MouseMove: {
d->debugEvent(event);
if (d->ignoringQtCursorEvents()) break;
QMouseEvent *mouseEvent = static_cast(event);
retval = compressMoveEventCommon(mouseEvent);
break;
}
case QEvent::Wheel: {
d->debugEvent(event);
QWheelEvent *wheelEvent = static_cast(event);
#ifdef Q_OS_OSX
// Some QT wheel events are actually touch pad pan events. From the QT docs:
// "Wheel events are generated for both mouse wheels and trackpad scroll gestures."
// We differentiate between touchpad events and real mouse wheels by inspecting the
// event source.
if (wheelEvent->source() == Qt::MouseEventSource::MouseEventSynthesizedBySystem) {
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.wheelEvent(KisSingleActionShortcut::WheelTrackpad, wheelEvent);
break;
}
#endif
d->accumulatedScrollDelta += wheelEvent->delta();
KisSingleActionShortcut::WheelAction action;
/**
* Ignore delta 0 events on OSX, since they are triggered by tablet
* proximity when using Wacom devices.
*/
#ifdef Q_OS_OSX
if(wheelEvent->delta() == 0) {
retval = true;
break;
}
#endif
if (wheelEvent->orientation() == Qt::Horizontal) {
if(wheelEvent->delta() < 0) {
action = KisSingleActionShortcut::WheelRight;
}
else {
action = KisSingleActionShortcut::WheelLeft;
}
}
else {
if(wheelEvent->delta() > 0) {
action = KisSingleActionShortcut::WheelUp;
}
else {
action = KisSingleActionShortcut::WheelDown;
}
}
if (qAbs(d->accumulatedScrollDelta) >= QWheelEvent::DefaultDeltasPerStep) {
//Make sure the input actions know we are active.
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.wheelEvent(action, wheelEvent);
d->accumulatedScrollDelta = 0;
}
else {
retval = true;
}
break;
}
case QEvent::Enter:
d->debugEvent(event);
//Make sure the input actions know we are active.
KisAbstractInputAction::setInputManager(this);
if (!d->containsPointer) {
d->containsPointer = true;
d->allowMouseEvents();
d->touchHasBlockedPressEvents = false;
}
d->matcher.enterEvent();
break;
case QEvent::Leave:
d->debugEvent(event);
d->containsPointer = false;
/**
* We won't get a TabletProximityLeave event when the tablet
* is hovering above some other widget, so restore cursor
* events processing right now.
*/
d->allowMouseEvents();
d->touchHasBlockedPressEvents = false;
d->matcher.leaveEvent();
break;
case QEvent::FocusIn:
d->debugEvent(event);
KisAbstractInputAction::setInputManager(this);
//Clear all state so we don't have half-matched shortcuts dangling around.
d->matcher.reinitialize();
{ // Emulate pressing of the key that are already pressed
KisExtendedModifiersMapper mapper;
Qt::KeyboardModifiers modifiers = mapper.queryStandardModifiers();
Q_FOREACH (Qt::Key key, mapper.queryExtendedModifiers()) {
QKeyEvent kevent(QEvent::ShortcutOverride, key, modifiers);
eventFilterImpl(&kevent);
}
}
d->allowMouseEvents();
break;
case QEvent::FocusOut: {
d->debugEvent(event);
KisAbstractInputAction::setInputManager(this);
QPointF currentLocalPos =
canvas()->canvasWidget()->mapFromGlobal(QCursor::pos());
d->matcher.lostFocusEvent(currentLocalPos);
break;
}
case QEvent::TabletPress: {
d->debugEvent(event);
QTabletEvent *tabletEvent = static_cast(event);
if (d->tryHidePopupPalette()) {
retval = true;
} else {
//Make sure the input actions know we are active.
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.buttonPressed(tabletEvent->button(), tabletEvent);
if (!d->containsPointer) {
d->containsPointer = true;
d->touchHasBlockedPressEvents = false;
}
}
event->setAccepted(true);
retval = true;
d->blockMouseEvents();
//Reset signal compressor to prevent processing events before press late
d->resetCompressor();
d->eatOneMousePress();
break;
}
case QEvent::TabletMove: {
d->debugEvent(event);
QTabletEvent *tabletEvent = static_cast(event);
retval = compressMoveEventCommon(tabletEvent);
if (d->tabletLatencyTracker) {
d->tabletLatencyTracker->push(tabletEvent->timestamp());
}
/**
* The flow of tablet events means the tablet is in the
* proximity area, so activate it even when the
* TabletEnterProximity event was missed (may happen when
* changing focus of the window with tablet in the proximity
* area)
*/
d->blockMouseEvents();
break;
}
case QEvent::TabletRelease: {
#ifdef Q_OS_MAC
d->allowMouseEvents();
#endif
d->debugEvent(event);
QTabletEvent *tabletEvent = static_cast(event);
retval = d->matcher.buttonReleased(tabletEvent->button(), tabletEvent);
retval = true;
event->setAccepted(true);
break;
}
case QEvent::TouchBegin:
{
if (startTouch(retval)) {
QTouchEvent *tevent = static_cast(event);
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.touchBeginEvent(tevent);
event->accept();
}
break;
}
case QEvent::TouchUpdate:
{
QTouchEvent *tevent = static_cast(event);
#ifdef Q_OS_MAC
int count = 0;
Q_FOREACH (const QTouchEvent::TouchPoint &point, tevent->touchPoints()) {
if (point.state() != Qt::TouchPointReleased) {
count++;
}
}
if (count < 2 && tevent->touchPoints().length() > count) {
d->touchHasBlockedPressEvents = false;
retval = d->matcher.touchEndEvent(tevent);
} else {
#endif
d->touchHasBlockedPressEvents = KisConfig(true).disableTouchOnCanvas();
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.touchUpdateEvent(tevent);
#ifdef Q_OS_OSX
}
#endif
event->accept();
break;
}
case QEvent::TouchEnd:
{
endTouch();
QTouchEvent *tevent = static_cast(event);
retval = d->matcher.touchEndEvent(tevent);
event->accept();
break;
}
case QEvent::NativeGesture:
{
QNativeGestureEvent *gevent = static_cast(event);
switch (gevent->gestureType()) {
case Qt::BeginNativeGesture:
{
if (startTouch(retval)) {
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.nativeGestureBeginEvent(gevent);
event->accept();
}
break;
}
case Qt::EndNativeGesture:
{
endTouch();
retval = d->matcher.nativeGestureEndEvent(gevent);
event->accept();
break;
}
default:
{
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.nativeGestureEvent(gevent);
event->accept();
break;
}
}
break;
}
default:
break;
}
return !retval ? d->processUnhandledEvent(event) : true;
}
bool KisInputManager::startTouch(bool &retval)
{
d->touchHasBlockedPressEvents = KisConfig(true).disableTouchOnCanvas();
// Touch rejection: if touch is disabled on canvas, no need to block mouse press events
if (KisConfig(true).disableTouchOnCanvas()) {
d->eatOneMousePress();
}
if (d->tryHidePopupPalette()) {
retval = true;
return false;
} else {
return true;
}
}
void KisInputManager::endTouch()
{
d->touchHasBlockedPressEvents = false;
}
void KisInputManager::slotCompressedMoveEvent()
{
if (d->compressedMoveEvent) {
// d->touchHasBlockedPressEvents = false;
(void) d->handleCompressedTabletEvent(d->compressedMoveEvent.data());
d->compressedMoveEvent.reset();
//dbgInput << "Compressed move event received.";
} else {
//dbgInput << "Unexpected empty move event";
}
}
KisCanvas2* KisInputManager::canvas() const
{
return d->canvas;
}
QPointer KisInputManager::toolProxy() const
{
return d->toolProxy;
}
void KisInputManager::slotAboutToChangeTool()
{
QPointF currentLocalPos;
if (canvas() && canvas()->canvasWidget()) {
currentLocalPos = canvas()->canvasWidget()->mapFromGlobal(QCursor::pos());
}
d->matcher.lostFocusEvent(currentLocalPos);
}
void KisInputManager::slotToolChanged()
{
if (!d->canvas) return;
KoToolManager *toolManager = KoToolManager::instance();
KoToolBase *tool = toolManager->toolById(canvas(), toolManager->activeToolId());
if (tool) {
d->setMaskSyntheticEvents(tool->maskSyntheticEvents());
if (tool->isInTextMode()) {
d->forwardAllEventsToTool = true;
d->matcher.suppressAllActions(true);
} else {
d->forwardAllEventsToTool = false;
d->matcher.suppressAllActions(false);
}
}
}
void KisInputManager::profileChanged()
{
d->matcher.clearShortcuts();
KisInputProfile *profile = KisInputProfileManager::instance()->currentProfile();
if (profile) {
const QList shortcuts = profile->allShortcuts();
for (KisShortcutConfiguration * const shortcut : shortcuts) {
dbgUI << "Adding shortcut" << shortcut->keys() << "for action" << shortcut->action()->name();
switch(shortcut->type()) {
case KisShortcutConfiguration::KeyCombinationType:
d->addKeyShortcut(shortcut->action(), shortcut->mode(), shortcut->keys());
break;
case KisShortcutConfiguration::MouseButtonType:
d->addStrokeShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->buttons());
break;
case KisShortcutConfiguration::MouseWheelType:
d->addWheelShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->wheel());
break;
case KisShortcutConfiguration::GestureType:
if (!d->addNativeGestureShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture())) {
d->addTouchShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture());
}
break;
default:
break;
}
}
}
else {
dbgInput << "No Input Profile Found: canvas interaction will be impossible";
}
}
diff --git a/libs/ui/kis_config.cc b/libs/ui/kis_config.cc
index 0eba622a79..9551c4678e 100644
--- a/libs/ui/kis_config.cc
+++ b/libs/ui/kis_config.cc
@@ -1,2035 +1,2035 @@
/*
* Copyright (c) 2002 Patrick Julien
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_config.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_canvas_resource_provider.h"
#include "kis_config_notifier.h"
#include "kis_snap_config.h"
#include
#include
KisConfig::KisConfig(bool readOnly)
: m_cfg( KSharedConfig::openConfig()->group(""))
, m_readOnly(readOnly)
{
if (!readOnly) {
KIS_SAFE_ASSERT_RECOVER_RETURN(qApp->thread() == QThread::currentThread());
}
}
KisConfig::~KisConfig()
{
if (m_readOnly) return;
if (qApp->thread() != QThread::currentThread()) {
dbgKrita << "WARNING: KisConfig: requested config synchronization from nonGUI thread! Called from:" << kisBacktrace();
return;
}
m_cfg.sync();
}
bool KisConfig::disableTouchOnCanvas(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("disableTouchOnCanvas", false));
}
void KisConfig::setDisableTouchOnCanvas(bool value) const
{
m_cfg.writeEntry("disableTouchOnCanvas", value);
}
bool KisConfig::useProjections(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("useProjections", true));
}
void KisConfig::setUseProjections(bool useProj) const
{
m_cfg.writeEntry("useProjections", useProj);
}
bool KisConfig::undoEnabled(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("undoEnabled", true));
}
void KisConfig::setUndoEnabled(bool undo) const
{
m_cfg.writeEntry("undoEnabled", undo);
}
int KisConfig::undoStackLimit(bool defaultValue) const
{
return (defaultValue ? 30 : m_cfg.readEntry("undoStackLimit", 30));
}
void KisConfig::setUndoStackLimit(int limit) const
{
m_cfg.writeEntry("undoStackLimit", limit);
}
bool KisConfig::useCumulativeUndoRedo(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useCumulativeUndoRedo",false));
}
void KisConfig::setCumulativeUndoRedo(bool value)
{
m_cfg.writeEntry("useCumulativeUndoRedo", value);
}
qreal KisConfig::stackT1(bool defaultValue) const
{
return (defaultValue ? 5 : m_cfg.readEntry("stackT1",5));
}
void KisConfig::setStackT1(int T1)
{
m_cfg.writeEntry("stackT1", T1);
}
qreal KisConfig::stackT2(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("stackT2",1));
}
void KisConfig::setStackT2(int T2)
{
m_cfg.writeEntry("stackT2", T2);
}
int KisConfig::stackN(bool defaultValue) const
{
return (defaultValue ? 5 : m_cfg.readEntry("stackN",5));
}
void KisConfig::setStackN(int N)
{
m_cfg.writeEntry("stackN", N);
}
qint32 KisConfig::defImageWidth(bool defaultValue) const
{
return (defaultValue ? 1600 : m_cfg.readEntry("imageWidthDef", 1600));
}
qint32 KisConfig::defImageHeight(bool defaultValue) const
{
return (defaultValue ? 1200 : m_cfg.readEntry("imageHeightDef", 1200));
}
qreal KisConfig::defImageResolution(bool defaultValue) const
{
return (defaultValue ? 100.0 : m_cfg.readEntry("imageResolutionDef", 100.0)) / 72.0;
}
QString KisConfig::defColorModel(bool defaultValue) const
{
return (defaultValue ? KoColorSpaceRegistry::instance()->rgb8()->colorModelId().id()
: m_cfg.readEntry("colorModelDef", KoColorSpaceRegistry::instance()->rgb8()->colorModelId().id()));
}
void KisConfig::defColorModel(const QString & model) const
{
m_cfg.writeEntry("colorModelDef", model);
}
QString KisConfig::defaultColorDepth(bool defaultValue) const
{
return (defaultValue ? KoColorSpaceRegistry::instance()->rgb8()->colorDepthId().id()
: m_cfg.readEntry("colorDepthDef", KoColorSpaceRegistry::instance()->rgb8()->colorDepthId().id()));
}
void KisConfig::setDefaultColorDepth(const QString & depth) const
{
m_cfg.writeEntry("colorDepthDef", depth);
}
QString KisConfig::defColorProfile(bool defaultValue) const
{
return (defaultValue ? KoColorSpaceRegistry::instance()->rgb8()->profile()->name() :
m_cfg.readEntry("colorProfileDef",
KoColorSpaceRegistry::instance()->rgb8()->profile()->name()));
}
void KisConfig::defColorProfile(const QString & profile) const
{
m_cfg.writeEntry("colorProfileDef", profile);
}
void KisConfig::defImageWidth(qint32 width) const
{
m_cfg.writeEntry("imageWidthDef", width);
}
void KisConfig::defImageHeight(qint32 height) const
{
m_cfg.writeEntry("imageHeightDef", height);
}
void KisConfig::defImageResolution(qreal res) const
{
m_cfg.writeEntry("imageResolutionDef", res*72.0);
}
int KisConfig::preferredVectorImportResolutionPPI(bool defaultValue) const
{
return defaultValue ? 100.0 : m_cfg.readEntry("preferredVectorImportResolution", 100.0);
}
void KisConfig::setPreferredVectorImportResolutionPPI(int value) const
{
m_cfg.writeEntry("preferredVectorImportResolution", value);
}
void cleanOldCursorStyleKeys(KConfigGroup &cfg)
{
if (cfg.hasKey("newCursorStyle") &&
cfg.hasKey("newOutlineStyle")) {
cfg.deleteEntry("cursorStyleDef");
}
}
CursorStyle KisConfig::newCursorStyle(bool defaultValue) const
{
if (defaultValue) {
return CURSOR_STYLE_NO_CURSOR;
}
int style = m_cfg.readEntry("newCursorStyle", int(-1));
if (style < 0) {
// old style format
style = m_cfg.readEntry("cursorStyleDef", int(OLD_CURSOR_STYLE_OUTLINE));
switch (style) {
case OLD_CURSOR_STYLE_TOOLICON:
style = CURSOR_STYLE_TOOLICON;
break;
case OLD_CURSOR_STYLE_CROSSHAIR:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_CROSS:
style = CURSOR_STYLE_CROSSHAIR;
break;
case OLD_CURSOR_STYLE_POINTER:
style = CURSOR_STYLE_POINTER;
break;
case OLD_CURSOR_STYLE_OUTLINE:
case OLD_CURSOR_STYLE_NO_CURSOR:
style = CURSOR_STYLE_NO_CURSOR;
break;
case OLD_CURSOR_STYLE_SMALL_ROUND:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_DOT:
style = CURSOR_STYLE_SMALL_ROUND;
break;
case OLD_CURSOR_STYLE_TRIANGLE_RIGHTHANDED:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_RIGHTHANDED:
style = CURSOR_STYLE_TRIANGLE_RIGHTHANDED;
break;
case OLD_CURSOR_STYLE_TRIANGLE_LEFTHANDED:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_LEFTHANDED:
style = CURSOR_STYLE_TRIANGLE_LEFTHANDED;
break;
default:
style = -1;
}
}
cleanOldCursorStyleKeys(m_cfg);
// compatibility with future versions
if (style < 0 || style >= N_CURSOR_STYLE_SIZE) {
style = CURSOR_STYLE_NO_CURSOR;
}
return (CursorStyle) style;
}
void KisConfig::setNewCursorStyle(CursorStyle style)
{
m_cfg.writeEntry("newCursorStyle", (int)style);
}
QColor KisConfig::getCursorMainColor(bool defaultValue) const
{
QColor col;
col.setRgbF(0.501961, 1.0, 0.501961);
return (defaultValue ? col : m_cfg.readEntry("cursorMaincColor", col));
}
void KisConfig::setCursorMainColor(const QColor &v) const
{
m_cfg.writeEntry("cursorMaincColor", v);
}
OutlineStyle KisConfig::newOutlineStyle(bool defaultValue) const
{
if (defaultValue) {
return OUTLINE_FULL;
}
int style = m_cfg.readEntry("newOutlineStyle", int(-1));
if (style < 0) {
// old style format
style = m_cfg.readEntry("cursorStyleDef", int(OLD_CURSOR_STYLE_OUTLINE));
switch (style) {
case OLD_CURSOR_STYLE_TOOLICON:
case OLD_CURSOR_STYLE_CROSSHAIR:
case OLD_CURSOR_STYLE_POINTER:
case OLD_CURSOR_STYLE_NO_CURSOR:
case OLD_CURSOR_STYLE_SMALL_ROUND:
case OLD_CURSOR_STYLE_TRIANGLE_RIGHTHANDED:
case OLD_CURSOR_STYLE_TRIANGLE_LEFTHANDED:
style = OUTLINE_NONE;
break;
case OLD_CURSOR_STYLE_OUTLINE:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_DOT:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_CROSS:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_RIGHTHANDED:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_LEFTHANDED:
style = OUTLINE_FULL;
break;
default:
style = -1;
}
}
cleanOldCursorStyleKeys(m_cfg);
// compatibility with future versions
if (style < 0 || style >= N_OUTLINE_STYLE_SIZE) {
style = OUTLINE_FULL;
}
return (OutlineStyle) style;
}
void KisConfig::setNewOutlineStyle(OutlineStyle style)
{
m_cfg.writeEntry("newOutlineStyle", (int)style);
}
QRect KisConfig::colorPreviewRect() const
{
return m_cfg.readEntry("colorPreviewRect", QVariant(QRect(32, 32, 48, 48))).toRect();
}
void KisConfig::setColorPreviewRect(const QRect &rect)
{
m_cfg.writeEntry("colorPreviewRect", QVariant(rect));
}
bool KisConfig::useDirtyPresets(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useDirtyPresets",false));
}
void KisConfig::setUseDirtyPresets(bool value)
{
m_cfg.writeEntry("useDirtyPresets",value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::useEraserBrushSize(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useEraserBrushSize",false));
}
void KisConfig::setUseEraserBrushSize(bool value)
{
m_cfg.writeEntry("useEraserBrushSize",value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::useEraserBrushOpacity(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useEraserBrushOpacity",false));
}
void KisConfig::setUseEraserBrushOpacity(bool value)
{
m_cfg.writeEntry("useEraserBrushOpacity",value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
QColor KisConfig::getMDIBackgroundColor(bool defaultValue) const
{
QColor col(77, 77, 77);
return (defaultValue ? col : m_cfg.readEntry("mdiBackgroundColor", col));
}
void KisConfig::setMDIBackgroundColor(const QColor &v) const
{
m_cfg.writeEntry("mdiBackgroundColor", v);
}
QString KisConfig::getMDIBackgroundImage(bool defaultValue) const
{
return (defaultValue ? "" : m_cfg.readEntry("mdiBackgroundImage", ""));
}
void KisConfig::setMDIBackgroundImage(const QString &filename) const
{
m_cfg.writeEntry("mdiBackgroundImage", filename);
}
QString KisConfig::monitorProfile(int screen) const
{
// Note: keep this in sync with the default profile for the RGB colorspaces!
QString profile = m_cfg.readEntry("monitorProfile" + QString(screen == 0 ? "": QString("_%1").arg(screen)), "sRGB-elle-V2-srgbtrc.icc");
//dbgKrita << "KisConfig::monitorProfile()" << profile;
return profile;
}
QString KisConfig::monitorForScreen(int screen, const QString &defaultMonitor, bool defaultValue) const
{
return (defaultValue ? defaultMonitor
: m_cfg.readEntry(QString("monitor_for_screen_%1").arg(screen), defaultMonitor));
}
void KisConfig::setMonitorForScreen(int screen, const QString& monitor)
{
m_cfg.writeEntry(QString("monitor_for_screen_%1").arg(screen), monitor);
}
void KisConfig::setMonitorProfile(int screen, const QString & monitorProfile, bool override) const
{
m_cfg.writeEntry("monitorProfile/OverrideX11", override);
m_cfg.writeEntry("monitorProfile" + QString(screen == 0 ? "": QString("_%1").arg(screen)), monitorProfile);
}
const KoColorProfile *KisConfig::getScreenProfile(int screen)
{
if (screen < 0) return 0;
KisConfig cfg(true);
QString monitorId;
if (KisColorManager::instance()->devices().size() > screen) {
monitorId = cfg.monitorForScreen(screen, KisColorManager::instance()->devices()[screen]);
}
//dbgKrita << "getScreenProfile(). Screen" << screen << "monitor id" << monitorId;
if (monitorId.isEmpty()) {
return 0;
}
QByteArray bytes = KisColorManager::instance()->displayProfile(monitorId);
//dbgKrita << "\tgetScreenProfile()" << bytes.size();
if (bytes.length() > 0) {
const KoColorProfile *profile = KoColorSpaceRegistry::instance()->createColorProfile(RGBAColorModelID.id(), Integer8BitsColorDepthID.id(), bytes);
//dbgKrita << "\tKisConfig::getScreenProfile for screen" << screen << profile->name();
return profile;
}
else {
//dbgKrita << "\tCould not get a system monitor profile";
return 0;
}
}
const KoColorProfile *KisConfig::displayProfile(int screen) const
{
if (screen < 0) return 0;
// if the user plays with the settings, they can override the display profile, in which case
// we don't want the system setting.
bool override = useSystemMonitorProfile();
//dbgKrita << "KisConfig::displayProfile(). Override X11:" << override;
const KoColorProfile *profile = 0;
if (override) {
//dbgKrita << "\tGoing to get the screen profile";
profile = KisConfig::getScreenProfile(screen);
}
// if it fails. check the configuration
if (!profile || !profile->isSuitableForDisplay()) {
//dbgKrita << "\tGoing to get the monitor profile";
QString monitorProfileName = monitorProfile(screen);
//dbgKrita << "\t\tmonitorProfileName:" << monitorProfileName;
if (!monitorProfileName.isEmpty()) {
profile = KoColorSpaceRegistry::instance()->profileByName(monitorProfileName);
}
if (profile) {
//dbgKrita << "\t\tsuitable for display" << profile->isSuitableForDisplay();
}
else {
//dbgKrita << "\t\tstill no profile";
}
}
// if we still don't have a profile, or the profile isn't suitable for display,
// we need to get a last-resort profile. the built-in sRGB is a good choice then.
if (!profile || !profile->isSuitableForDisplay()) {
//dbgKrita << "\tnothing worked, going to get sRGB built-in";
profile = KoColorSpaceRegistry::instance()->profileByName("sRGB Built-in");
}
if (profile) {
//dbgKrita << "\tKisConfig::displayProfile for screen" << screen << "is" << profile->name();
}
else {
//dbgKrita << "\tCouldn't get a display profile at all";
}
return profile;
}
QString KisConfig::workingColorSpace(bool defaultValue) const
{
return (defaultValue ? "RGBA" : m_cfg.readEntry("workingColorSpace", "RGBA"));
}
void KisConfig::setWorkingColorSpace(const QString & workingColorSpace) const
{
m_cfg.writeEntry("workingColorSpace", workingColorSpace);
}
QString KisConfig::printerColorSpace(bool /*defaultValue*/) const
{
//TODO currently only rgb8 is supported
//return (defaultValue ? "RGBA" : m_cfg.readEntry("printerColorSpace", "RGBA"));
return QString("RGBA");
}
void KisConfig::setPrinterColorSpace(const QString & printerColorSpace) const
{
m_cfg.writeEntry("printerColorSpace", printerColorSpace);
}
QString KisConfig::printerProfile(bool defaultValue) const
{
return (defaultValue ? "" : m_cfg.readEntry("printerProfile", ""));
}
void KisConfig::setPrinterProfile(const QString & printerProfile) const
{
m_cfg.writeEntry("printerProfile", printerProfile);
}
bool KisConfig::useBlackPointCompensation(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("useBlackPointCompensation", true));
}
void KisConfig::setUseBlackPointCompensation(bool useBlackPointCompensation) const
{
m_cfg.writeEntry("useBlackPointCompensation", useBlackPointCompensation);
}
bool KisConfig::allowLCMSOptimization(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("allowLCMSOptimization", true));
}
void KisConfig::setAllowLCMSOptimization(bool allowLCMSOptimization)
{
m_cfg.writeEntry("allowLCMSOptimization", allowLCMSOptimization);
}
bool KisConfig::forcePaletteColors(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("colorsettings/forcepalettecolors", false));
}
void KisConfig::setForcePaletteColors(bool forcePaletteColors)
{
m_cfg.writeEntry("colorsettings/forcepalettecolors", forcePaletteColors);
}
bool KisConfig::showRulers(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showrulers", false));
}
void KisConfig::setShowRulers(bool rulers) const
{
m_cfg.writeEntry("showrulers", rulers);
}
bool KisConfig::forceShowSaveMessages(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("forceShowSaveMessages", false));
}
void KisConfig::setForceShowSaveMessages(bool value) const
{
m_cfg.writeEntry("forceShowSaveMessages", value);
}
bool KisConfig::forceShowAutosaveMessages(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("forceShowAutosaveMessages", false));
}
void KisConfig::setForceShowAutosaveMessages(bool value) const
{
m_cfg.writeEntry("forceShowAutosaveMessages", value);
}
bool KisConfig::rulersTrackMouse(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("rulersTrackMouse", true));
}
void KisConfig::setRulersTrackMouse(bool value) const
{
m_cfg.writeEntry("rulersTrackMouse", value);
}
qint32 KisConfig::pasteBehaviour(bool defaultValue) const
{
return (defaultValue ? 2 : m_cfg.readEntry("pasteBehaviour", 2));
}
void KisConfig::setPasteBehaviour(qint32 renderIntent) const
{
m_cfg.writeEntry("pasteBehaviour", renderIntent);
}
qint32 KisConfig::monitorRenderIntent(bool defaultValue) const
{
qint32 intent = m_cfg.readEntry("renderIntent", INTENT_PERCEPTUAL);
if (intent > 3) intent = 3;
if (intent < 0) intent = 0;
return (defaultValue ? INTENT_PERCEPTUAL : intent);
}
void KisConfig::setRenderIntent(qint32 renderIntent) const
{
if (renderIntent > 3) renderIntent = 3;
if (renderIntent < 0) renderIntent = 0;
m_cfg.writeEntry("renderIntent", renderIntent);
}
bool KisConfig::useOpenGL(bool defaultValue) const
{
if (defaultValue) {
return true;
}
//dbgKrita << "use opengl" << m_cfg.readEntry("useOpenGL", true) << "success" << m_cfg.readEntry("canvasState", "OPENGL_SUCCESS");
QString cs = canvasState();
#ifdef Q_OS_WIN
return (m_cfg.readEntry("useOpenGLWindows", true) && (cs == "OPENGL_SUCCESS" || cs == "TRY_OPENGL"));
#else
return (m_cfg.readEntry("useOpenGL", true) && (cs == "OPENGL_SUCCESS" || cs == "TRY_OPENGL"));
#endif
}
void KisConfig::setUseOpenGL(bool useOpenGL) const
{
#ifdef Q_OS_WIN
m_cfg.writeEntry("useOpenGLWindows", useOpenGL);
#else
m_cfg.writeEntry("useOpenGL", useOpenGL);
#endif
}
int KisConfig::openGLFilteringMode(bool defaultValue) const
{
return (defaultValue ? 3 : m_cfg.readEntry("OpenGLFilterMode", 3));
}
void KisConfig::setOpenGLFilteringMode(int filteringMode)
{
m_cfg.writeEntry("OpenGLFilterMode", filteringMode);
}
bool KisConfig::useOpenGLTextureBuffer(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("useOpenGLTextureBuffer", true));
}
void KisConfig::setUseOpenGLTextureBuffer(bool useBuffer)
{
m_cfg.writeEntry("useOpenGLTextureBuffer", useBuffer);
}
int KisConfig::openGLTextureSize(bool defaultValue) const
{
return (defaultValue ? 256 : m_cfg.readEntry("textureSize", 256));
}
bool KisConfig::disableVSync(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("disableVSync", true));
}
void KisConfig::setDisableVSync(bool disableVSync)
{
m_cfg.writeEntry("disableVSync", disableVSync);
}
bool KisConfig::showAdvancedOpenGLSettings(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showAdvancedOpenGLSettings", false));
}
bool KisConfig::forceOpenGLFenceWorkaround(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("forceOpenGLFenceWorkaround", false));
}
int KisConfig::numMipmapLevels(bool defaultValue) const
{
return (defaultValue ? 4 : m_cfg.readEntry("numMipmapLevels", 4));
}
int KisConfig::textureOverlapBorder() const
{
return 1 << qMax(0, numMipmapLevels());
}
quint32 KisConfig::getGridMainStyle(bool defaultValue) const
{
int v = m_cfg.readEntry("gridmainstyle", 0);
v = qBound(0, v, 2);
return (defaultValue ? 0 : v);
}
void KisConfig::setGridMainStyle(quint32 v) const
{
m_cfg.writeEntry("gridmainstyle", v);
}
quint32 KisConfig::getGridSubdivisionStyle(bool defaultValue) const
{
quint32 v = m_cfg.readEntry("gridsubdivisionstyle", 1);
if (v > 2) v = 2;
return (defaultValue ? 1 : v);
}
void KisConfig::setGridSubdivisionStyle(quint32 v) const
{
m_cfg.writeEntry("gridsubdivisionstyle", v);
}
QColor KisConfig::getGridMainColor(bool defaultValue) const
{
QColor col(99, 99, 99);
return (defaultValue ? col : m_cfg.readEntry("gridmaincolor", col));
}
void KisConfig::setGridMainColor(const QColor & v) const
{
m_cfg.writeEntry("gridmaincolor", v);
}
QColor KisConfig::getGridSubdivisionColor(bool defaultValue) const
{
QColor col(150, 150, 150);
return (defaultValue ? col : m_cfg.readEntry("gridsubdivisioncolor", col));
}
void KisConfig::setGridSubdivisionColor(const QColor & v) const
{
m_cfg.writeEntry("gridsubdivisioncolor", v);
}
QColor KisConfig::getPixelGridColor(bool defaultValue) const
{
QColor col(255, 255, 255);
return (defaultValue ? col : m_cfg.readEntry("pixelGridColor", col));
}
void KisConfig::setPixelGridColor(const QColor & v) const
{
m_cfg.writeEntry("pixelGridColor", v);
}
qreal KisConfig::getPixelGridDrawingThreshold(bool defaultValue) const
{
qreal border = 24.0f;
return (defaultValue ? border : m_cfg.readEntry("pixelGridDrawingThreshold", border));
}
void KisConfig::setPixelGridDrawingThreshold(qreal v) const
{
m_cfg.writeEntry("pixelGridDrawingThreshold", v);
}
bool KisConfig::pixelGridEnabled(bool defaultValue) const
{
bool enabled = true;
return (defaultValue ? enabled : m_cfg.readEntry("pixelGridEnabled", enabled));
}
void KisConfig::enablePixelGrid(bool v) const
{
m_cfg.writeEntry("pixelGridEnabled", v);
}
quint32 KisConfig::guidesLineStyle(bool defaultValue) const
{
int v = m_cfg.readEntry("guidesLineStyle", 0);
v = qBound(0, v, 2);
return (defaultValue ? 0 : v);
}
void KisConfig::setGuidesLineStyle(quint32 v) const
{
m_cfg.writeEntry("guidesLineStyle", v);
}
QColor KisConfig::guidesColor(bool defaultValue) const
{
QColor col(99, 99, 99);
return (defaultValue ? col : m_cfg.readEntry("guidesColor", col));
}
void KisConfig::setGuidesColor(const QColor & v) const
{
m_cfg.writeEntry("guidesColor", v);
}
void KisConfig::loadSnapConfig(KisSnapConfig *config, bool defaultValue) const
{
KisSnapConfig defaultConfig(false);
if (defaultValue) {
*config = defaultConfig;
return;
}
config->setOrthogonal(m_cfg.readEntry("globalSnapOrthogonal", defaultConfig.orthogonal()));
config->setNode(m_cfg.readEntry("globalSnapNode", defaultConfig.node()));
config->setExtension(m_cfg.readEntry("globalSnapExtension", defaultConfig.extension()));
config->setIntersection(m_cfg.readEntry("globalSnapIntersection", defaultConfig.intersection()));
config->setBoundingBox(m_cfg.readEntry("globalSnapBoundingBox", defaultConfig.boundingBox()));
config->setImageBounds(m_cfg.readEntry("globalSnapImageBounds", defaultConfig.imageBounds()));
config->setImageCenter(m_cfg.readEntry("globalSnapImageCenter", defaultConfig.imageCenter()));
}
void KisConfig::saveSnapConfig(const KisSnapConfig &config)
{
m_cfg.writeEntry("globalSnapOrthogonal", config.orthogonal());
m_cfg.writeEntry("globalSnapNode", config.node());
m_cfg.writeEntry("globalSnapExtension", config.extension());
m_cfg.writeEntry("globalSnapIntersection", config.intersection());
m_cfg.writeEntry("globalSnapBoundingBox", config.boundingBox());
m_cfg.writeEntry("globalSnapImageBounds", config.imageBounds());
m_cfg.writeEntry("globalSnapImageCenter", config.imageCenter());
}
qint32 KisConfig::checkSize(bool defaultValue) const
{
return (defaultValue ? 32 : m_cfg.readEntry("checksize", 32));
}
void KisConfig::setCheckSize(qint32 checksize) const
{
m_cfg.writeEntry("checksize", checksize);
}
bool KisConfig::scrollCheckers(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("scrollingcheckers", false));
}
void KisConfig::setScrollingCheckers(bool sc) const
{
m_cfg.writeEntry("scrollingcheckers", sc);
}
QColor KisConfig::canvasBorderColor(bool defaultValue) const
{
QColor color(QColor(128,128,128));
return (defaultValue ? color : m_cfg.readEntry("canvasBorderColor", color));
}
void KisConfig::setCanvasBorderColor(const QColor& color) const
{
m_cfg.writeEntry("canvasBorderColor", color);
}
bool KisConfig::hideScrollbars(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("hideScrollbars", false));
}
void KisConfig::setHideScrollbars(bool value) const
{
m_cfg.writeEntry("hideScrollbars", value);
}
QColor KisConfig::checkersColor1(bool defaultValue) const
{
QColor col(220, 220, 220);
return (defaultValue ? col : m_cfg.readEntry("checkerscolor", col));
}
void KisConfig::setCheckersColor1(const QColor & v) const
{
m_cfg.writeEntry("checkerscolor", v);
}
QColor KisConfig::checkersColor2(bool defaultValue) const
{
return (defaultValue ? QColor(Qt::white) : m_cfg.readEntry("checkerscolor2", QColor(Qt::white)));
}
void KisConfig::setCheckersColor2(const QColor & v) const
{
m_cfg.writeEntry("checkerscolor2", v);
}
bool KisConfig::antialiasCurves(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("antialiascurves", true));
}
void KisConfig::setAntialiasCurves(bool v) const
{
m_cfg.writeEntry("antialiascurves", v);
}
bool KisConfig::antialiasSelectionOutline(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("AntialiasSelectionOutline", false));
}
void KisConfig::setAntialiasSelectionOutline(bool v) const
{
m_cfg.writeEntry("AntialiasSelectionOutline", v);
}
bool KisConfig::showRootLayer(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ShowRootLayer", false));
}
void KisConfig::setShowRootLayer(bool showRootLayer) const
{
m_cfg.writeEntry("ShowRootLayer", showRootLayer);
}
bool KisConfig::showGlobalSelection(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ShowGlobalSelection", false));
}
void KisConfig::setShowGlobalSelection(bool showGlobalSelection) const
{
m_cfg.writeEntry("ShowGlobalSelection", showGlobalSelection);
}
bool KisConfig::showOutlineWhilePainting(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("ShowOutlineWhilePainting", true));
}
void KisConfig::setShowOutlineWhilePainting(bool showOutlineWhilePainting) const
{
m_cfg.writeEntry("ShowOutlineWhilePainting", showOutlineWhilePainting);
}
bool KisConfig::forceAlwaysFullSizedOutline(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("forceAlwaysFullSizedOutline", false));
}
void KisConfig::setForceAlwaysFullSizedOutline(bool value) const
{
m_cfg.writeEntry("forceAlwaysFullSizedOutline", value);
}
KisConfig::SessionOnStartup KisConfig::sessionOnStartup(bool defaultValue) const
{
int value = defaultValue ? SOS_BlankSession : m_cfg.readEntry("sessionOnStartup", (int)SOS_BlankSession);
return (KisConfig::SessionOnStartup)value;
}
void KisConfig::setSessionOnStartup(SessionOnStartup value)
{
m_cfg.writeEntry("sessionOnStartup", (int)value);
}
bool KisConfig::saveSessionOnQuit(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("saveSessionOnQuit", false);
}
void KisConfig::setSaveSessionOnQuit(bool value)
{
m_cfg.writeEntry("saveSessionOnQuit", value);
}
qreal KisConfig::outlineSizeMinimum(bool defaultValue) const
{
return (defaultValue ? 1.0 : m_cfg.readEntry("OutlineSizeMinimum", 1.0));
}
void KisConfig::setOutlineSizeMinimum(qreal outlineSizeMinimum) const
{
m_cfg.writeEntry("OutlineSizeMinimum", outlineSizeMinimum);
}
qreal KisConfig::selectionViewSizeMinimum(bool defaultValue) const
{
return (defaultValue ? 5.0 : m_cfg.readEntry("SelectionViewSizeMinimum", 5.0));
}
void KisConfig::setSelectionViewSizeMinimum(qreal outlineSizeMinimum) const
{
m_cfg.writeEntry("SelectionViewSizeMinimum", outlineSizeMinimum);
}
int KisConfig::autoSaveInterval(bool defaultValue) const
{
return (defaultValue ? 15 * 60 : m_cfg.readEntry("AutoSaveInterval", 15 * 60));
}
void KisConfig::setAutoSaveInterval(int seconds) const
{
return m_cfg.writeEntry("AutoSaveInterval", seconds);
}
bool KisConfig::backupFile(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("CreateBackupFile", true));
}
void KisConfig::setBackupFile(bool backupFile) const
{
m_cfg.writeEntry("CreateBackupFile", backupFile);
}
bool KisConfig::showFilterGallery(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showFilterGallery", false));
}
void KisConfig::setShowFilterGallery(bool showFilterGallery) const
{
m_cfg.writeEntry("showFilterGallery", showFilterGallery);
}
bool KisConfig::showFilterGalleryLayerMaskDialog(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showFilterGalleryLayerMaskDialog", true));
}
void KisConfig::setShowFilterGalleryLayerMaskDialog(bool showFilterGallery) const
{
m_cfg.writeEntry("setShowFilterGalleryLayerMaskDialog", showFilterGallery);
}
QString KisConfig::canvasState(bool defaultValue) const
{
const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
return (defaultValue ? "OPENGL_NOT_TRIED" : kritarc.value("canvasState", "OPENGL_NOT_TRIED").toString());
}
void KisConfig::setCanvasState(const QString& state) const
{
static QStringList acceptableStates;
if (acceptableStates.isEmpty()) {
acceptableStates << "OPENGL_SUCCESS" << "TRY_OPENGL" << "OPENGL_NOT_TRIED" << "OPENGL_FAILED";
}
if (acceptableStates.contains(state)) {
const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
kritarc.setValue("canvasState", state);
}
}
bool KisConfig::toolOptionsPopupDetached(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ToolOptionsPopupDetached", false));
}
void KisConfig::setToolOptionsPopupDetached(bool detached) const
{
m_cfg.writeEntry("ToolOptionsPopupDetached", detached);
}
bool KisConfig::paintopPopupDetached(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("PaintopPopupDetached", false));
}
void KisConfig::setPaintopPopupDetached(bool detached) const
{
m_cfg.writeEntry("PaintopPopupDetached", detached);
}
QString KisConfig::pressureTabletCurve(bool defaultValue) const
{
return (defaultValue ? "0,0;1,1" : m_cfg.readEntry("tabletPressureCurve","0,0;1,1;"));
}
void KisConfig::setPressureTabletCurve(const QString& curveString) const
{
m_cfg.writeEntry("tabletPressureCurve", curveString);
}
bool KisConfig::useWin8PointerInput(bool defaultValue) const
{
#ifdef Q_OS_WIN
return (defaultValue ? false : m_cfg.readEntry("useWin8PointerInput", false));
#else
Q_UNUSED(defaultValue);
return false;
#endif
}
void KisConfig::setUseWin8PointerInput(bool value) const
{
#ifdef Q_OS_WIN
// Special handling: Only set value if changed
// I don't want it to be set if the user hasn't touched it
if (useWin8PointerInput() != value) {
m_cfg.writeEntry("useWin8PointerInput", value);
}
#else
Q_UNUSED(value)
#endif
}
qreal KisConfig::vastScrolling(bool defaultValue) const
{
return (defaultValue ? 0.9 : m_cfg.readEntry("vastScrolling", 0.9));
}
void KisConfig::setVastScrolling(const qreal factor) const
{
m_cfg.writeEntry("vastScrolling", factor);
}
int KisConfig::presetChooserViewMode(bool defaultValue) const
{
return (defaultValue ? 0 : m_cfg.readEntry("presetChooserViewMode", 0));
}
void KisConfig::setPresetChooserViewMode(const int mode) const
{
m_cfg.writeEntry("presetChooserViewMode", mode);
}
int KisConfig::presetIconSize(bool defaultValue) const
{
return (defaultValue ? 60 : m_cfg.readEntry("presetIconSize", 60));
}
void KisConfig::setPresetIconSize(const int value) const
{
m_cfg.writeEntry("presetIconSize", value);
}
bool KisConfig::firstRun(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("firstRun", true));
}
void KisConfig::setFirstRun(const bool first) const
{
m_cfg.writeEntry("firstRun", first);
}
int KisConfig::horizontalSplitLines(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("horizontalSplitLines", 1));
}
void KisConfig::setHorizontalSplitLines(const int numberLines) const
{
m_cfg.writeEntry("horizontalSplitLines", numberLines);
}
int KisConfig::verticalSplitLines(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("verticalSplitLines", 1));
}
void KisConfig::setVerticalSplitLines(const int numberLines) const
{
m_cfg.writeEntry("verticalSplitLines", numberLines);
}
bool KisConfig::clicklessSpacePan(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("clicklessSpacePan", true));
}
void KisConfig::setClicklessSpacePan(const bool toggle) const
{
m_cfg.writeEntry("clicklessSpacePan", toggle);
}
bool KisConfig::hideDockersFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideDockersFullScreen", true));
}
void KisConfig::setHideDockersFullscreen(const bool value) const
{
m_cfg.writeEntry("hideDockersFullScreen", value);
}
bool KisConfig::showDockers(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showDockers", true));
}
void KisConfig::setShowDockers(const bool value) const
{
m_cfg.writeEntry("showDockers", value);
}
bool KisConfig::showStatusBar(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showStatusBar", true));
}
void KisConfig::setShowStatusBar(const bool value) const
{
m_cfg.writeEntry("showStatusBar", value);
}
bool KisConfig::hideMenuFullscreen(bool defaultValue) const
{
return (defaultValue ? true: m_cfg.readEntry("hideMenuFullScreen", true));
}
void KisConfig::setHideMenuFullscreen(const bool value) const
{
m_cfg.writeEntry("hideMenuFullScreen", value);
}
bool KisConfig::hideScrollbarsFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideScrollbarsFullScreen", true));
}
void KisConfig::setHideScrollbarsFullscreen(const bool value) const
{
m_cfg.writeEntry("hideScrollbarsFullScreen", value);
}
bool KisConfig::hideStatusbarFullscreen(bool defaultValue) const
{
return (defaultValue ? true: m_cfg.readEntry("hideStatusbarFullScreen", true));
}
void KisConfig::setHideStatusbarFullscreen(const bool value) const
{
m_cfg.writeEntry("hideStatusbarFullScreen", value);
}
bool KisConfig::hideTitlebarFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideTitleBarFullscreen", true));
}
void KisConfig::setHideTitlebarFullscreen(const bool value) const
{
m_cfg.writeEntry("hideTitleBarFullscreen", value);
}
bool KisConfig::hideToolbarFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideToolbarFullscreen", true));
}
void KisConfig::setHideToolbarFullscreen(const bool value) const
{
m_cfg.writeEntry("hideToolbarFullscreen", value);
}
bool KisConfig::fullscreenMode(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("fullscreenMode", true));
}
void KisConfig::setFullscreenMode(const bool value) const
{
m_cfg.writeEntry("fullscreenMode", value);
}
QStringList KisConfig::favoriteCompositeOps(bool defaultValue) const
{
return (defaultValue ? QStringList() : m_cfg.readEntry("favoriteCompositeOps", QStringList()));
}
void KisConfig::setFavoriteCompositeOps(const QStringList& compositeOps) const
{
m_cfg.writeEntry("favoriteCompositeOps", compositeOps);
}
QString KisConfig::exportConfiguration(const QString &filterId, bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("ExportConfiguration-" + filterId, QString()));
}
void KisConfig::setExportConfiguration(const QString &filterId, KisPropertiesConfigurationSP properties) const
{
QString exportConfig = properties->toXML();
m_cfg.writeEntry("ExportConfiguration-" + filterId, exportConfig);
}
QString KisConfig::importConfiguration(const QString &filterId, bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("ImportConfiguration-" + filterId, QString()));
}
void KisConfig::setImportConfiguration(const QString &filterId, KisPropertiesConfigurationSP properties) const
{
QString importConfig = properties->toXML();
m_cfg.writeEntry("ImportConfiguration-" + filterId, importConfig);
}
bool KisConfig::useOcio(bool defaultValue) const
{
#ifdef HAVE_OCIO
return (defaultValue ? false : m_cfg.readEntry("Krita/Ocio/UseOcio", false));
#else
Q_UNUSED(defaultValue);
return false;
#endif
}
void KisConfig::setUseOcio(bool useOCIO) const
{
m_cfg.writeEntry("Krita/Ocio/UseOcio", useOCIO);
}
int KisConfig::favoritePresets(bool defaultValue) const
{
return (defaultValue ? 10 : m_cfg.readEntry("numFavoritePresets", 10));
}
void KisConfig::setFavoritePresets(const int value)
{
m_cfg.writeEntry("numFavoritePresets", value);
}
bool KisConfig::levelOfDetailEnabled(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("levelOfDetailEnabled", false));
}
void KisConfig::setLevelOfDetailEnabled(bool value)
{
m_cfg.writeEntry("levelOfDetailEnabled", value);
}
KisConfig::OcioColorManagementMode
KisConfig::ocioColorManagementMode(bool defaultValue) const
{
return (OcioColorManagementMode)(defaultValue ? INTERNAL
: m_cfg.readEntry("Krita/Ocio/OcioColorManagementMode", (int) INTERNAL));
}
void KisConfig::setOcioColorManagementMode(OcioColorManagementMode mode) const
{
m_cfg.writeEntry("Krita/Ocio/OcioColorManagementMode", (int) mode);
}
QString KisConfig::ocioConfigurationPath(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("Krita/Ocio/OcioConfigPath", QString()));
}
void KisConfig::setOcioConfigurationPath(const QString &path) const
{
m_cfg.writeEntry("Krita/Ocio/OcioConfigPath", path);
}
QString KisConfig::ocioLutPath(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("Krita/Ocio/OcioLutPath", QString()));
}
void KisConfig::setOcioLutPath(const QString &path) const
{
m_cfg.writeEntry("Krita/Ocio/OcioLutPath", path);
}
int KisConfig::ocioLutEdgeSize(bool defaultValue) const
{
return (defaultValue ? 64 : m_cfg.readEntry("Krita/Ocio/LutEdgeSize", 64));
}
void KisConfig::setOcioLutEdgeSize(int value)
{
m_cfg.writeEntry("Krita/Ocio/LutEdgeSize", value);
}
bool KisConfig::ocioLockColorVisualRepresentation(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("Krita/Ocio/OcioLockColorVisualRepresentation", false));
}
void KisConfig::setOcioLockColorVisualRepresentation(bool value)
{
m_cfg.writeEntry("Krita/Ocio/OcioLockColorVisualRepresentation", value);
}
QString KisConfig::defaultPalette(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("defaultPalette", "Default"));
}
void KisConfig::setDefaultPalette(const QString& name) const
{
m_cfg.writeEntry("defaultPalette", name);
}
QString KisConfig::toolbarSlider(int sliderNumber, bool defaultValue) const
{
QString def = "flow";
if (sliderNumber == 1) {
def = "opacity";
}
if (sliderNumber == 2) {
def = "size";
}
return (defaultValue ? def : m_cfg.readEntry(QString("toolbarslider_%1").arg(sliderNumber), def));
}
void KisConfig::setToolbarSlider(int sliderNumber, const QString &slider)
{
m_cfg.writeEntry(QString("toolbarslider_%1").arg(sliderNumber), slider);
}
int KisConfig::layerThumbnailSize(bool defaultValue) const
{
return (defaultValue ? 20 : m_cfg.readEntry("layerThumbnailSize", 20));
}
void KisConfig::setLayerThumbnailSize(int size)
{
m_cfg.writeEntry("layerThumbnailSize", size);
}
bool KisConfig::sliderLabels(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("sliderLabels", true));
}
void KisConfig::setSliderLabels(bool enabled)
{
m_cfg.writeEntry("sliderLabels", enabled);
}
QString KisConfig::currentInputProfile(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("currentInputProfile", QString()));
}
void KisConfig::setCurrentInputProfile(const QString& name)
{
m_cfg.writeEntry("currentInputProfile", name);
}
bool KisConfig::useSystemMonitorProfile(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ColorManagement/UseSystemMonitorProfile", false));
}
void KisConfig::setUseSystemMonitorProfile(bool _useSystemMonitorProfile) const
{
m_cfg.writeEntry("ColorManagement/UseSystemMonitorProfile", _useSystemMonitorProfile);
}
bool KisConfig::presetStripVisible(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("presetStripVisible", true));
}
void KisConfig::setPresetStripVisible(bool visible)
{
m_cfg.writeEntry("presetStripVisible", visible);
}
bool KisConfig::scratchpadVisible(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("scratchpadVisible", true));
}
void KisConfig::setScratchpadVisible(bool visible)
{
m_cfg.writeEntry("scratchpadVisible", visible);
}
bool KisConfig::showSingleChannelAsColor(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showSingleChannelAsColor", false));
}
void KisConfig::setShowSingleChannelAsColor(bool asColor)
{
m_cfg.writeEntry("showSingleChannelAsColor", asColor);
}
bool KisConfig::hidePopups(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("hidePopups", false));
}
void KisConfig::setHidePopups(bool hidepopups)
{
m_cfg.writeEntry("hidePopups", hidepopups);
}
int KisConfig::numDefaultLayers(bool defaultValue) const
{
return (defaultValue ? 2 : m_cfg.readEntry("NumberOfLayersForNewImage", 2));
}
void KisConfig::setNumDefaultLayers(int num)
{
m_cfg.writeEntry("NumberOfLayersForNewImage", num);
}
quint8 KisConfig::defaultBackgroundOpacity(bool defaultValue) const
{
return (defaultValue ? (int)OPACITY_OPAQUE_U8 : m_cfg.readEntry("BackgroundOpacityForNewImage", (int)OPACITY_OPAQUE_U8));
}
void KisConfig::setDefaultBackgroundOpacity(quint8 value)
{
m_cfg.writeEntry("BackgroundOpacityForNewImage", (int)value);
}
QColor KisConfig::defaultBackgroundColor(bool defaultValue) const
{
return (defaultValue ? QColor(Qt::white) : m_cfg.readEntry("BackgroundColorForNewImage", QColor(Qt::white)));
}
void KisConfig::setDefaultBackgroundColor(QColor value)
{
m_cfg.writeEntry("BackgroundColorForNewImage", value);
}
KisConfig::BackgroundStyle KisConfig::defaultBackgroundStyle(bool defaultValue) const
{
- return (KisConfig::BackgroundStyle)(defaultValue ? LAYER : m_cfg.readEntry("BackgroundStyleForNewImage", (int)LAYER));
+ return (KisConfig::BackgroundStyle)(defaultValue ? RASTER_LAYER : m_cfg.readEntry("BackgroundStyleForNewImage", (int)RASTER_LAYER));
}
void KisConfig::setDefaultBackgroundStyle(KisConfig::BackgroundStyle value)
{
m_cfg.writeEntry("BackgroundStyleForNewImage", (int)value);
}
int KisConfig::lineSmoothingType(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("LineSmoothingType", 1));
}
void KisConfig::setLineSmoothingType(int value)
{
m_cfg.writeEntry("LineSmoothingType", value);
}
qreal KisConfig::lineSmoothingDistance(bool defaultValue) const
{
return (defaultValue ? 50.0 : m_cfg.readEntry("LineSmoothingDistance", 50.0));
}
void KisConfig::setLineSmoothingDistance(qreal value)
{
m_cfg.writeEntry("LineSmoothingDistance", value);
}
qreal KisConfig::lineSmoothingTailAggressiveness(bool defaultValue) const
{
return (defaultValue ? 0.15 : m_cfg.readEntry("LineSmoothingTailAggressiveness", 0.15));
}
void KisConfig::setLineSmoothingTailAggressiveness(qreal value)
{
m_cfg.writeEntry("LineSmoothingTailAggressiveness", value);
}
bool KisConfig::lineSmoothingSmoothPressure(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("LineSmoothingSmoothPressure", false));
}
void KisConfig::setLineSmoothingSmoothPressure(bool value)
{
m_cfg.writeEntry("LineSmoothingSmoothPressure", value);
}
bool KisConfig::lineSmoothingScalableDistance(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingScalableDistance", true));
}
void KisConfig::setLineSmoothingScalableDistance(bool value)
{
m_cfg.writeEntry("LineSmoothingScalableDistance", value);
}
qreal KisConfig::lineSmoothingDelayDistance(bool defaultValue) const
{
return (defaultValue ? 50.0 : m_cfg.readEntry("LineSmoothingDelayDistance", 50.0));
}
void KisConfig::setLineSmoothingDelayDistance(qreal value)
{
m_cfg.writeEntry("LineSmoothingDelayDistance", value);
}
bool KisConfig::lineSmoothingUseDelayDistance(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingUseDelayDistance", true));
}
void KisConfig::setLineSmoothingUseDelayDistance(bool value)
{
m_cfg.writeEntry("LineSmoothingUseDelayDistance", value);
}
bool KisConfig::lineSmoothingFinishStabilizedCurve(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingFinishStabilizedCurve", true));
}
void KisConfig::setLineSmoothingFinishStabilizedCurve(bool value)
{
m_cfg.writeEntry("LineSmoothingFinishStabilizedCurve", value);
}
bool KisConfig::lineSmoothingStabilizeSensors(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingStabilizeSensors", true));
}
void KisConfig::setLineSmoothingStabilizeSensors(bool value)
{
m_cfg.writeEntry("LineSmoothingStabilizeSensors", value);
}
int KisConfig::tabletEventsDelay(bool defaultValue) const
{
return (defaultValue ? 10 : m_cfg.readEntry("tabletEventsDelay", 10));
}
void KisConfig::setTabletEventsDelay(int value)
{
m_cfg.writeEntry("tabletEventsDelay", value);
}
bool KisConfig::trackTabletEventLatency(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("trackTabletEventLatency", false));
}
void KisConfig::setTrackTabletEventLatency(bool value)
{
m_cfg.writeEntry("trackTabletEventLatency", value);
}
bool KisConfig::testingAcceptCompressedTabletEvents(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("testingAcceptCompressedTabletEvents", false));
}
void KisConfig::setTestingAcceptCompressedTabletEvents(bool value)
{
m_cfg.writeEntry("testingAcceptCompressedTabletEvents", value);
}
bool KisConfig::shouldEatDriverShortcuts(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("shouldEatDriverShortcuts", false));
}
bool KisConfig::testingCompressBrushEvents(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("testingCompressBrushEvents", false));
}
void KisConfig::setTestingCompressBrushEvents(bool value)
{
m_cfg.writeEntry("testingCompressBrushEvents", value);
}
int KisConfig::workaroundX11SmoothPressureSteps(bool defaultValue) const
{
return (defaultValue ? 0 : m_cfg.readEntry("workaroundX11SmoothPressureSteps", 0));
}
bool KisConfig::showCanvasMessages(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showOnCanvasMessages", true));
}
void KisConfig::setShowCanvasMessages(bool show)
{
m_cfg.writeEntry("showOnCanvasMessages", show);
}
bool KisConfig::compressKra(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("compressLayersInKra", false));
}
void KisConfig::setCompressKra(bool compress)
{
m_cfg.writeEntry("compressLayersInKra", compress);
}
bool KisConfig::toolOptionsInDocker(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("ToolOptionsInDocker", true));
}
void KisConfig::setToolOptionsInDocker(bool inDocker)
{
m_cfg.writeEntry("ToolOptionsInDocker", inDocker);
}
bool KisConfig::kineticScrollingEnabled(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("KineticScrollingEnabled", true));
}
void KisConfig::setKineticScrollingEnabled(bool value)
{
m_cfg.writeEntry("KineticScrollingEnabled", value);
}
int KisConfig::kineticScrollingGesture(bool defaultValue) const
{
return (defaultValue ? 2 : m_cfg.readEntry("KineticScrollingGesture", 2));
}
void KisConfig::setKineticScrollingGesture(int gesture)
{
m_cfg.writeEntry("KineticScrollingGesture", gesture);
}
int KisConfig::kineticScrollingSensitivity(bool defaultValue) const
{
return (defaultValue ? 75 : m_cfg.readEntry("KineticScrollingSensitivity", 75));
}
void KisConfig::setKineticScrollingSensitivity(int sensitivity)
{
m_cfg.writeEntry("KineticScrollingSensitivity", sensitivity);
}
bool KisConfig::kineticScrollingHiddenScrollbars(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("KineticScrollingHideScrollbar", false));
}
void KisConfig::setKineticScrollingHideScrollbars(bool scrollbar)
{
m_cfg.writeEntry("KineticScrollingHideScrollbar", scrollbar);
}
const KoColorSpace* KisConfig::customColorSelectorColorSpace(bool defaultValue) const
{
const KoColorSpace *cs = 0;
KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
if (defaultValue || cfg.readEntry("useCustomColorSpace", true)) {
KoColorSpaceRegistry* csr = KoColorSpaceRegistry::instance();
QString modelID = cfg.readEntry("customColorSpaceModel", "RGBA");
QString depthID = cfg.readEntry("customColorSpaceDepthID", "U8");
QString profile = cfg.readEntry("customColorSpaceProfile", "sRGB built-in - (lcms internal)");
if (profile == "default") {
// qDebug() << "Falling back to default color profile.";
profile = "sRGB built-in - (lcms internal)";
}
cs = csr->colorSpace(modelID, depthID, profile);
}
return cs;
}
void KisConfig::setCustomColorSelectorColorSpace(const KoColorSpace *cs)
{
KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
cfg.writeEntry("useCustomColorSpace", bool(cs));
if(cs) {
cfg.writeEntry("customColorSpaceModel", cs->colorModelId().id());
cfg.writeEntry("customColorSpaceDepthID", cs->colorDepthId().id());
cfg.writeEntry("customColorSpaceProfile", cs->profile()->name());
}
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::enableOpenGLFramerateLogging(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("enableOpenGLFramerateLogging", false));
}
void KisConfig::setEnableOpenGLFramerateLogging(bool value) const
{
m_cfg.writeEntry("enableOpenGLFramerateLogging", value);
}
bool KisConfig::enableBrushSpeedLogging(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("enableBrushSpeedLogging", false));
}
void KisConfig::setEnableBrushSpeedLogging(bool value) const
{
m_cfg.writeEntry("enableBrushSpeedLogging", value);
}
void KisConfig::setEnableAmdVectorizationWorkaround(bool value)
{
m_cfg.writeEntry("amdDisableVectorWorkaround", value);
}
bool KisConfig::enableAmdVectorizationWorkaround(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("amdDisableVectorWorkaround", false));
}
void KisConfig::setAnimationDropFrames(bool value)
{
bool oldValue = animationDropFrames();
if (value == oldValue) return;
m_cfg.writeEntry("animationDropFrames", value);
KisConfigNotifier::instance()->notifyDropFramesModeChanged();
}
bool KisConfig::animationDropFrames(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("animationDropFrames", true));
}
int KisConfig::scrubbingUpdatesDelay(bool defaultValue) const
{
return (defaultValue ? 30 : m_cfg.readEntry("scrubbingUpdatesDelay", 30));
}
void KisConfig::setScrubbingUpdatesDelay(int value)
{
m_cfg.writeEntry("scrubbingUpdatesDelay", value);
}
int KisConfig::scrubbingAudioUpdatesDelay(bool defaultValue) const
{
return (defaultValue ? -1 : m_cfg.readEntry("scrubbingAudioUpdatesDelay", -1));
}
void KisConfig::setScrubbingAudioUpdatesDelay(int value)
{
m_cfg.writeEntry("scrubbingAudioUpdatesDelay", value);
}
int KisConfig::audioOffsetTolerance(bool defaultValue) const
{
return (defaultValue ? -1 : m_cfg.readEntry("audioOffsetTolerance", -1));
}
void KisConfig::setAudioOffsetTolerance(int value)
{
m_cfg.writeEntry("audioOffsetTolerance", value);
}
bool KisConfig::switchSelectionCtrlAlt(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("switchSelectionCtrlAlt", false);
}
void KisConfig::setSwitchSelectionCtrlAlt(bool value)
{
m_cfg.writeEntry("switchSelectionCtrlAlt", value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::convertToImageColorspaceOnImport(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("ConvertToImageColorSpaceOnImport", false);
}
void KisConfig::setConvertToImageColorspaceOnImport(bool value)
{
m_cfg.writeEntry("ConvertToImageColorSpaceOnImport", value);
}
int KisConfig::stabilizerSampleSize(bool defaultValue) const
{
#ifdef Q_OS_WIN
const int defaultSampleSize = 50;
#else
const int defaultSampleSize = 15;
#endif
return defaultValue ?
defaultSampleSize : m_cfg.readEntry("stabilizerSampleSize", defaultSampleSize);
}
void KisConfig::setStabilizerSampleSize(int value)
{
m_cfg.writeEntry("stabilizerSampleSize", value);
}
bool KisConfig::stabilizerDelayedPaint(bool defaultValue) const
{
const bool defaultEnabled = true;
return defaultValue ?
defaultEnabled : m_cfg.readEntry("stabilizerDelayedPaint", defaultEnabled);
}
void KisConfig::setStabilizerDelayedPaint(bool value)
{
m_cfg.writeEntry("stabilizerDelayedPaint", value);
}
QString KisConfig::customFFMpegPath(bool defaultValue) const
{
return defaultValue ? QString() : m_cfg.readEntry("ffmpegExecutablePath", QString());
}
void KisConfig::setCustomFFMpegPath(const QString &value) const
{
m_cfg.writeEntry("ffmpegExecutablePath", value);
}
bool KisConfig::showBrushHud(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("showBrushHud", false);
}
void KisConfig::setShowBrushHud(bool value)
{
m_cfg.writeEntry("showBrushHud", value);
}
QString KisConfig::brushHudSetting(bool defaultValue) const
{
QString defaultDoc = "\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n";
return defaultValue ? defaultDoc : m_cfg.readEntry("brushHudSettings", defaultDoc);
}
void KisConfig::setBrushHudSetting(const QString &value) const
{
m_cfg.writeEntry("brushHudSettings", value);
}
bool KisConfig::calculateAnimationCacheInBackground(bool defaultValue) const
{
return defaultValue ? true : m_cfg.readEntry("calculateAnimationCacheInBackground", true);
}
void KisConfig::setCalculateAnimationCacheInBackground(bool value)
{
m_cfg.writeEntry("calculateAnimationCacheInBackground", value);
}
QColor KisConfig::defaultAssistantsColor(bool defaultValue) const
{
static const QColor defaultColor = QColor(176, 176, 176, 255);
return defaultValue ? defaultColor : m_cfg.readEntry("defaultAssistantsColor", defaultColor);
}
void KisConfig::setDefaultAssistantsColor(const QColor &color) const
{
m_cfg.writeEntry("defaultAssistantsColor", color);
}
bool KisConfig::autoSmoothBezierCurves(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("autoSmoothBezierCurves", false);
}
void KisConfig::setAutoSmoothBezierCurves(bool value)
{
m_cfg.writeEntry("autoSmoothBezierCurves", value);
}
bool KisConfig::activateTransformToolAfterPaste(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("activateTransformToolAfterPaste", false);
}
void KisConfig::setActivateTransformToolAfterPaste(bool value)
{
m_cfg.writeEntry("activateTransformToolAfterPaste", value);
}
#include
#include
void KisConfig::writeKoColor(const QString& name, const KoColor& color) const
{
QDomDocument doc = QDomDocument(name);
QDomElement el = doc.createElement(name);
doc.appendChild(el);
color.toXML(doc, el);
m_cfg.writeEntry(name, doc.toString());
}
//ported from kispropertiesconfig.
KoColor KisConfig::readKoColor(const QString& name, const KoColor& color) const
{
QDomDocument doc;
if (!m_cfg.readEntry(name).isNull()) {
doc.setContent(m_cfg.readEntry(name));
QDomElement e = doc.documentElement().firstChild().toElement();
return KoColor::fromXML(e, Integer16BitsColorDepthID.id());
} else {
QString blackColor = "\n\n \n\n";
doc.setContent(blackColor);
QDomElement e = doc.documentElement().firstChild().toElement();
return KoColor::fromXML(e, Integer16BitsColorDepthID.id());
}
return color;
}
diff --git a/libs/ui/kis_config.h b/libs/ui/kis_config.h
index eb7aa92606..dbc8d05056 100644
--- a/libs/ui/kis_config.h
+++ b/libs/ui/kis_config.h
@@ -1,616 +1,617 @@
/*
* Copyright (c) 2002 Patrick Julien
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_CONFIG_H_
#define KIS_CONFIG_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include "kritaui_export.h"
class KoColorProfile;
class KoColorSpace;
class KisSnapConfig;
class KRITAUI_EXPORT KisConfig
{
public:
/**
* @brief KisConfig create a kisconfig object
* @param readOnly if true, there will be no call to sync when the object is deleted.
* Any KisConfig object created in a thread must be read-only.
*/
KisConfig(bool readOnly);
~KisConfig();
bool disableTouchOnCanvas(bool defaultValue = false) const;
void setDisableTouchOnCanvas(bool value) const;
bool useProjections(bool defaultValue = false) const;
void setUseProjections(bool useProj) const;
bool undoEnabled(bool defaultValue = false) const;
void setUndoEnabled(bool undo) const;
int undoStackLimit(bool defaultValue = false) const;
void setUndoStackLimit(int limit) const;
bool useCumulativeUndoRedo(bool defaultValue = false) const;
void setCumulativeUndoRedo(bool value);
double stackT1(bool defaultValue = false) const;
void setStackT1(int T1);
double stackT2(bool defaultValue = false) const;
void setStackT2(int T2);
int stackN(bool defaultValue = false) const;
void setStackN(int N);
qint32 defImageWidth(bool defaultValue = false) const;
void defImageWidth(qint32 width) const;
qint32 defImageHeight(bool defaultValue = false) const;
void defImageHeight(qint32 height) const;
qreal defImageResolution(bool defaultValue = false) const;
void defImageResolution(qreal res) const;
int preferredVectorImportResolutionPPI(bool defaultValue = false) const;
void setPreferredVectorImportResolutionPPI(int value) const;
/**
* @return the id of the default color model used for creating new images.
*/
QString defColorModel(bool defaultValue = false) const;
/**
* set the id of the default color model used for creating new images.
*/
void defColorModel(const QString & model) const;
/**
* @return the id of the default color depth used for creating new images.
*/
QString defaultColorDepth(bool defaultValue = false) const;
/**
* set the id of the default color depth used for creating new images.
*/
void setDefaultColorDepth(const QString & depth) const;
/**
* @return the id of the default color profile used for creating new images.
*/
QString defColorProfile(bool defaultValue = false) const;
/**
* set the id of the default color profile used for creating new images.
*/
void defColorProfile(const QString & depth) const;
CursorStyle newCursorStyle(bool defaultValue = false) const;
void setNewCursorStyle(CursorStyle style);
QColor getCursorMainColor(bool defaultValue = false) const;
void setCursorMainColor(const QColor& v) const;
OutlineStyle newOutlineStyle(bool defaultValue = false) const;
void setNewOutlineStyle(OutlineStyle style);
QRect colorPreviewRect() const;
void setColorPreviewRect(const QRect &rect);
/// get the profile the user has selected for the given screen
QString monitorProfile(int screen) const;
void setMonitorProfile(int screen, const QString & monitorProfile, bool override) const;
QString monitorForScreen(int screen, const QString &defaultMonitor, bool defaultValue = true) const;
void setMonitorForScreen(int screen, const QString& monitor);
/// Get the actual profile to be used for the given screen, which is
/// either the screen profile set by the color management system or
/// the custom monitor profile set by the user, depending on the configuration
const KoColorProfile *displayProfile(int screen) const;
QString workingColorSpace(bool defaultValue = false) const;
void setWorkingColorSpace(const QString & workingColorSpace) const;
QString importProfile(bool defaultValue = false) const;
void setImportProfile(const QString & importProfile) const;
QString printerColorSpace(bool defaultValue = false) const;
void setPrinterColorSpace(const QString & printerColorSpace) const;
QString printerProfile(bool defaultValue = false) const;
void setPrinterProfile(const QString & printerProfile) const;
bool useBlackPointCompensation(bool defaultValue = false) const;
void setUseBlackPointCompensation(bool useBlackPointCompensation) const;
bool allowLCMSOptimization(bool defaultValue = false) const;
void setAllowLCMSOptimization(bool allowLCMSOptimization);
bool forcePaletteColors(bool defaultValue = false) const;
void setForcePaletteColors(bool forcePaletteColors);
void writeKoColor(const QString& name, const KoColor& color) const;
KoColor readKoColor(const QString& name, const KoColor& color = KoColor()) const;
bool showRulers(bool defaultValue = false) const;
void setShowRulers(bool rulers) const;
bool forceShowSaveMessages(bool defaultValue = true) const;
void setForceShowSaveMessages(bool value) const;
bool forceShowAutosaveMessages(bool defaultValue = true) const;
void setForceShowAutosaveMessages(bool ShowAutosaveMessages) const;
bool rulersTrackMouse(bool defaultValue = false) const;
void setRulersTrackMouse(bool value) const;
qint32 pasteBehaviour(bool defaultValue = false) const;
void setPasteBehaviour(qint32 behaviour) const;
qint32 monitorRenderIntent(bool defaultValue = false) const;
void setRenderIntent(qint32 monitorRenderIntent) const;
bool useOpenGL(bool defaultValue = false) const;
void setUseOpenGL(bool useOpenGL) const;
int openGLFilteringMode(bool defaultValue = false) const;
void setOpenGLFilteringMode(int filteringMode);
bool useOpenGLTextureBuffer(bool defaultValue = false) const;
void setUseOpenGLTextureBuffer(bool useBuffer);
bool disableVSync(bool defaultValue = false) const;
void setDisableVSync(bool disableVSync);
bool showAdvancedOpenGLSettings(bool defaultValue = false) const;
bool forceOpenGLFenceWorkaround(bool defaultValue = false) const;
int numMipmapLevels(bool defaultValue = false) const;
int openGLTextureSize(bool defaultValue = false) const;
int textureOverlapBorder() const;
quint32 getGridMainStyle(bool defaultValue = false) const;
void setGridMainStyle(quint32 v) const;
quint32 getGridSubdivisionStyle(bool defaultValue = false) const;
void setGridSubdivisionStyle(quint32 v) const;
QColor getGridMainColor(bool defaultValue = false) const;
void setGridMainColor(const QColor & v) const;
QColor getGridSubdivisionColor(bool defaultValue = false) const;
void setGridSubdivisionColor(const QColor & v) const;
QColor getPixelGridColor(bool defaultValue = false) const;
void setPixelGridColor(const QColor & v) const;
qreal getPixelGridDrawingThreshold(bool defaultValue = false) const;
void setPixelGridDrawingThreshold(qreal v) const;
bool pixelGridEnabled(bool defaultValue = false) const;
void enablePixelGrid(bool v) const;
quint32 guidesLineStyle(bool defaultValue = false) const;
void setGuidesLineStyle(quint32 v) const;
QColor guidesColor(bool defaultValue = false) const;
void setGuidesColor(const QColor & v) const;
void loadSnapConfig(KisSnapConfig *config, bool defaultValue = false) const;
void saveSnapConfig(const KisSnapConfig &config);
qint32 checkSize(bool defaultValue = false) const;
void setCheckSize(qint32 checkSize) const;
bool scrollCheckers(bool defaultValue = false) const;
void setScrollingCheckers(bool scollCheckers) const;
QColor checkersColor1(bool defaultValue = false) const;
void setCheckersColor1(const QColor & v) const;
QColor checkersColor2(bool defaultValue = false) const;
void setCheckersColor2(const QColor & v) const;
QColor canvasBorderColor(bool defaultValue = false) const;
void setCanvasBorderColor(const QColor &color) const;
bool hideScrollbars(bool defaultValue = false) const;
void setHideScrollbars(bool value) const;
bool antialiasCurves(bool defaultValue = false) const;
void setAntialiasCurves(bool v) const;
bool antialiasSelectionOutline(bool defaultValue = false) const;
void setAntialiasSelectionOutline(bool v) const;
bool showRootLayer(bool defaultValue = false) const;
void setShowRootLayer(bool showRootLayer) const;
bool showGlobalSelection(bool defaultValue = false) const;
void setShowGlobalSelection(bool showGlobalSelection) const;
bool showOutlineWhilePainting(bool defaultValue = false) const;
void setShowOutlineWhilePainting(bool showOutlineWhilePainting) const;
bool forceAlwaysFullSizedOutline(bool defaultValue = false) const;
void setForceAlwaysFullSizedOutline(bool value) const;
enum SessionOnStartup {
SOS_BlankSession,
SOS_PreviousSession,
SOS_ShowSessionManager
};
SessionOnStartup sessionOnStartup(bool defaultValue = false) const;
void setSessionOnStartup(SessionOnStartup value);
bool saveSessionOnQuit(bool defaultValue) const;
void setSaveSessionOnQuit(bool value);
qreal outlineSizeMinimum(bool defaultValue = false) const;
void setOutlineSizeMinimum(qreal outlineSizeMinimum) const;
qreal selectionViewSizeMinimum(bool defaultValue = false) const;
void setSelectionViewSizeMinimum(qreal outlineSizeMinimum) const;
int autoSaveInterval(bool defaultValue = false) const;
void setAutoSaveInterval(int seconds) const;
bool backupFile(bool defaultValue = false) const;
void setBackupFile(bool backupFile) const;
bool showFilterGallery(bool defaultValue = false) const;
void setShowFilterGallery(bool showFilterGallery) const;
bool showFilterGalleryLayerMaskDialog(bool defaultValue = false) const;
void setShowFilterGalleryLayerMaskDialog(bool showFilterGallery) const;
// OPENGL_SUCCESS, TRY_OPENGL, OPENGL_NOT_TRIED, OPENGL_FAILED
QString canvasState(bool defaultValue = false) const;
void setCanvasState(const QString& state) const;
bool toolOptionsPopupDetached(bool defaultValue = false) const;
void setToolOptionsPopupDetached(bool detached) const;
bool paintopPopupDetached(bool defaultValue = false) const;
void setPaintopPopupDetached(bool detached) const;
QString pressureTabletCurve(bool defaultValue = false) const;
void setPressureTabletCurve(const QString& curveString) const;
bool useWin8PointerInput(bool defaultValue = false) const;
void setUseWin8PointerInput(bool value) const;
qreal vastScrolling(bool defaultValue = false) const;
void setVastScrolling(const qreal factor) const;
int presetChooserViewMode(bool defaultValue = false) const;
void setPresetChooserViewMode(const int mode) const;
int presetIconSize(bool defaultValue = false) const;
void setPresetIconSize(const int value) const;
bool firstRun(bool defaultValue = false) const;
void setFirstRun(const bool firstRun) const;
bool clicklessSpacePan(bool defaultValue = false) const;
void setClicklessSpacePan(const bool toggle) const;
int horizontalSplitLines(bool defaultValue = false) const;
void setHorizontalSplitLines(const int numberLines) const;
int verticalSplitLines(bool defaultValue = false) const;
void setVerticalSplitLines(const int numberLines) const;
bool hideDockersFullscreen(bool defaultValue = false) const;
void setHideDockersFullscreen(const bool value) const;
bool showDockers(bool defaultValue = false) const;
void setShowDockers(const bool value) const;
bool showStatusBar(bool defaultValue = false) const;
void setShowStatusBar(const bool value) const;
bool hideMenuFullscreen(bool defaultValue = false) const;
void setHideMenuFullscreen(const bool value) const;
bool hideScrollbarsFullscreen(bool defaultValue = false) const;
void setHideScrollbarsFullscreen(const bool value) const;
bool hideStatusbarFullscreen(bool defaultValue = false) const;
void setHideStatusbarFullscreen(const bool value) const;
bool hideTitlebarFullscreen(bool defaultValue = false) const;
void setHideTitlebarFullscreen(const bool value) const;
bool hideToolbarFullscreen(bool defaultValue = false) const;
void setHideToolbarFullscreen(const bool value) const;
bool fullscreenMode(bool defaultValue = false) const;
void setFullscreenMode(const bool value) const;
QStringList favoriteCompositeOps(bool defaultValue = false) const;
void setFavoriteCompositeOps(const QStringList& compositeOps) const;
QString exportConfiguration(const QString &filterId, bool defaultValue = false) const;
void setExportConfiguration(const QString &filterId, KisPropertiesConfigurationSP properties) const;
QString importConfiguration(const QString &filterId, bool defaultValue = false) const;
void setImportConfiguration(const QString &filterId, KisPropertiesConfigurationSP properties) const;
bool useOcio(bool defaultValue = false) const;
void setUseOcio(bool useOCIO) const;
int favoritePresets(bool defaultValue = false) const;
void setFavoritePresets(const int value);
bool levelOfDetailEnabled(bool defaultValue = false) const;
void setLevelOfDetailEnabled(bool value);
enum OcioColorManagementMode {
INTERNAL = 0,
OCIO_CONFIG,
OCIO_ENVIRONMENT
};
OcioColorManagementMode ocioColorManagementMode(bool defaultValue = false) const;
void setOcioColorManagementMode(OcioColorManagementMode mode) const;
QString ocioConfigurationPath(bool defaultValue = false) const;
void setOcioConfigurationPath(const QString &path) const;
QString ocioLutPath(bool defaultValue = false) const;
void setOcioLutPath(const QString &path) const;
int ocioLutEdgeSize(bool defaultValue = false) const;
void setOcioLutEdgeSize(int value);
bool ocioLockColorVisualRepresentation(bool defaultValue = false) const;
void setOcioLockColorVisualRepresentation(bool value);
bool useSystemMonitorProfile(bool defaultValue = false) const;
void setUseSystemMonitorProfile(bool _useSystemMonitorProfile) const;
QString defaultPalette(bool defaultValue = false) const;
void setDefaultPalette(const QString& name) const;
QString toolbarSlider(int sliderNumber, bool defaultValue = false) const;
void setToolbarSlider(int sliderNumber, const QString &slider);
int layerThumbnailSize(bool defaultValue = false) const;
void setLayerThumbnailSize(int size);
bool sliderLabels(bool defaultValue = false) const;
void setSliderLabels(bool enabled);
QString currentInputProfile(bool defaultValue = false) const;
void setCurrentInputProfile(const QString& name);
bool presetStripVisible(bool defaultValue = false) const;
void setPresetStripVisible(bool visible);
bool scratchpadVisible(bool defaultValue = false) const;
void setScratchpadVisible(bool visible);
bool showSingleChannelAsColor(bool defaultValue = false) const;
void setShowSingleChannelAsColor(bool asColor);
bool hidePopups(bool defaultValue = false) const;
void setHidePopups(bool hidepopups);
int numDefaultLayers(bool defaultValue = false) const;
void setNumDefaultLayers(int num);
quint8 defaultBackgroundOpacity(bool defaultValue = false) const;
void setDefaultBackgroundOpacity(quint8 value);
QColor defaultBackgroundColor(bool defaultValue = false) const;
void setDefaultBackgroundColor(QColor value);
enum BackgroundStyle {
- LAYER = 0,
- PROJECTION = 1
+ RASTER_LAYER = 0,
+ CANVAS_COLOR = 1,
+ FILL_LAYER = 2
};
BackgroundStyle defaultBackgroundStyle(bool defaultValue = false) const;
void setDefaultBackgroundStyle(BackgroundStyle value);
int lineSmoothingType(bool defaultValue = false) const;
void setLineSmoothingType(int value);
qreal lineSmoothingDistance(bool defaultValue = false) const;
void setLineSmoothingDistance(qreal value);
qreal lineSmoothingTailAggressiveness(bool defaultValue = false) const;
void setLineSmoothingTailAggressiveness(qreal value);
bool lineSmoothingSmoothPressure(bool defaultValue = false) const;
void setLineSmoothingSmoothPressure(bool value);
bool lineSmoothingScalableDistance(bool defaultValue = false) const;
void setLineSmoothingScalableDistance(bool value);
qreal lineSmoothingDelayDistance(bool defaultValue = false) const;
void setLineSmoothingDelayDistance(qreal value);
bool lineSmoothingUseDelayDistance(bool defaultValue = false) const;
void setLineSmoothingUseDelayDistance(bool value);
bool lineSmoothingFinishStabilizedCurve(bool defaultValue = false) const;
void setLineSmoothingFinishStabilizedCurve(bool value);
bool lineSmoothingStabilizeSensors(bool defaultValue = false) const;
void setLineSmoothingStabilizeSensors(bool value);
int tabletEventsDelay(bool defaultValue = false) const;
void setTabletEventsDelay(int value);
bool trackTabletEventLatency(bool defaultValue = false) const;
void setTrackTabletEventLatency(bool value);
bool testingAcceptCompressedTabletEvents(bool defaultValue = false) const;
void setTestingAcceptCompressedTabletEvents(bool value);
bool shouldEatDriverShortcuts(bool defaultValue = false) const;
bool testingCompressBrushEvents(bool defaultValue = false) const;
void setTestingCompressBrushEvents(bool value);
const KoColorSpace* customColorSelectorColorSpace(bool defaultValue = false) const;
void setCustomColorSelectorColorSpace(const KoColorSpace *cs);
bool useDirtyPresets(bool defaultValue = false) const;
void setUseDirtyPresets(bool value);
bool useEraserBrushSize(bool defaultValue = false) const;
void setUseEraserBrushSize(bool value);
bool useEraserBrushOpacity(bool defaultValue = false) const;
void setUseEraserBrushOpacity(bool value);
QColor getMDIBackgroundColor(bool defaultValue = false) const;
void setMDIBackgroundColor(const QColor & v) const;
QString getMDIBackgroundImage(bool defaultValue = false) const;
void setMDIBackgroundImage(const QString & fileName) const;
int workaroundX11SmoothPressureSteps(bool defaultValue = false) const;
bool showCanvasMessages(bool defaultValue = false) const;
void setShowCanvasMessages(bool show);
bool compressKra(bool defaultValue = false) const;
void setCompressKra(bool compress);
bool toolOptionsInDocker(bool defaultValue = false) const;
void setToolOptionsInDocker(bool inDocker);
bool kineticScrollingEnabled(bool defaultValue = false) const;
void setKineticScrollingEnabled(bool enabled);
int kineticScrollingGesture(bool defaultValue = false) const;
void setKineticScrollingGesture(int kineticScroll);
int kineticScrollingSensitivity(bool defaultValue = false) const;
void setKineticScrollingSensitivity(int sensitivity);
bool kineticScrollingHiddenScrollbars(bool defaultValue = false) const;
void setKineticScrollingHideScrollbars(bool scrollbar);
void setEnableOpenGLFramerateLogging(bool value) const;
bool enableOpenGLFramerateLogging(bool defaultValue = false) const;
void setEnableBrushSpeedLogging(bool value) const;
bool enableBrushSpeedLogging(bool defaultValue = false) const;
void setEnableAmdVectorizationWorkaround(bool value);
bool enableAmdVectorizationWorkaround(bool defaultValue = false) const;
bool animationDropFrames(bool defaultValue = false) const;
void setAnimationDropFrames(bool value);
int scrubbingUpdatesDelay(bool defaultValue = false) const;
void setScrubbingUpdatesDelay(int value);
int scrubbingAudioUpdatesDelay(bool defaultValue = false) const;
void setScrubbingAudioUpdatesDelay(int value);
int audioOffsetTolerance(bool defaultValue = false) const;
void setAudioOffsetTolerance(int value);
bool switchSelectionCtrlAlt(bool defaultValue = false) const;
void setSwitchSelectionCtrlAlt(bool value);
bool convertToImageColorspaceOnImport(bool defaultValue = false) const;
void setConvertToImageColorspaceOnImport(bool value);
int stabilizerSampleSize(bool defaultValue = false) const;
void setStabilizerSampleSize(int value);
bool stabilizerDelayedPaint(bool defaultValue = false) const;
void setStabilizerDelayedPaint(bool value);
QString customFFMpegPath(bool defaultValue = false) const;
void setCustomFFMpegPath(const QString &value) const;
bool showBrushHud(bool defaultValue = false) const;
void setShowBrushHud(bool value);
QString brushHudSetting(bool defaultValue = false) const;
void setBrushHudSetting(const QString &value) const;
bool calculateAnimationCacheInBackground(bool defaultValue = false) const;
void setCalculateAnimationCacheInBackground(bool value);
QColor defaultAssistantsColor(bool defaultValue = false) const;
void setDefaultAssistantsColor(const QColor &color) const;
bool autoSmoothBezierCurves(bool defaultValue = false) const;
void setAutoSmoothBezierCurves(bool value);
bool activateTransformToolAfterPaste(bool defaultValue = false) const;
void setActivateTransformToolAfterPaste(bool value);
template
void writeEntry(const QString& name, const T& value) {
m_cfg.writeEntry(name, value);
}
template
void writeList(const QString& name, const QList& value) {
m_cfg.writeEntry(name, value);
}
template
T readEntry(const QString& name, const T& defaultValue=T()) {
return m_cfg.readEntry(name, defaultValue);
}
template
QList readList(const QString& name, const QList& defaultValue=QList()) {
return m_cfg.readEntry(name, defaultValue);
}
/// get the profile the color management system has stored for the given screen
static const KoColorProfile* getScreenProfile(int screen);
private:
KisConfig(const KisConfig&);
KisConfig& operator=(const KisConfig&) const;
private:
mutable KConfigGroup m_cfg;
bool m_readOnly;
};
#endif // KIS_CONFIG_H_
diff --git a/libs/ui/kis_layer_manager.cc b/libs/ui/kis_layer_manager.cc
index c34be1e3f9..a03d4c69a2 100644
--- a/libs/ui/kis_layer_manager.cc
+++ b/libs/ui/kis_layer_manager.cc
@@ -1,967 +1,971 @@
/*
* Copyright (C) 2006 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_layer_manager.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_config.h"
#include "kis_cursor.h"
#include "dialogs/kis_dlg_adj_layer_props.h"
#include "dialogs/kis_dlg_adjustment_layer.h"
#include "dialogs/kis_dlg_layer_properties.h"
#include "dialogs/kis_dlg_generator_layer.h"
#include "dialogs/kis_dlg_file_layer.h"
#include "dialogs/kis_dlg_layer_style.h"
#include "kis_filter_manager.h"
#include "kis_node_visitor.h"
#include "kis_paint_layer.h"
#include "commands/kis_image_commands.h"
#include "commands/kis_node_commands.h"
#include "kis_change_file_layer_command.h"
#include "kis_canvas_resource_provider.h"
#include "kis_selection_manager.h"
#include "kis_statusbar.h"
#include "KisViewManager.h"
#include "kis_zoom_manager.h"
#include "canvas/kis_canvas2.h"
#include "widgets/kis_meta_data_merge_strategy_chooser_widget.h"
#include "widgets/kis_wdg_generator.h"
#include "kis_progress_widget.h"
#include "kis_node_commands_adapter.h"
#include "kis_node_manager.h"
#include "kis_action.h"
#include "kis_action_manager.h"
#include "kis_raster_keyframe_channel.h"
#include "KisImportExportManager.h"
#include "kis_signal_compressor_with_param.h"
#include "kis_abstract_projection_plane.h"
#include "commands_new/kis_set_layer_style_command.h"
#include "kis_post_execution_undo_adapter.h"
#include "kis_selection_mask.h"
#include "kis_layer_utils.h"
#include "lazybrush/kis_colorize_mask.h"
#include "KisSaveGroupVisitor.h"
KisLayerManager::KisLayerManager(KisViewManager * view)
: m_view(view)
, m_imageView(0)
, m_imageFlatten(0)
, m_imageMergeLayer(0)
, m_groupLayersSave(0)
, m_imageResizeToLayer(0)
, m_flattenLayer(0)
, m_rasterizeLayer(0)
, m_commandsAdapter(new KisNodeCommandsAdapter(m_view))
, m_layerStyle(0)
{
}
KisLayerManager::~KisLayerManager()
{
delete m_commandsAdapter;
}
void KisLayerManager::setView(QPointerview)
{
m_imageView = view;
}
KisLayerSP KisLayerManager::activeLayer()
{
if (m_imageView) {
return m_imageView->currentLayer();
}
return 0;
}
KisPaintDeviceSP KisLayerManager::activeDevice()
{
if (activeLayer()) {
return activeLayer()->paintDevice();
}
return 0;
}
void KisLayerManager::activateLayer(KisLayerSP layer)
{
if (m_imageView) {
emit sigLayerActivated(layer);
layersUpdated();
if (layer) {
m_view->resourceProvider()->slotNodeActivated(layer.data());
}
}
}
void KisLayerManager::setup(KisActionManager* actionManager)
{
m_imageFlatten = actionManager->createAction("flatten_image");
connect(m_imageFlatten, SIGNAL(triggered()), this, SLOT(flattenImage()));
m_imageMergeLayer = actionManager->createAction("merge_layer");
connect(m_imageMergeLayer, SIGNAL(triggered()), this, SLOT(mergeLayer()));
m_flattenLayer = actionManager->createAction("flatten_layer");
connect(m_flattenLayer, SIGNAL(triggered()), this, SLOT(flattenLayer()));
m_rasterizeLayer = actionManager->createAction("rasterize_layer");
connect(m_rasterizeLayer, SIGNAL(triggered()), this, SLOT(rasterizeLayer()));
m_groupLayersSave = actionManager->createAction("save_groups_as_images");
connect(m_groupLayersSave, SIGNAL(triggered()), this, SLOT(saveGroupLayers()));
m_convertGroupAnimated = actionManager->createAction("convert_group_to_animated");
connect(m_convertGroupAnimated, SIGNAL(triggered()), this, SLOT(convertGroupToAnimated()));
m_imageResizeToLayer = actionManager->createAction("resizeimagetolayer");
connect(m_imageResizeToLayer, SIGNAL(triggered()), this, SLOT(imageResizeToActiveLayer()));
KisAction *action = actionManager->createAction("trim_to_image");
connect(action, SIGNAL(triggered()), this, SLOT(trimToImage()));
m_layerStyle = actionManager->createAction("layer_style");
connect(m_layerStyle, SIGNAL(triggered()), this, SLOT(layerStyle()));
}
void KisLayerManager::updateGUI()
{
KisImageSP image = m_view->image();
KisLayerSP layer = activeLayer();
const bool isGroupLayer = layer && layer->inherits("KisGroupLayer");
m_imageMergeLayer->setText(
isGroupLayer ?
i18nc("@action:inmenu", "Merge Group") :
i18nc("@action:inmenu", "Merge with Layer Below"));
m_flattenLayer->setVisible(!isGroupLayer);
if (m_view->statusBar())
m_view->statusBar()->setProfile(image);
}
void KisLayerManager::imageResizeToActiveLayer()
{
KisLayerSP layer;
KisImageWSP image = m_view->image();
if (image && (layer = activeLayer())) {
QRect cropRect = layer->projection()->nonDefaultPixelArea();
if (!cropRect.isEmpty()) {
image->cropImage(cropRect);
} else {
m_view->showFloatingMessage(
i18nc("floating message in layer manager",
"Layer is empty "),
QIcon(), 2000, KisFloatingMessage::Low);
}
}
}
void KisLayerManager::trimToImage()
{
KisImageWSP image = m_view->image();
if (image) {
image->cropImage(image->bounds());
}
}
void KisLayerManager::layerProperties()
{
if (!m_view) return;
if (!m_view->document()) return;
KisLayerSP layer = activeLayer();
if (!layer) return;
QList selectedNodes = m_view->nodeManager()->selectedNodes();
const bool multipleLayersSelected = selectedNodes.size() > 1;
KisAdjustmentLayerSP alayer = KisAdjustmentLayerSP(dynamic_cast(layer.data()));
KisGeneratorLayerSP glayer = KisGeneratorLayerSP(dynamic_cast(layer.data()));
KisFileLayerSP flayer = KisFileLayerSP(dynamic_cast(layer.data()));
if (alayer && !multipleLayersSelected) {
KisPaintDeviceSP dev = alayer->projection();
KisDlgAdjLayerProps dlg(alayer, alayer.data(), dev, m_view, alayer->filter().data(), alayer->name(), i18n("Filter Layer Properties"), m_view->mainWindow(), "dlgadjlayerprops");
dlg.resize(dlg.minimumSizeHint());
KisFilterConfigurationSP configBefore(alayer->filter());
KIS_ASSERT_RECOVER_RETURN(configBefore);
QString xmlBefore = configBefore->toXML();
if (dlg.exec() == QDialog::Accepted) {
alayer->setName(dlg.layerName());
KisFilterConfigurationSP configAfter(dlg.filterConfiguration());
Q_ASSERT(configAfter);
QString xmlAfter = configAfter->toXML();
if(xmlBefore != xmlAfter) {
KisChangeFilterCmd *cmd
= new KisChangeFilterCmd(alayer,
configBefore->name(),
xmlBefore,
configAfter->name(),
xmlAfter,
false);
// FIXME: check whether is needed
cmd->redo();
m_view->undoAdapter()->addCommand(cmd);
m_view->document()->setModified(true);
}
}
else {
KisFilterConfigurationSP configAfter(dlg.filterConfiguration());
Q_ASSERT(configAfter);
QString xmlAfter = configAfter->toXML();
if(xmlBefore != xmlAfter) {
alayer->setFilter(KisFilterRegistry::instance()->cloneConfiguration(configBefore.data()));
alayer->setDirty();
}
}
}
else if (glayer && !multipleLayersSelected) {
KisDlgGeneratorLayer dlg(glayer->name(), m_view, m_view->mainWindow());
dlg.setCaption(i18n("Fill Layer Properties"));
KisFilterConfigurationSP configBefore(glayer->filter());
Q_ASSERT(configBefore);
QString xmlBefore = configBefore->toXML();
dlg.setConfiguration(configBefore.data());
dlg.resize(dlg.minimumSizeHint());
if (dlg.exec() == QDialog::Accepted) {
glayer->setName(dlg.layerName());
KisFilterConfigurationSP configAfter(dlg.configuration());
Q_ASSERT(configAfter);
QString xmlAfter = configAfter->toXML();
if(xmlBefore != xmlAfter) {
KisChangeFilterCmd *cmd
= new KisChangeFilterCmd(glayer,
configBefore->name(),
xmlBefore,
configAfter->name(),
xmlAfter,
true);
// FIXME: check whether is needed
cmd->redo();
m_view->undoAdapter()->addCommand(cmd);
m_view->document()->setModified(true);
}
}
} else if (flayer && !multipleLayersSelected){
QString basePath = QFileInfo(m_view->document()->url().toLocalFile()).absolutePath();
QString fileNameOld = flayer->fileName();
KisFileLayer::ScalingMethod scalingMethodOld = flayer->scalingMethod();
KisDlgFileLayer dlg(basePath, flayer->name(), m_view->mainWindow());
dlg.setCaption(i18n("File Layer Properties"));
dlg.setFileName(fileNameOld);
dlg.setScalingMethod(scalingMethodOld);
if (dlg.exec() == QDialog::Accepted) {
const QString fileNameNew = dlg.fileName();
KisFileLayer::ScalingMethod scalingMethodNew = dlg.scaleToImageResolution();
if(fileNameNew.isEmpty()){
QMessageBox::critical(m_view->mainWindow(), i18nc("@title:window", "Krita"), i18n("No file name specified"));
return;
}
flayer->setName(dlg.layerName());
if (fileNameOld!= fileNameNew || scalingMethodOld != scalingMethodNew) {
KisChangeFileLayerCmd *cmd
= new KisChangeFileLayerCmd(flayer,
basePath,
fileNameOld,
scalingMethodOld,
basePath,
fileNameNew,
scalingMethodNew);
m_view->undoAdapter()->addCommand(cmd);
}
}
} else { // If layer == normal painting layer, vector layer, or group layer
QList selectedNodes = m_view->nodeManager()->selectedNodes();
KisDlgLayerProperties *dialog = new KisDlgLayerProperties(selectedNodes, m_view);
dialog->resize(dialog->minimumSizeHint());
dialog->setAttribute(Qt::WA_DeleteOnClose);
Qt::WindowFlags flags = dialog->windowFlags();
dialog->setWindowFlags(flags | Qt::WindowStaysOnTopHint | Qt::Dialog);
dialog->show();
}
}
void KisLayerManager::convertNodeToPaintLayer(KisNodeSP source)
{
KisImageWSP image = m_view->image();
if (!image) return;
KisLayer *srcLayer = qobject_cast(source.data());
if (srcLayer && (srcLayer->inherits("KisGroupLayer") || srcLayer->layerStyle() || srcLayer->childCount() > 0)) {
image->flattenLayer(srcLayer);
return;
}
KisPaintDeviceSP srcDevice =
source->paintDevice() ? source->projection() : source->original();
bool putBehind = false;
QString newCompositeOp = source->compositeOpId();
KisColorizeMask *colorizeMask = dynamic_cast(source.data());
if (colorizeMask) {
srcDevice = colorizeMask->coloringProjection();
putBehind = colorizeMask->compositeOpId() == COMPOSITE_BEHIND;
if (putBehind) {
newCompositeOp = COMPOSITE_OVER;
}
}
if (!srcDevice) return;
KisPaintDeviceSP clone;
if (*srcDevice->colorSpace() !=
*srcDevice->compositionSourceColorSpace()) {
clone = new KisPaintDevice(srcDevice->compositionSourceColorSpace());
QRect rc(srcDevice->extent());
KisPainter::copyAreaOptimized(rc.topLeft(), srcDevice, clone, rc);
} else {
clone = new KisPaintDevice(*srcDevice);
}
KisLayerSP layer = new KisPaintLayer(image,
source->name(),
source->opacity(),
clone);
layer->setCompositeOpId(newCompositeOp);
KisNodeSP parent = source->parent();
KisNodeSP above = source->prevSibling();
while (parent && !parent->allowAsChild(layer)) {
above = above ? above->parent() : source->parent();
parent = above ? above->parent() : 0;
}
if (putBehind && above == source->parent()) {
above = above->prevSibling();
}
m_commandsAdapter->beginMacro(kundo2_i18n("Convert to a Paint Layer"));
m_commandsAdapter->removeNode(source);
m_commandsAdapter->addNode(layer, parent, above);
m_commandsAdapter->endMacro();
}
void KisLayerManager::convertGroupToAnimated()
{
KisGroupLayerSP group = dynamic_cast(activeLayer().data());
if (group.isNull()) return;
KisPaintLayerSP animatedLayer = new KisPaintLayer(m_view->image(), group->name(), OPACITY_OPAQUE_U8);
animatedLayer->enableAnimation();
KisRasterKeyframeChannel *contentChannel = dynamic_cast(
animatedLayer->getKeyframeChannel(KisKeyframeChannel::Content.id(), true));
KIS_ASSERT_RECOVER_RETURN(contentChannel);
KisNodeSP child = group->firstChild();
int time = 0;
while (child) {
contentChannel->importFrame(time, child->projection(), NULL);
time++;
child = child->nextSibling();
}
m_commandsAdapter->beginMacro(kundo2_i18n("Convert to an animated layer"));
m_commandsAdapter->addNode(animatedLayer, group->parent(), group);
m_commandsAdapter->removeNode(group);
m_commandsAdapter->endMacro();
}
void KisLayerManager::convertLayerToFileLayer(KisNodeSP source)
{
KisImageSP image = m_view->image();
if (!image) return;
QStringList listMimeFilter = KisImportExportManager::supportedMimeTypes(KisImportExportManager::Export);
KoDialog dlg;
QWidget *page = new QWidget(&dlg);
dlg.setMainWidget(page);
QBoxLayout *layout = new QVBoxLayout(page);
dlg.setWindowTitle(i18n("Save layers to..."));
QLabel *lbl = new QLabel(i18n("Choose the location where the layer will be saved to. The new file layer will then reference this location."));
lbl->setWordWrap(true);
layout->addWidget(lbl);
KisFileNameRequester *urlRequester = new KisFileNameRequester(page);
urlRequester->setMode(KoFileDialog::SaveFile);
urlRequester->setMimeTypeFilters(listMimeFilter);
urlRequester->setFileName(m_view->document()->url().toLocalFile());
if (m_view->document()->url().isLocalFile()) {
QFileInfo location = QFileInfo(m_view->document()->url().toLocalFile()).baseName();
location.setFile(location.dir(), location.baseName() + "_" + source->name() + ".png");
urlRequester->setFileName(location.absoluteFilePath());
}
else {
const QFileInfo location = QFileInfo(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
const QString proposedFileName = QDir(location.absoluteFilePath()).absoluteFilePath(source->name() + ".png");
urlRequester->setFileName(proposedFileName);
}
// We don't want .kra files as file layers, Krita cannot handle the load.
QStringList mimes = KisImportExportManager::supportedMimeTypes(KisImportExportManager::Export);
int i = mimes.indexOf(KIS_MIME_TYPE);
if (i >= 0 && i < mimes.size()) {
mimes.removeAt(i);
}
urlRequester->setMimeTypeFilters(mimes);
layout->addWidget(urlRequester);
if (!dlg.exec()) return;
QString path = urlRequester->fileName();
if (path.isEmpty()) return;
QFileInfo f(path);
QString mimeType= KisMimeDatabase::mimeTypeForFile(f.fileName());
if (mimeType.isEmpty()) {
mimeType = "image/png";
}
QScopedPointer doc(KisPart::instance()->createDocument());
QRect bounds = source->exactBounds();
KisImageSP dst = new KisImage(doc->createUndoStore(),
image->width(),
image->height(),
image->projection()->compositionSourceColorSpace(),
source->name());
dst->setResolution(image->xRes(), image->yRes());
doc->setFileBatchMode(false);
doc->setCurrentImage(dst);
KisNodeSP node = source->clone();
dst->addNode(node);
dst->initialRefreshGraph();
dst->cropImage(bounds);
dst->waitForDone();
bool r = doc->exportDocumentSync(QUrl::fromLocalFile(path), mimeType.toLatin1());
if (!r) {
qWarning() << "Converting layer to file layer. path:"<< path << "gave errors" << doc->errorMessage();
} else {
QString basePath = QFileInfo(m_view->document()->url().toLocalFile()).absolutePath();
QString relativePath = QDir(basePath).relativeFilePath(path);
KisFileLayer *fileLayer = new KisFileLayer(image, basePath, relativePath, KisFileLayer::None, source->name(), OPACITY_OPAQUE_U8);
fileLayer->setX(bounds.x());
fileLayer->setY(bounds.y());
KisNodeSP dstParent = source->parent();
KisNodeSP dstAboveThis = source->prevSibling();
m_commandsAdapter->beginMacro(kundo2_i18n("Convert to a file layer"));
m_commandsAdapter->removeNode(source);
m_commandsAdapter->addNode(fileLayer, dstParent, dstAboveThis);
m_commandsAdapter->endMacro();
}
doc->closeUrl(false);
}
void KisLayerManager::adjustLayerPosition(KisNodeSP node, KisNodeSP activeNode, KisNodeSP &parent, KisNodeSP &above)
{
Q_ASSERT(activeNode);
parent = activeNode;
above = parent->lastChild();
while (parent &&
(!parent->allowAsChild(node) || parent->userLocked())) {
above = parent;
parent = parent->parent();
}
if (!parent) {
warnKrita << "KisLayerManager::adjustLayerPosition:"
<< "No node accepted newly created node";
parent = m_view->image()->root();
above = parent->lastChild();
}
}
void KisLayerManager::addLayerCommon(KisNodeSP activeNode, KisNodeSP layer, bool updateImage)
{
KisNodeSP parent;
KisNodeSP above;
adjustLayerPosition(layer, activeNode, parent, above);
KisGroupLayer *group = dynamic_cast(parent.data());
const bool parentForceUpdate = group && !group->projectionIsValid();
updateImage |= parentForceUpdate;
m_commandsAdapter->addNode(layer, parent, above, updateImage, updateImage);
}
KisLayerSP KisLayerManager::addPaintLayer(KisNodeSP activeNode)
{
KisLayerSP layer = KisLayerUtils::constructDefaultLayer(m_view->image());
addLayerCommon(activeNode, layer, false);
return layer;
}
KisNodeSP KisLayerManager::addGroupLayer(KisNodeSP activeNode)
{
KisImageWSP image = m_view->image();
KisGroupLayerSP group = new KisGroupLayer(image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8);
addLayerCommon(activeNode, group, false);
return group;
}
KisNodeSP KisLayerManager::addCloneLayer(KisNodeSP activeNode)
{
KisImageWSP image = m_view->image();
KisNodeSP node = new KisCloneLayer(activeLayer(), image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8);
addLayerCommon(activeNode, node);
return node;
}
KisNodeSP KisLayerManager::addShapeLayer(KisNodeSP activeNode)
{
if (!m_view) return 0;
if (!m_view->document()) return 0;
KisImageWSP image = m_view->image();
KisShapeLayerSP layer = new KisShapeLayer(m_view->document()->shapeController(), image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8);
addLayerCommon(activeNode, layer, false);
return layer;
}
KisNodeSP KisLayerManager::addAdjustmentLayer(KisNodeSP activeNode)
{
KisImageWSP image = m_view->image();
KisSelectionSP selection = m_view->selection();
KisAdjustmentLayerSP adjl = addAdjustmentLayer(activeNode, QString(), 0, selection);
image->refreshGraph();
KisPaintDeviceSP previewDevice = new KisPaintDevice(*adjl->original());
KisDlgAdjustmentLayer dlg(adjl, adjl.data(), previewDevice, image->nextLayerName(), i18n("New Filter Layer"), m_view);
dlg.resize(dlg.minimumSizeHint());
// ensure that the device may be free'd by the dialog
// when it is not needed anymore
previewDevice = 0;
if (dlg.exec() != QDialog::Accepted || adjl->filter().isNull()) {
// XXX: add messagebox warning if there's no filter set!
m_commandsAdapter->undoLastCommand();
} else {
adjl->setName(dlg.layerName());
}
return adjl;
}
KisAdjustmentLayerSP KisLayerManager::addAdjustmentLayer(KisNodeSP activeNode, const QString & name,
KisFilterConfigurationSP filter, KisSelectionSP selection)
{
KisImageWSP image = m_view->image();
KisAdjustmentLayerSP layer = new KisAdjustmentLayer(image, name, filter, selection);
addLayerCommon(activeNode, layer);
return layer;
}
KisNodeSP KisLayerManager::addGeneratorLayer(KisNodeSP activeNode)
{
KisImageWSP image = m_view->image();
+ QColor currentForeground = m_view->resourceProvider()->fgColor().toQColor();
KisDlgGeneratorLayer dlg(image->nextLayerName(), m_view, m_view->mainWindow());
- dlg.resize(dlg.minimumSizeHint());
+ KisFilterConfigurationSP defaultConfig = dlg.configuration();
+ defaultConfig->setProperty("color", currentForeground);
+ dlg.setConfiguration(defaultConfig);
+ dlg.resize(dlg.minimumSizeHint());
if (dlg.exec() == QDialog::Accepted) {
KisSelectionSP selection = m_view->selection();
KisFilterConfigurationSP generator = dlg.configuration();
QString name = dlg.layerName();
KisNodeSP node = new KisGeneratorLayer(image, name, generator, selection);
addLayerCommon(activeNode, node );
return node;
}
return 0;
}
void KisLayerManager::flattenImage()
{
KisImageSP image = m_view->image();
if (!m_view->blockUntilOperationsFinished(image)) return;
if (image) {
bool doIt = true;
if (image->nHiddenLayers() > 0) {
int answer = QMessageBox::warning(m_view->mainWindow(),
i18nc("@title:window", "Flatten Image"),
i18n("The image contains hidden layers that will be lost. Do you want to flatten the image?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No);
if (answer != QMessageBox::Yes) {
doIt = false;
}
}
if (doIt) {
image->flatten(m_view->activeNode());
}
}
}
inline bool isSelectionMask(KisNodeSP node) {
return dynamic_cast(node.data());
}
bool tryMergeSelectionMasks(KisNodeSP currentNode, KisImageSP image)
{
bool result = false;
KisNodeSP prevNode = currentNode->prevSibling();
if (isSelectionMask(currentNode) &&
prevNode && isSelectionMask(prevNode)) {
QList mergedNodes;
mergedNodes.append(currentNode);
mergedNodes.append(prevNode);
image->mergeMultipleLayers(mergedNodes, currentNode);
result = true;
}
return result;
}
bool tryFlattenGroupLayer(KisNodeSP currentNode, KisImageSP image)
{
bool result = false;
if (currentNode->inherits("KisGroupLayer")) {
KisGroupLayer *layer = qobject_cast(currentNode.data());
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(layer, false);
image->flattenLayer(layer);
result = true;
}
return result;
}
void KisLayerManager::mergeLayer()
{
KisImageSP image = m_view->image();
if (!image) return;
KisLayerSP layer = activeLayer();
if (!layer) return;
if (!m_view->blockUntilOperationsFinished(image)) return;
QList selectedNodes = m_view->nodeManager()->selectedNodes();
if (selectedNodes.size() > 1) {
image->mergeMultipleLayers(selectedNodes, m_view->activeNode());
}
else if (tryMergeSelectionMasks(m_view->activeNode(), image)) {
// already done!
} else if (tryFlattenGroupLayer(m_view->activeNode(), image)) {
// already done!
} else {
if (!layer->prevSibling()) return;
KisLayer *prevLayer = qobject_cast(layer->prevSibling().data());
if (!prevLayer) return;
if (prevLayer->userLocked()) {
m_view->showFloatingMessage(
i18nc("floating message in layer manager",
"Layer is locked "),
QIcon(), 2000, KisFloatingMessage::Low);
}
else if (layer->metaData()->isEmpty() && prevLayer->metaData()->isEmpty()) {
image->mergeDown(layer, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
}
else {
const KisMetaData::MergeStrategy* strategy = KisMetaDataMergeStrategyChooserWidget::showDialog(m_view->mainWindow());
if (!strategy) return;
image->mergeDown(layer, strategy);
}
}
m_view->updateGUI();
}
void KisLayerManager::flattenLayer()
{
KisImageSP image = m_view->image();
if (!image) return;
KisLayerSP layer = activeLayer();
if (!layer) return;
if (!m_view->blockUntilOperationsFinished(image)) return;
convertNodeToPaintLayer(layer);
m_view->updateGUI();
}
void KisLayerManager::rasterizeLayer()
{
KisImageSP image = m_view->image();
if (!image) return;
KisLayerSP layer = activeLayer();
if (!layer) return;
if (!m_view->blockUntilOperationsFinished(image)) return;
KisPaintLayerSP paintLayer = new KisPaintLayer(image, layer->name(), layer->opacity());
KisPainter gc(paintLayer->paintDevice());
QRect rc = layer->projection()->exactBounds();
gc.bitBlt(rc.topLeft(), layer->projection(), rc);
m_commandsAdapter->beginMacro(kundo2_i18n("Rasterize Layer"));
m_commandsAdapter->addNode(paintLayer.data(), layer->parent().data(), layer.data());
int childCount = layer->childCount();
for (int i = 0; i < childCount; i++) {
m_commandsAdapter->moveNode(layer->firstChild(), paintLayer, paintLayer->lastChild());
}
m_commandsAdapter->removeNode(layer);
m_commandsAdapter->endMacro();
updateGUI();
}
void KisLayerManager::layersUpdated()
{
KisLayerSP layer = activeLayer();
if (!layer) return;
m_view->updateGUI();
}
void KisLayerManager::saveGroupLayers()
{
QStringList listMimeFilter = KisImportExportManager::supportedMimeTypes(KisImportExportManager::Export);
KoDialog dlg;
QWidget *page = new QWidget(&dlg);
dlg.setMainWidget(page);
QBoxLayout *layout = new QVBoxLayout(page);
KisFileNameRequester *urlRequester = new KisFileNameRequester(page);
urlRequester->setMode(KoFileDialog::SaveFile);
if (m_view->document()->url().isLocalFile()) {
urlRequester->setStartDir(QFileInfo(m_view->document()->url().toLocalFile()).absolutePath());
}
urlRequester->setMimeTypeFilters(listMimeFilter);
urlRequester->setFileName(m_view->document()->url().toLocalFile());
layout->addWidget(urlRequester);
QCheckBox *chkInvisible = new QCheckBox(i18n("Convert Invisible Groups"), page);
chkInvisible->setChecked(false);
layout->addWidget(chkInvisible);
QCheckBox *chkDepth = new QCheckBox(i18n("Export Only Toplevel Groups"), page);
chkDepth->setChecked(true);
layout->addWidget(chkDepth);
if (!dlg.exec()) return;
QString path = urlRequester->fileName();
if (path.isEmpty()) return;
QFileInfo f(path);
QString mimeType= KisMimeDatabase::mimeTypeForFile(f.fileName(), false);
if (mimeType.isEmpty()) {
mimeType = "image/png";
}
QString extension = KisMimeDatabase::suffixesForMimeType(mimeType).first();
QString basename = f.baseName();
KisImageSP image = m_view->image();
if (!image) return;
KisSaveGroupVisitor v(image, chkInvisible->isChecked(), chkDepth->isChecked(), f.absolutePath(), basename, extension, mimeType);
image->rootLayer()->accept(v);
}
bool KisLayerManager::activeLayerHasSelection()
{
return (activeLayer()->selection() != 0);
}
KisNodeSP KisLayerManager::addFileLayer(KisNodeSP activeNode)
{
QString basePath;
QUrl url = m_view->document()->url();
if (url.isLocalFile()) {
basePath = QFileInfo(url.toLocalFile()).absolutePath();
}
KisImageWSP image = m_view->image();
KisDlgFileLayer dlg(basePath, image->nextLayerName(), m_view->mainWindow());
dlg.resize(dlg.minimumSizeHint());
if (dlg.exec() == QDialog::Accepted) {
QString name = dlg.layerName();
QString fileName = dlg.fileName();
if(fileName.isEmpty()){
QMessageBox::critical(m_view->mainWindow(), i18nc("@title:window", "Krita"), i18n("No file name specified"));
return 0;
}
KisFileLayer::ScalingMethod scalingMethod = dlg.scaleToImageResolution();
KisNodeSP node = new KisFileLayer(image, basePath, fileName, scalingMethod, name, OPACITY_OPAQUE_U8);
addLayerCommon(activeNode, node);
return node;
}
return 0;
}
void updateLayerStyles(KisLayerSP layer, KisDlgLayerStyle *dlg)
{
KisSetLayerStyleCommand::updateLayerStyle(layer, dlg->style()->clone());
}
void KisLayerManager::layerStyle()
{
KisImageWSP image = m_view->image();
if (!image) return;
KisLayerSP layer = activeLayer();
if (!layer) return;
if (!m_view->blockUntilOperationsFinished(image)) return;
KisPSDLayerStyleSP oldStyle;
if (layer->layerStyle()) {
oldStyle = layer->layerStyle()->clone();
}
else {
oldStyle = toQShared(new KisPSDLayerStyle());
}
KisDlgLayerStyle dlg(oldStyle->clone(), m_view->resourceProvider());
std::function updateCall(std::bind(updateLayerStyles, layer, &dlg));
SignalToFunctionProxy proxy(updateCall);
connect(&dlg, SIGNAL(configChanged()), &proxy, SLOT(start()));
if (dlg.exec() == QDialog::Accepted) {
KisPSDLayerStyleSP newStyle = dlg.style();
KUndo2CommandSP command = toQShared(
new KisSetLayerStyleCommand(layer, oldStyle, newStyle));
image->postExecutionUndoAdapter()->addCommand(command);
}
}
diff --git a/libs/ui/layerstyles/WdgGradientOverlay.ui b/libs/ui/layerstyles/WdgGradientOverlay.ui
index 5fb0c6e772..0bf1218d5a 100644
--- a/libs/ui/layerstyles/WdgGradientOverlay.ui
+++ b/libs/ui/layerstyles/WdgGradientOverlay.ui
@@ -1,286 +1,284 @@
WdgGradientOverlay
0
0
- 411
- 294
+ 473
+ 358
-
Gradient Overlay
-
Gradient
-
Ble&nd Mode:
cmbCompositeOp
-
0
0
Set the blend mode for the layer
-
Opac&ity:
intOpacity
-
0
0
10
15
Set the master opacity for the layer
Adjust the transparency of the layer
-
&Gradient:
cmbGradient
-
-
11
0
-
&Reverse
-
St&yle:
cmbStyle
-
-
0
0
-
Linear
-
Radial
-
Angle
-
Reflected
-
Diamond
-
Ali&gn with Layer
-
&Angle:
- dialAngle
+ angleSelector
- -
-
-
-
-
-
- Set the angle of the light source
-
-
- -179
-
-
- 180
-
-
- true
-
-
-
- -
-
-
- -179
-
-
- 180
-
-
-
-
-
- -
+
-
S&cale:
intScale
- -
+
-
0
0
Set size of gradation
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
label_6
intScale
label_9
label_7
label_8
cmbCompositeOp
intOpacity
label_13
label_14
-
Qt::Vertical
20
40
-
- KisIntParseSpinBox
- QSpinBox
-
-
KisSliderSpinBox
QWidget
1
KisCompositeOpComboBox
QComboBox
+
+ KisLayerStyleAngleSelector
+ QWidget
+ KisLayerStyleAngleSelector.h
+ 1
+
KisCmbGradient
QToolButton
diff --git a/libs/ui/layerstyles/WdgSatin.ui b/libs/ui/layerstyles/WdgSatin.ui
index 31d2567bc3..1f40d07151 100644
--- a/libs/ui/layerstyles/WdgSatin.ui
+++ b/libs/ui/layerstyles/WdgSatin.ui
@@ -1,278 +1,260 @@
WdgSatin
0
0
400
- 345
+ 429
-
Satin
-
Structure
-
Ble&nd Mode:
cmbCompositeOp
-
-
0
0
Set the blend mode for the layer
-
...
-
Opaci&ty:
intOpacity
-
0
0
10
15
Set the master opacity for the layer
Adjust the transparency of the layer
- -
-
-
- -
+
-
An&gle:
- dialAngle
+ angleSelector
- -
-
-
-
-
-
- Set the angle of the light source
-
-
- -179
-
-
- 180
-
-
- true
-
-
-
- -
-
-
- -179
-
-
- 180
-
-
-
-
-
-
&Distance:
intDistance
-
0
0
-
S&ize:
intSize
-
0
0
-
Contour:
-
-
Smooth the contour
Anti-aliased
-
&Invert
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
cmbContour
chkAntiAliased
intOpacity
label_13
label_14
label_4
intDistance
intSize
label
label_2
label_6
chkInvert
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
+
Qt::Vertical
20
40
KisColorButton
QPushButton
-
- KisIntParseSpinBox
- QSpinBox
-
-
KisSliderSpinBox
QWidget
1
KisCompositeOpComboBox
QComboBox
+
+ KisLayerStyleAngleSelector
+ QWidget
+ KisLayerStyleAngleSelector.h
+ 1
+
KisCmbContour
QWidget
diff --git a/libs/ui/layerstyles/WdgStroke.ui b/libs/ui/layerstyles/WdgStroke.ui
index bc7a5531b2..761fc4d488 100644
--- a/libs/ui/layerstyles/WdgStroke.ui
+++ b/libs/ui/layerstyles/WdgStroke.ui
@@ -1,440 +1,451 @@
WdgStroke
0
0
- 406
- 642
+ 457
+ 781
-
Stroke
-
Structure
-
S&ize:
intSize
-
0
0
-
Positio&n:
cmbPosition
-
0
0
-
Outside
-
Inside
-
Center
-
&Blend Mode:
cmbCompositeOp
-
0
0
-
Opacit&y:
intOpacity
-
0
0
-
Fill
-
-
Color
-
Gradient
-
Pattern
-
- 0
+ 1
-
Color:
-
...
-
&Gradient:
cmbGradient
-
-