diff --git a/krita/data/CMakeLists.txt b/krita/data/CMakeLists.txt
index 1013dfb365..02fc9bec22 100644
--- a/krita/data/CMakeLists.txt
+++ b/krita/data/CMakeLists.txt
@@ -1,26 +1,27 @@
add_subdirectory( actions )
add_subdirectory( brushes )
add_subdirectory( bundles )
add_subdirectory( patterns )
add_subdirectory( gradients )
add_subdirectory( profiles )
add_subdirectory( templates )
add_subdirectory( workspaces )
add_subdirectory( themes )
add_subdirectory( predefined_image_sizes )
add_subdirectory( input )
add_subdirectory( shortcuts )
add_subdirectory( paintoppresets )
add_subdirectory( palettes )
add_subdirectory( symbols )
add_subdirectory( preset_icons )
add_subdirectory( metadata/schemas )
add_subdirectory( gamutmasks )
+add_subdirectory( windowlayouts )
########### install files ###############
install( FILES
kritarc
DESTINATION ${CONFIG_INSTALL_DIR}
)
diff --git a/krita/data/sessions/Painting with references.ksn b/krita/data/sessions/Painting with references.ksn
new file mode 100644
index 0000000000..f8aaa9534a
--- /dev/null
+++ b/krita/data/sessions/Painting with references.ksn
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+ false
+ file:///C:/samples/Painting.kra
+ QWRuUXl3QUNBQUFBQUFBQUFBQUFBQUFBQTNFQUFBUDZBQUFBQUFBQUFBRC8vLy8rLy8vLy9nQUFBQUVDQUFBQUE1QT0=
+ false
+ 355
+ 502.5
+ 0
+
+ false
+ 1.1937001140250856
+ 2
+
+
+ false
+ file:///C:/samples/References.kra
+ QWRuUXl3QUNBQUFBQUFBQUFBQUFBQUFBQTNFQUFBUzhBQUFBQUFBQUFBRC8vLy8rLy8vLy9nQUFBQUFDQUFBQUE1QT0=
+ false
+ 424
+ 599.5
+ 0
+
+ false
+ 1.424125807677689
+ 2
+
+
diff --git a/krita/data/sessions/Working with references.ksn b/krita/data/sessions/Working with references.ksn
new file mode 100644
index 0000000000..ae1b8c5bc7
--- /dev/null
+++ b/krita/data/sessions/Working with references.ksn
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+ false
+ file:///C:/samples/Painting.kra
+ QWRuUXl3QUNBQUFBQUFBQUFBQUFBQUFBQW1zQUFBUzhBQUFBQUFBQUFBRC8vLy8rLy8vLy9nQUFBQUFDQUFBQUE1QT0=
+ false
+ 34
+ 351.6932373046875
+ 0
+
+ false
+ 59.04048681259156
+ 0
+
+
+ false
+ file:///C:/samples/References.kra
+ QWRuUXl3QUNBQUFBQUFBQUFBQUFBQUFBQTNNQUFBUzhBQUFBQUFBQUFBRC8vLy8rLy8vLy9nQUFBQUVDQUFBQUE1QT0=
+ false
+ 345.6188510879705
+ 432.48219934451225
+ 0
+
+ false
+ 0.9617056710520412
+ 0
+
+
diff --git a/krita/data/windowlayouts/CMakeLists.txt b/krita/data/windowlayouts/CMakeLists.txt
new file mode 100644
index 0000000000..31c5e6aac0
--- /dev/null
+++ b/krita/data/windowlayouts/CMakeLists.txt
@@ -0,0 +1,7 @@
+########### install files ###############
+
+install( FILES
+ "Cockpit (laptop mode).kwl"
+ "Dual screen editing.kwl"
+DESTINATION ${DATA_INSTALL_DIR}/krita/windowlayouts)
+
diff --git a/krita/data/windowlayouts/Cockpit (laptop mode).kwl b/krita/data/windowlayouts/Cockpit (laptop mode).kwl
new file mode 100644
index 0000000000..de54412e91
--- /dev/null
+++ b/krita/data/windowlayouts/Cockpit (laptop mode).kwl
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/krita/data/windowlayouts/Dual screen editing.kwl b/krita/data/windowlayouts/Dual screen editing.kwl
new file mode 100644
index 0000000000..e465eb8a57
--- /dev/null
+++ b/krita/data/windowlayouts/Dual screen editing.kwl
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/ui/KisImportExportManager.cpp b/libs/ui/KisImportExportManager.cpp
index 88b62a3c9e..4dccd9f57b 100644
--- a/libs/ui/KisImportExportManager.cpp
+++ b/libs/ui/KisImportExportManager.cpp
@@ -1,725 +1,726 @@
/*
* Copyright (C) 2016 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 "KisImportExportManager.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 "kis_config.h"
#include "KisImportExportFilter.h"
#include "KisDocument.h"
#include
#include
#include "kis_painter.h"
#include "kis_guides_config.h"
#include "kis_grid_config.h"
#include "kis_popup_button.h"
#include
#include "kis_async_action_feedback.h"
#include "KisReferenceImagesLayer.h"
// static cache for import and export mimetypes
QStringList KisImportExportManager::m_importMimeTypes;
QStringList KisImportExportManager::m_exportMimeTypes;
class Q_DECL_HIDDEN KisImportExportManager::Private
{
public:
KoUpdaterPtr updater;
QString cachedExportFilterMimeType;
QSharedPointer cachedExportFilter;
};
struct KisImportExportManager::ConversionResult {
ConversionResult()
{
}
ConversionResult(const QFuture &futureStatus)
: m_isAsync(true),
m_futureStatus(futureStatus)
{
}
ConversionResult(KisImportExportErrorCode status)
: m_isAsync(false),
m_status(status)
{
}
bool isAsync() const {
return m_isAsync;
}
QFuture futureStatus() const {
// if the result is not async, then it means some failure happened,
// just return a cancelled future
KIS_SAFE_ASSERT_RECOVER_NOOP(m_isAsync || !m_status.isOk());
return m_futureStatus;
}
KisImportExportErrorCode status() const {
return m_status;
}
void setStatus(KisImportExportErrorCode value) {
m_status = value;
}
private:
bool m_isAsync = false;
QFuture m_futureStatus;
KisImportExportErrorCode m_status = ImportExportCodes::InternalError;
};
KisImportExportManager::KisImportExportManager(KisDocument* document)
: m_document(document)
, d(new Private)
{
}
KisImportExportManager::~KisImportExportManager()
{
delete d;
}
KisImportExportErrorCode KisImportExportManager::importDocument(const QString& location, const QString& mimeType)
{
ConversionResult result = convert(Import, location, location, mimeType, false, 0, false);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!result.isAsync(), ImportExportCodes::InternalError);
return result.status();
}
KisImportExportErrorCode KisImportExportManager::exportDocument(const QString& location, const QString& realLocation, const QByteArray& mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
{
ConversionResult result = convert(Export, location, realLocation, mimeType, showWarnings, exportConfiguration, false);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!result.isAsync(), ImportExportCodes::InternalError);
return result.status();
}
QFuture KisImportExportManager::exportDocumentAsyc(const QString &location, const QString &realLocation, const QByteArray &mimeType,
KisImportExportErrorCode &status, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration)
{
ConversionResult result = convert(Export, location, realLocation, mimeType, showWarnings, exportConfiguration, true);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(result.isAsync() ||
!result.status().isOk(), QFuture());
status = result.status();
return result.futureStatus();
}
// The static method to figure out to which parts of the
// graph this mimetype has a connection to.
QStringList KisImportExportManager::supportedMimeTypes(Direction direction)
{
// Find the right mimetype by the extension
QSet mimeTypes;
// mimeTypes << KisDocument::nativeFormatMimeType() << "application/x-krita-paintoppreset" << "image/openraster";
if (direction == KisImportExportManager::Import) {
if (m_importMimeTypes.isEmpty()) {
QListlist = KoJsonTrader::instance()->query("Krita/FileFilter", "");
Q_FOREACH(QPluginLoader *loader, list) {
QJsonObject json = loader->metaData().value("MetaData").toObject();
Q_FOREACH(const QString &mimetype, json.value("X-KDE-Import").toString().split(",", QString::SkipEmptyParts)) {
//qDebug() << "Adding import mimetype" << mimetype << KisMimeDatabase::descriptionForMimeType(mimetype) << "from plugin" << loader;
mimeTypes << mimetype;
}
}
qDeleteAll(list);
m_importMimeTypes = mimeTypes.toList();
}
return m_importMimeTypes;
}
else if (direction == KisImportExportManager::Export) {
if (m_exportMimeTypes.isEmpty()) {
QListlist = KoJsonTrader::instance()->query("Krita/FileFilter", "");
Q_FOREACH(QPluginLoader *loader, list) {
QJsonObject json = loader->metaData().value("MetaData").toObject();
Q_FOREACH(const QString &mimetype, json.value("X-KDE-Export").toString().split(",", QString::SkipEmptyParts)) {
//qDebug() << "Adding export mimetype" << mimetype << KisMimeDatabase::descriptionForMimeType(mimetype) << "from plugin" << loader;
mimeTypes << mimetype;
}
}
qDeleteAll(list);
m_exportMimeTypes = mimeTypes.toList();
}
return m_exportMimeTypes;
}
return QStringList();
}
KisImportExportFilter *KisImportExportManager::filterForMimeType(const QString &mimetype, KisImportExportManager::Direction direction)
{
int weight = -1;
KisImportExportFilter *filter = 0;
QListlist = KoJsonTrader::instance()->query("Krita/FileFilter", "");
Q_FOREACH(QPluginLoader *loader, list) {
QJsonObject json = loader->metaData().value("MetaData").toObject();
QString directionKey = direction == Export ? "X-KDE-Export" : "X-KDE-Import";
if (json.value(directionKey).toString().split(",", QString::SkipEmptyParts).contains(mimetype)) {
KLibFactory *factory = qobject_cast(loader->instance());
if (!factory) {
warnUI << loader->errorString();
continue;
}
QObject* obj = factory->create(0);
if (!obj || !obj->inherits("KisImportExportFilter")) {
delete obj;
continue;
}
KisImportExportFilter *f = qobject_cast(obj);
if (!f) {
delete obj;
continue;
}
int w = json.value("X-KDE-Weight").toInt();
if (w > weight) {
delete filter;
filter = f;
f->setObjectName(loader->fileName());
weight = w;
}
}
}
qDeleteAll(list);
if (filter) {
filter->setMimeType(mimetype);
}
return filter;
}
bool KisImportExportManager::batchMode(void) const
{
return m_document->fileBatchMode();
}
void KisImportExportManager::setUpdater(KoUpdaterPtr updater)
{
d->updater = updater;
}
QString KisImportExportManager::askForAudioFileName(const QString &defaultDir, QWidget *parent)
{
KoFileDialog dialog(parent, KoFileDialog::ImportFiles, "ImportAudio");
if (!defaultDir.isEmpty()) {
dialog.setDefaultDir(defaultDir);
}
QStringList mimeTypes;
mimeTypes << "audio/mpeg";
mimeTypes << "audio/ogg";
mimeTypes << "audio/vorbis";
mimeTypes << "audio/vnd.wave";
mimeTypes << "audio/flac";
dialog.setMimeTypeFilters(mimeTypes);
dialog.setCaption(i18nc("@title:window", "Open Audio"));
return dialog.filename();
}
KisImportExportManager::ConversionResult KisImportExportManager::convert(KisImportExportManager::Direction direction, const QString &location, const QString& realLocation, const QString &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration, bool isAsync)
{
// export configuration is supported for export only
KIS_SAFE_ASSERT_RECOVER_NOOP(direction == Export || !bool(exportConfiguration));
QString typeName = mimeType;
if (typeName.isEmpty()) {
typeName = KisMimeDatabase::mimeTypeForFile(location, direction == KisImportExportManager::Export ? false : true);
}
QSharedPointer filter;
/**
* Fetching a filter from the registry is a really expensive operation,
* because it blocks all the threads. Cache the filter if possible.
*/
if (direction == KisImportExportManager::Export &&
d->cachedExportFilter &&
d->cachedExportFilterMimeType == typeName) {
filter = d->cachedExportFilter;
} else {
filter = toQShared(filterForMimeType(typeName, direction));
if (direction == Export) {
d->cachedExportFilter = filter;
d->cachedExportFilterMimeType = typeName;
}
}
if (!filter) {
return KisImportExportErrorCode(ImportExportCodes::FileFormatIncorrect);
}
filter->setFilename(location);
filter->setRealFilename(realLocation);
filter->setBatchMode(batchMode());
filter->setMimeType(typeName);
if (!d->updater.isNull()) {
// WARNING: The updater is not guaranteed to be persistent! If you ever want
// to add progress reporting to "Save also as .kra", make sure you create
// a separate KoProgressUpdater for that!
// WARNING2: the failsafe completion of the updater happens in the destructor
// the filter.
filter->setUpdater(d->updater);
}
QByteArray from, to;
if (direction == Export) {
from = m_document->nativeFormatMimeType();
to = typeName.toLatin1();
}
else {
from = typeName.toLatin1();
to = m_document->nativeFormatMimeType();
}
KIS_ASSERT_RECOVER_RETURN_VALUE(
direction == Import || direction == Export,
KisImportExportErrorCode(ImportExportCodes::InternalError)); // "bad conversion graph"
ConversionResult result = KisImportExportErrorCode(ImportExportCodes::OK);
if (direction == Import) {
KisUsageLogger::log(QString("Importing %1 to %2. Location: %3. Real location: %4. Batchmode: %5")
.arg(QString::fromLatin1(from))
.arg(QString::fromLatin1(to))
.arg(location)
.arg(realLocation)
.arg(batchMode()));
// async importing is not yet supported!
KIS_SAFE_ASSERT_RECOVER_NOOP(!isAsync);
// FIXME: Dmitry says "this progress reporting code never worked. Initial idea was to implement it his way, but I stopped and didn't finish it"
if (0 && !batchMode()) {
KisAsyncActionFeedback f(i18n("Opening document..."), 0);
result = f.runAction(std::bind(&KisImportExportManager::doImport, this, location, filter));
} else {
result = doImport(location, filter);
}
if (result.status().isOk()) {
KisImageSP image = m_document->image();
KisUsageLogger::log(QString("Loaded image from %1. Size: %2 * %3 pixels, %4 dpi. Color model: %6 %5 (%7). Layers: %8")
.arg(QString::fromLatin1(from))
.arg(image->width())
.arg(image->height())
.arg(image->xRes())
.arg(image->colorSpace()->colorModelId().name())
.arg(image->colorSpace()->colorDepthId().name())
.arg(image->colorSpace()->profile()->name())
.arg(image->nlayers()));
}
else {
KisUsageLogger::log(QString("Failed to load image from %1").arg(QString::fromLatin1(from)));
}
}
else /* if (direction == Export) */ {
if (!exportConfiguration) {
exportConfiguration = filter->lastSavedConfiguration(from, to);
}
if (exportConfiguration) {
fillStaticExportConfigurationProperties(exportConfiguration);
}
bool alsoAsKra = false;
bool askUser = askUserAboutExportConfiguration(filter, exportConfiguration,
from, to,
batchMode(), showWarnings,
&alsoAsKra);
if (!batchMode() && !askUser) {
return KisImportExportErrorCode(ImportExportCodes::Cancelled);
}
KisUsageLogger::log(QString("Converting from %1 to %2. Location: %3. Real location: %4. Batchmode: %5. Configuration: %6")
.arg(QString::fromLatin1(from))
.arg(QString::fromLatin1(to))
.arg(location)
.arg(realLocation)
.arg(batchMode())
.arg(exportConfiguration ? exportConfiguration->toXML() : "none"));
if (isAsync) {
result = QtConcurrent::run(std::bind(&KisImportExportManager::doExport, this, location, filter, exportConfiguration, alsoAsKra));
// we should explicitly report that the exporting has been initiated
result.setStatus(ImportExportCodes::OK);
} else if (!batchMode()) {
KisAsyncActionFeedback f(i18n("Saving document..."), 0);
result = f.runAction(std::bind(&KisImportExportManager::doExport, this, location, filter, exportConfiguration, alsoAsKra));
} else {
result = doExport(location, filter, exportConfiguration, alsoAsKra);
}
if (exportConfiguration && !batchMode() && showWarnings) {
KisConfig(false).setExportConfiguration(typeName, exportConfiguration);
}
}
return result;
}
void KisImportExportManager::fillStaticExportConfigurationProperties(KisPropertiesConfigurationSP exportConfiguration, KisImageSP image)
{
KisPaintDeviceSP dev = image->projection();
const KoColorSpace* cs = dev->colorSpace();
const bool isThereAlpha =
KisPainter::checkDeviceHasTransparency(image->projection());
exportConfiguration->setProperty(KisImportExportFilter::ImageContainsTransparencyTag, isThereAlpha);
exportConfiguration->setProperty(KisImportExportFilter::ColorModelIDTag, cs->colorModelId().id());
exportConfiguration->setProperty(KisImportExportFilter::ColorDepthIDTag, cs->colorDepthId().id());
const bool sRGB =
(cs->profile()->name().contains(QLatin1String("srgb"), Qt::CaseInsensitive) &&
!cs->profile()->name().contains(QLatin1String("g10")));
exportConfiguration->setProperty(KisImportExportFilter::sRGBTag, sRGB);
}
void KisImportExportManager::fillStaticExportConfigurationProperties(KisPropertiesConfigurationSP exportConfiguration)
{
return fillStaticExportConfigurationProperties(exportConfiguration, m_document->image());
}
bool KisImportExportManager::askUserAboutExportConfiguration(
QSharedPointer filter,
KisPropertiesConfigurationSP exportConfiguration,
const QByteArray &from,
const QByteArray &to,
const bool batchMode,
const bool showWarnings,
bool *alsoAsKra)
{
// prevents the animation renderer from running this code
const QString mimeUserDescription = KisMimeDatabase::descriptionForMimeType(to);
QStringList warnings;
QStringList errors;
{
KisPreExportChecker checker;
checker.check(m_document->image(), filter->exportChecks());
warnings = checker.warnings();
errors = checker.errors();
}
KisConfigWidget *wdg = 0;
if (QThread::currentThread() == qApp->thread()) {
wdg = filter->createConfigurationWidget(0, from, to);
KisMainWindow *kisMain = KisPart::instance()->currentMainwindow();
if (wdg && kisMain) {
KisViewManager *manager = kisMain->viewManager();
wdg->setView(manager);
}
}
// Extra checks that cannot be done by the checker, because the checker only has access to the image.
if (!m_document->assistants().isEmpty() && to != m_document->nativeFormatMimeType()) {
warnings.append(i18nc("image conversion warning", "The image contains assistants . The assistants will not be saved."));
}
if (m_document->referenceImagesLayer() && m_document->referenceImagesLayer()->shapeCount() > 0 && to != m_document->nativeFormatMimeType()) {
warnings.append(i18nc("image conversion warning", "The image contains reference images . The reference images will not be saved."));
}
if (m_document->guidesConfig().hasGuides() && to != m_document->nativeFormatMimeType()) {
warnings.append(i18nc("image conversion warning", "The image contains guides . The guides will not be saved."));
}
if (!m_document->gridConfig().isDefault() && to != m_document->nativeFormatMimeType()) {
warnings.append(i18nc("image conversion warning", "The image contains a custom grid configuration . The configuration will not be saved."));
}
if (!batchMode && !errors.isEmpty()) {
QString error = ""
+ i18n("Error: cannot save this image as a %1.", mimeUserDescription)
+ " " + i18n("Reasons:") + "
"
+ "
";
Q_FOREACH(const QString &w, errors) {
error += "\n" + w + " ";
}
error += " ";
QMessageBox::critical(KisPart::instance()->currentMainwindow(), i18nc("@title:window", "Krita: Export Error"), error);
return false;
}
if (!batchMode && (wdg || !warnings.isEmpty())) {
KoDialog dlg;
dlg.setButtons(KoDialog::Ok | KoDialog::Cancel);
dlg.setWindowTitle(mimeUserDescription);
QWidget *page = new QWidget(&dlg);
QVBoxLayout *layout = new QVBoxLayout(page);
if (showWarnings && !warnings.isEmpty()) {
QHBoxLayout *hLayout = new QHBoxLayout();
QLabel *labelWarning = new QLabel();
labelWarning->setPixmap(KisIconUtils::loadIcon("warning").pixmap(32, 32));
hLayout->addWidget(labelWarning);
KisPopupButton *bn = new KisPopupButton(0);
bn->setText(i18nc("Keep the extra space at the end of the sentence, please", "Warning: saving as %1 will lose information from your image. ", mimeUserDescription));
hLayout->addWidget(bn);
layout->addLayout(hLayout);
QTextBrowser *browser = new QTextBrowser();
browser->setMinimumWidth(bn->width());
bn->setPopupWidget(browser);
QString warning = ""
+ i18n("You will lose information when saving this image as a %1.", mimeUserDescription);
if (warnings.size() == 1) {
warning += " " + i18n("Reason:") + "
";
}
else {
warning += " " + i18n("Reasons:") + "
";
}
warning += "
";
Q_FOREACH(const QString &w, warnings) {
warning += "\n" + w + " ";
}
warning += " ";
browser->setHtml(warning);
}
if (wdg) {
QGroupBox *box = new QGroupBox(i18n("Options"));
QVBoxLayout *boxLayout = new QVBoxLayout(box);
wdg->setConfiguration(exportConfiguration);
boxLayout->addWidget(wdg);
layout->addWidget(box);
}
QCheckBox *chkAlsoAsKra = 0;
if (showWarnings && !warnings.isEmpty()) {
chkAlsoAsKra = new QCheckBox(i18n("Also save your image as a Krita file."));
chkAlsoAsKra->setChecked(KisConfig(true).readEntry("AlsoSaveAsKra", false));
layout->addWidget(chkAlsoAsKra);
}
dlg.setMainWidget(page);
dlg.resize(dlg.minimumSize());
if (showWarnings || wdg) {
if (!dlg.exec()) {
return false;
}
}
*alsoAsKra = false;
if (chkAlsoAsKra) {
KisConfig(false).writeEntry("AlsoSaveAsKra", chkAlsoAsKra->isChecked());
*alsoAsKra = chkAlsoAsKra->isChecked();
}
if (wdg) {
*exportConfiguration = *wdg->configuration();
}
}
return true;
}
KisImportExportErrorCode KisImportExportManager::doImport(const QString &location, QSharedPointer filter)
{
QFile file(location);
if (!file.exists()) {
return ImportExportCodes::FileNotExist;
}
if (filter->supportsIO() && !file.open(QFile::ReadOnly)) {
return KisImportExportErrorCode(KisImportExportErrorCannotRead(file.error()));
}
KisImportExportErrorCode status = filter->convert(m_document, &file, KisPropertiesConfigurationSP());
if (file.isOpen()) {
file.close();
}
return status;
}
KisImportExportErrorCode KisImportExportManager::doExport(const QString &location, QSharedPointer filter, KisPropertiesConfigurationSP exportConfiguration, bool alsoAsKra)
{
KisImportExportErrorCode status =
doExportImpl(location, filter, exportConfiguration);
if (alsoAsKra && status.isOk()) {
QString kraLocation = location + ".kra";
QByteArray mime = m_document->nativeFormatMimeType();
QSharedPointer filter(
filterForMimeType(QString::fromLatin1(mime), Export));
KIS_SAFE_ASSERT_RECOVER_NOOP(filter);
if (filter) {
filter->setFilename(kraLocation);
KisPropertiesConfigurationSP kraExportConfiguration =
filter->lastSavedConfiguration(mime, mime);
status = doExportImpl(kraLocation, filter, kraExportConfiguration);
} else {
status = ImportExportCodes::FileFormatIncorrect;
}
}
return status;
}
// Temporary workaround until QTBUG-57299 is fixed.
// 02-10-2019 update: the bug is closed, but we've still seen this issue.
// and without using QSaveFile the issue can still occur
// when QFile::copy fails because Dropbox/Google/OneDrive
// locks the target file.
#ifndef Q_OS_WIN
#define USE_QSAVEFILE
#endif
KisImportExportErrorCode KisImportExportManager::doExportImpl(const QString &location, QSharedPointer filter, KisPropertiesConfigurationSP exportConfiguration)
{
#ifdef USE_QSAVEFILE
QSaveFile file(location);
file.setDirectWriteFallback(true);
if (filter->supportsIO() && !file.open(QFile::WriteOnly)) {
#else
QFileInfo fi(location);
- QTemporaryFile file(fi.absolutePath() + ".XXXXXX.kra");
+ QTemporaryFile file(QDir::tempPath() + "/.XXXXXX.kra");
if (filter->supportsIO() && !file.open()) {
#endif
KisImportExportErrorCannotWrite result(file.error());
#ifdef USE_QSAVEFILE
file.cancelWriting();
#endif
return result;
}
KisImportExportErrorCode status = filter->convert(m_document, &file, exportConfiguration);
if (filter->supportsIO()) {
if (!status.isOk()) {
#ifdef USE_QSAVEFILE
file.cancelWriting();
#endif
} else {
#ifdef USE_QSAVEFILE
if (!file.commit()) {
qWarning() << "Could not commit QSaveFile";
status = KisImportExportErrorCannotWrite(file.error());
}
#else
file.flush();
file.close();
QFile target(location);
if (target.exists()) {
// There should already be a .kra~ backup
target.remove();
}
if (!file.copy(location)) {
file.setAutoRemove(false);
return KisImportExportErrorCannotWrite(file.error());
}
#endif
}
}
// Do some minimal verification
QString verificationResult = filter->verify(location);
if (!verificationResult.isEmpty()) {
status = KisImportExportErrorCode(ImportExportCodes::ErrorWhileWriting);
m_document->setErrorMessage(verificationResult);
}
return status;
}
#include
diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc
index 72c3d72d81..f20cdc259c 100644
--- a/libs/ui/dialogs/kis_dlg_preferences.cc
+++ b/libs/ui/dialogs/kis_dlg_preferences.cc
@@ -1,1782 +1,1785 @@
/*
* preferencesdlg.cc - part of KImageShop
*
* Copyright (c) 1999 Michael Koch
* Copyright (c) 2003-2011 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_preferences.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 "KoID.h"
#include
#include
#include
#include
#include
#include
#include
#include "KisProofingConfiguration.h"
#include "KoColorConversionTransformation.h"
#include "kis_action_registry.h"
#include
#include
#include "kis_clipboard.h"
#include "widgets/kis_cmb_idlist.h"
#include "KoColorSpace.h"
#include "KoColorSpaceRegistry.h"
#include "kis_action_registry.h"
#include "kis_canvas_resource_provider.h"
#include "kis_clipboard.h"
#include "kis_color_manager.h"
#include "kis_config.h"
#include "kis_cursor.h"
#include "kis_image_config.h"
#include "kis_preference_set_registry.h"
#include "widgets/kis_cmb_idlist.h"
#include
#include "kis_file_name_requester.h"
#include
#include
#include
#include "slider_and_spin_box_sync.h"
// for the performance update
#include
#include
#include "input/config/kis_input_configuration_page.h"
#include "input/wintab/drawpile_tablettester/tablettester.h"
#ifdef Q_OS_WIN
#include "config_use_qt_tablet_windows.h"
# ifndef USE_QT_TABLET_WINDOWS
# include
# endif
#include "config-high-dpi-scale-factor-rounding-policy.h"
#endif
struct BackupSuffixValidator : public QValidator {
BackupSuffixValidator(QObject *parent)
: QValidator(parent)
, invalidCharacters(QStringList()
<< "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"
<< "/" << "\\" << ":" << ";" << " ")
{}
~BackupSuffixValidator() override {}
const QStringList invalidCharacters;
State validate(QString &line, int &/*pos*/) const override
{
Q_FOREACH(const QString invalidChar, invalidCharacters) {
if (line.contains(invalidChar)) {
return Invalid;
}
}
return Acceptable;
}
};
GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
: WdgGeneralSettings(_parent, _name)
{
KisConfig cfg(true);
//
// Cursor Tab
//
m_cmbCursorShape->addItem(i18n("No Cursor"));
m_cmbCursorShape->addItem(i18n("Tool Icon"));
m_cmbCursorShape->addItem(i18n("Arrow"));
m_cmbCursorShape->addItem(i18n("Small Circle"));
m_cmbCursorShape->addItem(i18n("Crosshair"));
m_cmbCursorShape->addItem(i18n("Triangle Righthanded"));
m_cmbCursorShape->addItem(i18n("Triangle Lefthanded"));
m_cmbCursorShape->addItem(i18n("Black Pixel"));
m_cmbCursorShape->addItem(i18n("White Pixel"));
m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle());
m_cmbOutlineShape->addItem(i18n("No Outline"));
m_cmbOutlineShape->addItem(i18n("Circle Outline"));
m_cmbOutlineShape->addItem(i18n("Preview Outline"));
m_cmbOutlineShape->addItem(i18n("Tilt Outline"));
m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle());
m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting());
m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline());
KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
cursorColor.fromQColor(cfg.getCursorMainColor());
cursorColorBtutton->setColor(cursorColor);
//
// Window Tab
//
m_cmbMDIType->setCurrentIndex(cfg.readEntry("mdi_viewmode", (int)QMdiArea::TabbedView));
m_backgroundimage->setText(cfg.getMDIBackgroundImage());
connect(m_bnFileName, SIGNAL(clicked()), SLOT(getBackgroundImage()));
connect(clearBgImageButton, SIGNAL(clicked()), SLOT(clearBackgroundImage()));
QString xml = cfg.getMDIBackgroundColor();
KoColor mdiColor = KoColor::fromXML(xml);
m_mdiColor->setColor(mdiColor);
m_chkRubberBand->setChecked(cfg.readEntry("mdi_rubberband", cfg.useOpenGL()));
m_chkCanvasMessages->setChecked(cfg.showCanvasMessages());
const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
m_chkHiDPI->setChecked(kritarc.value("EnableHiDPI", true).toBool());
#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
m_chkHiDPIFractionalScaling->setChecked(kritarc.value("EnableHiDPIFractionalScaling", true).toBool());
#else
m_chkHiDPIFractionalScaling->setVisible(false);
#endif
chkUsageLogging->setChecked(kritarc.value("LogUsage", true).toBool());
m_chkSingleApplication->setChecked(kritarc.value("EnableSingleApplication", true).toBool());
//
// Tools tab
//
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
cmbFlowMode->setCurrentIndex((int)!cfg.readEntry("useCreamyAlphaDarken", true));
m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt());
chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas());
chkEnableTouchRotation->setChecked(!cfg.disableTouchRotation());
chkEnableTranformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste());
m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled());
m_cmbKineticScrollingGesture->addItem(i18n("On Touch Drag"));
m_cmbKineticScrollingGesture->addItem(i18n("On Click Drag"));
m_cmbKineticScrollingGesture->addItem(i18n("On Middle-Click Drag"));
//m_cmbKineticScrollingGesture->addItem(i18n("On Right Click Drag"));
m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture());
m_kineticScrollingSensitivitySlider->setRange(0, 100);
m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity());
m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars());
//
// File handling
//
int autosaveInterval = cfg.autoSaveInterval();
//convert to minutes
m_autosaveSpinBox->setValue(autosaveInterval / 60);
m_autosaveCheckBox->setChecked(autosaveInterval > 0);
chkHideAutosaveFiles->setChecked(cfg.readEntry("autosavefileshidden", true));
m_chkCompressKra->setChecked(cfg.compressKra());
chkZip64->setChecked(cfg.useZip64());
m_backupFileCheckBox->setChecked(cfg.backupFile());
cmbBackupFileLocation->setCurrentIndex(cfg.readEntry("backupfilelocation", 0));
txtBackupFileSuffix->setText(cfg.readEntry("backupfilesuffix", "~"));
QValidator *validator = new BackupSuffixValidator(txtBackupFileSuffix);
txtBackupFileSuffix->setValidator(validator);
intNumBackupFiles->setValue(cfg.readEntry("numberofbackupfiles", 1));
//
// Miscellaneous
//
cmbStartupSession->addItem(i18n("Open default window"));
cmbStartupSession->addItem(i18n("Load previous session"));
cmbStartupSession->addItem(i18n("Show session manager"));
cmbStartupSession->setCurrentIndex(cfg.sessionOnStartup());
chkSaveSessionOnQuit->setChecked(cfg.saveSessionOnQuit(false));
m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport());
m_undoStackSize->setValue(cfg.undoStackLimit());
m_favoritePresetsSpinBox->setValue(cfg.favoritePresets());
chkShowRootLayer->setChecked(cfg.showRootLayer());
KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
bool dontUseNative = true;
#ifdef Q_OS_UNIX
if (qgetenv("XDG_CURRENT_DESKTOP") == "KDE") {
dontUseNative = false;
}
#endif
#ifdef Q_OS_WIN
dontUseNative = false;
+#endif
+#ifdef Q_OS_MACOS
+ m_chkNativeFileDialog->setVisible(false);
#endif
m_chkNativeFileDialog->setChecked(!group.readEntry("DontUseNativeFileDialog", dontUseNative));
intMaxBrushSize->setValue(cfg.readEntry("maximumBrushSize", 1000));
//
// Resources
//
m_urlCacheDbLocation->setMode(KoFileDialog::OpenDirectory);
m_urlCacheDbLocation->setConfigurationName("cachedb_location");
m_urlCacheDbLocation->setFileName(cfg.readEntry(KisResourceCacheDb::dbLocationKey, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)));
m_urlResourceFolder->setMode(KoFileDialog::OpenDirectory);
m_urlResourceFolder->setConfigurationName("resource_directory");
m_urlResourceFolder->setFileName(cfg.readEntry(KisResourceLocator::resourceLocationKey, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)));
}
void GeneralTab::setDefault()
{
KisConfig cfg(true);
m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle(true));
m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle(true));
chkShowRootLayer->setChecked(cfg.showRootLayer(true));
m_autosaveCheckBox->setChecked(cfg.autoSaveInterval(true) > 0);
//convert to minutes
m_autosaveSpinBox->setValue(cfg.autoSaveInterval(true) / 60);
chkHideAutosaveFiles->setChecked(true);
m_undoStackSize->setValue(cfg.undoStackLimit(true));
m_backupFileCheckBox->setChecked(cfg.backupFile(true));
cmbBackupFileLocation->setCurrentIndex(0);
txtBackupFileSuffix->setText("~");
intNumBackupFiles->setValue(1);
m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting(true));
m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline(true));
m_chkNativeFileDialog->setChecked(false);
intMaxBrushSize->setValue(1000);
m_cmbMDIType->setCurrentIndex((int)QMdiArea::TabbedView);
m_chkRubberBand->setChecked(cfg.useOpenGL(true));
m_favoritePresetsSpinBox->setValue(cfg.favoritePresets(true));
KoColor mdiColor;
mdiColor.fromXML(cfg.getMDIBackgroundColor(true));
m_mdiColor->setColor(mdiColor);
m_backgroundimage->setText(cfg.getMDIBackgroundImage(true));
m_chkCanvasMessages->setChecked(cfg.showCanvasMessages(true));
m_chkCompressKra->setChecked(cfg.compressKra(true));
chkZip64->setChecked(cfg.useZip64(true));
m_chkHiDPI->setChecked(false);
m_chkSingleApplication->setChecked(true);
m_chkHiDPI->setChecked(true);
#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
m_chkHiDPIFractionalScaling->setChecked(true);
#endif
chkUsageLogging->setChecked(true);
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
cmbFlowMode->setCurrentIndex(0);
m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled(true));
m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture(true));
m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity(true));
m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars(true));
m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true));
chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas(true));
chkEnableTouchRotation->setChecked(!cfg.disableTouchRotation(true));
chkEnableTranformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste(true));
m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport(true));
KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
cursorColor.fromQColor(cfg.getCursorMainColor(true));
cursorColorBtutton->setColor(cursorColor);
m_urlCacheDbLocation->setFileName(cfg.readEntry(KisResourceCacheDb::dbLocationKey, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)));
m_urlResourceFolder->setFileName(cfg.readEntry(KisResourceLocator::resourceLocationKey, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)));
}
CursorStyle GeneralTab::cursorStyle()
{
return (CursorStyle)m_cmbCursorShape->currentIndex();
}
OutlineStyle GeneralTab::outlineStyle()
{
return (OutlineStyle)m_cmbOutlineShape->currentIndex();
}
KisConfig::SessionOnStartup GeneralTab::sessionOnStartup() const
{
return (KisConfig::SessionOnStartup)cmbStartupSession->currentIndex();
}
bool GeneralTab::saveSessionOnQuit() const
{
return chkSaveSessionOnQuit->isChecked();
}
bool GeneralTab::showRootLayer()
{
return chkShowRootLayer->isChecked();
}
int GeneralTab::autoSaveInterval()
{
//convert to seconds
return m_autosaveCheckBox->isChecked() ? m_autosaveSpinBox->value() * 60 : 0;
}
int GeneralTab::undoStackSize()
{
return m_undoStackSize->value();
}
bool GeneralTab::showOutlineWhilePainting()
{
return m_showOutlinePainting->isChecked();
}
int GeneralTab::mdiMode()
{
return m_cmbMDIType->currentIndex();
}
int GeneralTab::favoritePresets()
{
return m_favoritePresetsSpinBox->value();
}
bool GeneralTab::showCanvasMessages()
{
return m_chkCanvasMessages->isChecked();
}
bool GeneralTab::compressKra()
{
return m_chkCompressKra->isChecked();
}
bool GeneralTab::useZip64()
{
return chkZip64->isChecked();
}
bool GeneralTab::toolOptionsInDocker()
{
return m_radioToolOptionsInDocker->isChecked();
}
bool GeneralTab::kineticScrollingEnabled()
{
return m_groupBoxKineticScrollingSettings->isChecked();
}
int GeneralTab::kineticScrollingGesture()
{
return m_cmbKineticScrollingGesture->currentIndex();
}
int GeneralTab::kineticScrollingSensitivity()
{
return m_kineticScrollingSensitivitySlider->value();
}
bool GeneralTab::kineticScrollingHiddenScrollbars()
{
return m_chkKineticScrollingHideScrollbars->isChecked();
}
bool GeneralTab::switchSelectionCtrlAlt()
{
return m_chkSwitchSelectionCtrlAlt->isChecked();
}
bool GeneralTab::convertToImageColorspaceOnImport()
{
return m_chkConvertOnImport->isChecked();
}
void GeneralTab::getBackgroundImage()
{
KoFileDialog dialog(this, KoFileDialog::OpenFile, "BackgroundImages");
dialog.setCaption(i18n("Select a Background Image"));
dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
dialog.setImageFilters();
QString fn = dialog.filename();
// dialog box was canceled or somehow no file was selected
if (fn.isEmpty()) {
return;
}
QImage image(fn);
if (image.isNull()) {
QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("%1 is not a valid image file!", fn));
}
else {
m_backgroundimage->setText(fn);
}
}
void GeneralTab::clearBackgroundImage()
{
// clearing the background image text will implicitly make the background color be used
m_backgroundimage->setText("");
}
#include "kactioncollection.h"
#include "KisActionsSnapshot.h"
ShortcutSettingsTab::ShortcutSettingsTab(QWidget *parent, const char *name)
: QWidget(parent)
{
setObjectName(name);
QGridLayout * l = new QGridLayout(this);
l->setMargin(0);
m_page = new WdgShortcutSettings(this);
l->addWidget(m_page, 0, 0);
m_snapshot.reset(new KisActionsSnapshot);
KActionCollection *collection =
KisPart::instance()->currentMainwindow()->actionCollection();
Q_FOREACH (QAction *action, collection->actions()) {
m_snapshot->addAction(action->objectName(), action);
}
QMap sortedCollections =
m_snapshot->actionCollections();
for (auto it = sortedCollections.constBegin(); it != sortedCollections.constEnd(); ++it) {
m_page->addCollection(it.value(), it.key());
}
}
ShortcutSettingsTab::~ShortcutSettingsTab()
{
}
void ShortcutSettingsTab::setDefault()
{
m_page->allDefault();
}
void ShortcutSettingsTab::saveChanges()
{
m_page->save();
KisActionRegistry::instance()->settingsPageSaved();
}
void ShortcutSettingsTab::cancelChanges()
{
m_page->undo();
}
ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
: QWidget(parent)
{
setObjectName(name);
// XXX: Make sure only profiles that fit the specified color model
// are shown in the profile combos
QGridLayout * l = new QGridLayout(this);
l->setMargin(0);
m_page = new WdgColorSettings(this);
l->addWidget(m_page, 0, 0);
KisConfig cfg(true);
m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile());
connect(m_page->chkUseSystemMonitorProfile, SIGNAL(toggled(bool)), this, SLOT(toggleAllowMonitorProfileSelection(bool)));
m_page->cmbWorkingColorSpace->setIDList(KoColorSpaceRegistry::instance()->listKeys());
m_page->cmbWorkingColorSpace->setCurrent(cfg.workingColorSpace());
m_page->bnAddColorProfile->setIcon(KisIconUtils::loadIcon("document-open"));
m_page->bnAddColorProfile->setToolTip( i18n("Open Color Profile") );
connect(m_page->bnAddColorProfile, SIGNAL(clicked()), SLOT(installProfile()));
QFormLayout *monitorProfileGrid = new QFormLayout(m_page->monitorprofileholder);
for(int i = 0; i < QGuiApplication::screens().count(); ++i) {
QLabel *lbl = new QLabel(i18nc("The number of the screen", "Screen %1:", i + 1));
m_monitorProfileLabels << lbl;
KisSqueezedComboBox *cmb = new KisSqueezedComboBox();
cmb->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
monitorProfileGrid->addRow(lbl, cmb);
m_monitorProfileWidgets << cmb;
}
// disable if not Linux as KisColorManager is not yet implemented outside Linux
#ifndef Q_OS_LINUX
m_page->chkUseSystemMonitorProfile->setChecked(false);
m_page->chkUseSystemMonitorProfile->setDisabled(true);
m_page->chkUseSystemMonitorProfile->setHidden(true);
#endif
refillMonitorProfiles(KoID("RGBA"));
for(int i = 0; i < QApplication::screens().count(); ++i) {
if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
}
}
m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation());
m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization());
m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors());
KisImageConfig cfgImage(true);
KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration();
m_page->sldAdaptationState->setMaximum(20);
m_page->sldAdaptationState->setMinimum(0);
m_page->sldAdaptationState->setValue((int)proofingConfig->adaptationState*20);
//probably this should become the screenprofile?
KoColor ga(KoColorSpaceRegistry::instance()->rgb8());
ga.fromKoColor(proofingConfig->warningColor);
m_page->gamutAlarm->setColor(ga);
const KoColorSpace *proofingSpace = KoColorSpaceRegistry::instance()->colorSpace(proofingConfig->proofingModel,
proofingConfig->proofingDepth,
proofingConfig->proofingProfile);
if (proofingSpace) {
m_page->proofingSpaceSelector->setCurrentColorSpace(proofingSpace);
}
m_page->cmbProofingIntent->setCurrentIndex((int)proofingConfig->intent);
m_page->ckbProofBlackPoint->setChecked(proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));
m_pasteBehaviourGroup.addButton(m_page->radioPasteWeb, PASTE_ASSUME_WEB);
m_pasteBehaviourGroup.addButton(m_page->radioPasteMonitor, PASTE_ASSUME_MONITOR);
m_pasteBehaviourGroup.addButton(m_page->radioPasteAsk, PASTE_ASK);
QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour());
Q_ASSERT(button);
if (button) {
button->setChecked(true);
}
m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent());
toggleAllowMonitorProfileSelection(cfg.useSystemMonitorProfile());
}
void ColorSettingsTab::installProfile()
{
KoFileDialog dialog(this, KoFileDialog::OpenFiles, "OpenDocumentICC");
dialog.setCaption(i18n("Install Color Profiles"));
dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
dialog.setMimeTypeFilters(QStringList() << "application/vnd.iccprofile", "application/vnd.iccprofile");
QStringList profileNames = dialog.filenames();
KoColorSpaceEngine *iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc");
Q_ASSERT(iccEngine);
QString saveLocation = KoResourcePaths::saveLocation("icc_profiles");
Q_FOREACH (const QString &profileName, profileNames) {
if (!QFile::copy(profileName, saveLocation + QFileInfo(profileName).fileName())) {
qWarning() << "Could not install profile!" << saveLocation + QFileInfo(profileName).fileName();
continue;
}
iccEngine->addProfile(saveLocation + QFileInfo(profileName).fileName());
}
KisConfig cfg(true);
refillMonitorProfiles(KoID("RGBA"));
for(int i = 0; i < QApplication::screens().count(); ++i) {
if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
}
}
}
void ColorSettingsTab::toggleAllowMonitorProfileSelection(bool useSystemProfile)
{
KisConfig cfg(true);
if (useSystemProfile) {
QStringList devices = KisColorManager::instance()->devices();
if (devices.size() == QApplication::screens().count()) {
for(int i = 0; i < QApplication::screens().count(); ++i) {
m_monitorProfileWidgets[i]->clear();
QString monitorForScreen = cfg.monitorForScreen(i, devices[i]);
Q_FOREACH (const QString &device, devices) {
m_monitorProfileLabels[i]->setText(i18nc("The display/screen we got from Qt", "Screen %1:", i + 1));
m_monitorProfileWidgets[i]->addSqueezedItem(KisColorManager::instance()->deviceName(device), device);
if (devices[i] == monitorForScreen) {
m_monitorProfileWidgets[i]->setCurrentIndex(i);
}
}
}
}
}
else {
refillMonitorProfiles(KoID("RGBA"));
for(int i = 0; i < QApplication::screens().count(); ++i) {
if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
}
}
}
}
void ColorSettingsTab::setDefault()
{
m_page->cmbWorkingColorSpace->setCurrent("RGBA");
refillMonitorProfiles(KoID("RGBA"));
KisConfig cfg(true);
KisImageConfig cfgImage(true);
KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration();
const KoColorSpace *proofingSpace = KoColorSpaceRegistry::instance()->colorSpace(proofingConfig->proofingModel,proofingConfig->proofingDepth,proofingConfig->proofingProfile);
if (proofingSpace) {
m_page->proofingSpaceSelector->setCurrentColorSpace(proofingSpace);
}
m_page->cmbProofingIntent->setCurrentIndex((int)proofingConfig->intent);
m_page->ckbProofBlackPoint->setChecked(proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));
m_page->sldAdaptationState->setValue(0);
//probably this should become the screenprofile?
KoColor ga(KoColorSpaceRegistry::instance()->rgb8());
ga.fromKoColor(proofingConfig->warningColor);
m_page->gamutAlarm->setColor(ga);
m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation(true));
m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization(true));
m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors(true));
m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent(true));
m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile(true));
QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour(true));
Q_ASSERT(button);
if (button) {
button->setChecked(true);
}
}
void ColorSettingsTab::refillMonitorProfiles(const KoID & colorSpaceId)
{
for (int i = 0; i < QApplication::screens().count(); ++i) {
m_monitorProfileWidgets[i]->clear();
}
QMap profileList;
Q_FOREACH(const KoColorProfile *profile, KoColorSpaceRegistry::instance()->profilesFor(colorSpaceId.id())) {
profileList[profile->name()] = profile;
}
Q_FOREACH (const KoColorProfile *profile, profileList.values()) {
//qDebug() << "Profile" << profile->name() << profile->isSuitableForDisplay() << csf->defaultProfile();
if (profile->isSuitableForDisplay()) {
for (int i = 0; i < QApplication::screens().count(); ++i) {
m_monitorProfileWidgets[i]->addSqueezedItem(profile->name());
}
}
}
for (int i = 0; i < QApplication::screens().count(); ++i) {
m_monitorProfileLabels[i]->setText(i18nc("The number of the screen", "Screen %1:", i + 1));
m_monitorProfileWidgets[i]->setCurrent(KoColorSpaceRegistry::instance()->defaultProfileForColorSpace(colorSpaceId.id()));
}
}
//---------------------------------------------------------------------------------------------------
void TabletSettingsTab::setDefault()
{
KisCubicCurve curve;
curve.fromString(DEFAULT_CURVE_STRING);
m_page->pressureCurve->setCurve(curve);
m_page->chkUseRightMiddleClickWorkaround->setChecked(
KisConfig(true).useRightMiddleTabletButtonWorkaround(true));
#if defined Q_OS_WIN && (!defined USE_QT_TABLET_WINDOWS || defined QT_HAS_WINTAB_SWITCH)
#ifdef USE_QT_TABLET_WINDOWS
// ask Qt if WinInk is actually available
const bool isWinInkAvailable = true;
#else
const bool isWinInkAvailable = KisTabletSupportWin8::isAvailable();
#endif
if (isWinInkAvailable) {
KisConfig cfg(true);
m_page->radioWintab->setChecked(!cfg.useWin8PointerInput(true));
m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput(true));
} else {
m_page->radioWintab->setChecked(true);
m_page->radioWin8PointerInput->setChecked(false);
}
#else
m_page->grpTabletApi->setVisible(false);
#endif
}
TabletSettingsTab::TabletSettingsTab(QWidget* parent, const char* name): QWidget(parent)
{
setObjectName(name);
QGridLayout * l = new QGridLayout(this);
l->setMargin(0);
m_page = new WdgTabletSettings(this);
l->addWidget(m_page, 0, 0);
KisConfig cfg(true);
KisCubicCurve curve;
curve.fromString( cfg.pressureTabletCurve() );
m_page->pressureCurve->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
m_page->pressureCurve->setCurve(curve);
m_page->chkUseRightMiddleClickWorkaround->setChecked(
cfg.useRightMiddleTabletButtonWorkaround());
#if defined Q_OS_WIN && (!defined USE_QT_TABLET_WINDOWS || defined QT_HAS_WINTAB_SWITCH)
#ifdef USE_QT_TABLET_WINDOWS
// ask Qt if WinInk is actually available
const bool isWinInkAvailable = true;
#else
const bool isWinInkAvailable = KisTabletSupportWin8::isAvailable();
#endif
if (isWinInkAvailable) {
m_page->radioWintab->setChecked(!cfg.useWin8PointerInput());
m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput());
} else {
m_page->radioWintab->setChecked(true);
m_page->radioWin8PointerInput->setChecked(false);
m_page->grpTabletApi->setVisible(false);
}
#ifdef USE_QT_TABLET_WINDOWS
connect(m_page->btnResolutionSettings, SIGNAL(clicked()), SLOT(slotResolutionSettings()));
connect(m_page->radioWintab, SIGNAL(toggled(bool)), m_page->btnResolutionSettings, SLOT(setEnabled(bool)));
m_page->btnResolutionSettings->setEnabled(m_page->radioWintab->isChecked());
#else
m_page->btnResolutionSettings->setVisible(false);
#endif
#else
m_page->grpTabletApi->setVisible(false);
#endif
connect(m_page->btnTabletTest, SIGNAL(clicked()), SLOT(slotTabletTest()));
}
void TabletSettingsTab::slotTabletTest()
{
TabletTestDialog tabletTestDialog(this);
tabletTestDialog.exec();
}
#if defined Q_OS_WIN && defined USE_QT_TABLET_WINDOWS
#include "KisDlgCustomTabletResolution.h"
#endif
void TabletSettingsTab::slotResolutionSettings()
{
#if defined Q_OS_WIN && defined USE_QT_TABLET_WINDOWS
KisDlgCustomTabletResolution dlg(this);
dlg.exec();
#endif
}
//---------------------------------------------------------------------------------------------------
#include "kis_acyclic_signal_connector.h"
int getTotalRAM()
{
return KisImageConfig(true).totalRAM();
}
int PerformanceTab::realTilesRAM()
{
return intMemoryLimit->value() - intPoolLimit->value();
}
PerformanceTab::PerformanceTab(QWidget *parent, const char *name)
: WdgPerformanceSettings(parent, name)
{
KisImageConfig cfg(true);
const double totalRAM = cfg.totalRAM();
lblTotalMemory->setText(KFormat().formatByteSize(totalRAM * 1024 * 1024, 0, KFormat::IECBinaryDialect, KFormat::UnitMegaByte));
sliderMemoryLimit->setSuffix(i18n(" %"));
sliderMemoryLimit->setRange(1, 100, 2);
sliderMemoryLimit->setSingleStep(0.01);
sliderPoolLimit->setSuffix(i18n(" %"));
sliderPoolLimit->setRange(0, 20, 2);
sliderMemoryLimit->setSingleStep(0.01);
sliderUndoLimit->setSuffix(i18n(" %"));
sliderUndoLimit->setRange(0, 50, 2);
sliderMemoryLimit->setSingleStep(0.01);
intMemoryLimit->setMinimumWidth(80);
intPoolLimit->setMinimumWidth(80);
intUndoLimit->setMinimumWidth(80);
SliderAndSpinBoxSync *sync1 =
new SliderAndSpinBoxSync(sliderMemoryLimit,
intMemoryLimit,
getTotalRAM);
sync1->slotParentValueChanged();
m_syncs << sync1;
SliderAndSpinBoxSync *sync2 =
new SliderAndSpinBoxSync(sliderPoolLimit,
intPoolLimit,
std::bind(&KisIntParseSpinBox::value,
intMemoryLimit));
connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync2, SLOT(slotParentValueChanged()));
sync2->slotParentValueChanged();
m_syncs << sync2;
SliderAndSpinBoxSync *sync3 =
new SliderAndSpinBoxSync(sliderUndoLimit,
intUndoLimit,
std::bind(&PerformanceTab::realTilesRAM,
this));
connect(intPoolLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
sync3->slotParentValueChanged();
m_syncs << sync3;
sliderSwapSize->setSuffix(i18n(" GiB"));
sliderSwapSize->setRange(1, 64);
intSwapSize->setRange(1, 64);
KisAcyclicSignalConnector *swapSizeConnector = new KisAcyclicSignalConnector(this);
swapSizeConnector->connectForwardInt(sliderSwapSize, SIGNAL(valueChanged(int)),
intSwapSize, SLOT(setValue(int)));
swapSizeConnector->connectBackwardInt(intSwapSize, SIGNAL(valueChanged(int)),
sliderSwapSize, SLOT(setValue(int)));
lblSwapFileLocation->setText(cfg.swapDir());
connect(bnSwapFile, SIGNAL(clicked()), SLOT(selectSwapDir()));
sliderThreadsLimit->setRange(1, QThread::idealThreadCount());
sliderFrameClonesLimit->setRange(1, QThread::idealThreadCount());
sliderFpsLimit->setRange(20, 300);
sliderFpsLimit->setSuffix(i18n(" fps"));
connect(sliderThreadsLimit, SIGNAL(valueChanged(int)), SLOT(slotThreadsLimitChanged(int)));
connect(sliderFrameClonesLimit, SIGNAL(valueChanged(int)), SLOT(slotFrameClonesLimitChanged(int)));
intCachedFramesSizeLimit->setRange(1, 10000);
intCachedFramesSizeLimit->setSuffix(i18n(" px"));
intCachedFramesSizeLimit->setSingleStep(1);
intCachedFramesSizeLimit->setPageStep(1000);
intRegionOfInterestMargin->setRange(1, 100);
intRegionOfInterestMargin->setSuffix(i18n(" %"));
intRegionOfInterestMargin->setSingleStep(1);
intRegionOfInterestMargin->setPageStep(10);
connect(chkCachedFramesSizeLimit, SIGNAL(toggled(bool)), intCachedFramesSizeLimit, SLOT(setEnabled(bool)));
connect(chkUseRegionOfInterest, SIGNAL(toggled(bool)), intRegionOfInterestMargin, SLOT(setEnabled(bool)));
#ifndef Q_OS_WIN
// AVX workaround is needed on Windows+GCC only
chkDisableAVXOptimizations->setVisible(false);
#endif
load(false);
}
PerformanceTab::~PerformanceTab()
{
qDeleteAll(m_syncs);
}
void PerformanceTab::load(bool requestDefault)
{
KisImageConfig cfg(true);
sliderMemoryLimit->setValue(cfg.memoryHardLimitPercent(requestDefault));
sliderPoolLimit->setValue(cfg.memoryPoolLimitPercent(requestDefault));
sliderUndoLimit->setValue(cfg.memorySoftLimitPercent(requestDefault));
chkPerformanceLogging->setChecked(cfg.enablePerfLog(requestDefault));
chkProgressReporting->setChecked(cfg.enableProgressReporting(requestDefault));
sliderSwapSize->setValue(cfg.maxSwapSize(requestDefault) / 1024);
lblSwapFileLocation->setText(cfg.swapDir(requestDefault));
m_lastUsedThreadsLimit = cfg.maxNumberOfThreads(requestDefault);
m_lastUsedClonesLimit = cfg.frameRenderingClones(requestDefault);
sliderThreadsLimit->setValue(m_lastUsedThreadsLimit);
sliderFrameClonesLimit->setValue(m_lastUsedClonesLimit);
sliderFpsLimit->setValue(cfg.fpsLimit(requestDefault));
{
KisConfig cfg2(true);
chkOpenGLFramerateLogging->setChecked(cfg2.enableOpenGLFramerateLogging(requestDefault));
chkBrushSpeedLogging->setChecked(cfg2.enableBrushSpeedLogging(requestDefault));
chkDisableVectorOptimizations->setChecked(cfg2.enableAmdVectorizationWorkaround(requestDefault));
#ifdef Q_OS_WIN
chkDisableAVXOptimizations->setChecked(cfg2.disableAVXOptimizations(requestDefault));
#endif
chkBackgroundCacheGeneration->setChecked(cfg2.calculateAnimationCacheInBackground(requestDefault));
}
if (cfg.useOnDiskAnimationCacheSwapping(requestDefault)) {
optOnDisk->setChecked(true);
} else {
optInMemory->setChecked(true);
}
chkCachedFramesSizeLimit->setChecked(cfg.useAnimationCacheFrameSizeLimit(requestDefault));
intCachedFramesSizeLimit->setValue(cfg.animationCacheFrameSizeLimit(requestDefault));
intCachedFramesSizeLimit->setEnabled(chkCachedFramesSizeLimit->isChecked());
chkUseRegionOfInterest->setChecked(cfg.useAnimationCacheRegionOfInterest(requestDefault));
intRegionOfInterestMargin->setValue(cfg.animationCacheRegionOfInterestMargin(requestDefault) * 100.0);
intRegionOfInterestMargin->setEnabled(chkUseRegionOfInterest->isChecked());
}
void PerformanceTab::save()
{
KisImageConfig cfg(false);
cfg.setMemoryHardLimitPercent(sliderMemoryLimit->value());
cfg.setMemorySoftLimitPercent(sliderUndoLimit->value());
cfg.setMemoryPoolLimitPercent(sliderPoolLimit->value());
cfg.setEnablePerfLog(chkPerformanceLogging->isChecked());
cfg.setEnableProgressReporting(chkProgressReporting->isChecked());
cfg.setMaxSwapSize(sliderSwapSize->value() * 1024);
cfg.setSwapDir(lblSwapFileLocation->text());
cfg.setMaxNumberOfThreads(sliderThreadsLimit->value());
cfg.setFrameRenderingClones(sliderFrameClonesLimit->value());
cfg.setFpsLimit(sliderFpsLimit->value());
{
KisConfig cfg2(true);
cfg2.setEnableOpenGLFramerateLogging(chkOpenGLFramerateLogging->isChecked());
cfg2.setEnableBrushSpeedLogging(chkBrushSpeedLogging->isChecked());
cfg2.setEnableAmdVectorizationWorkaround(chkDisableVectorOptimizations->isChecked());
#ifdef Q_OS_WIN
cfg2.setDisableAVXOptimizations(chkDisableAVXOptimizations->isChecked());
#endif
cfg2.setCalculateAnimationCacheInBackground(chkBackgroundCacheGeneration->isChecked());
}
cfg.setUseOnDiskAnimationCacheSwapping(optOnDisk->isChecked());
cfg.setUseAnimationCacheFrameSizeLimit(chkCachedFramesSizeLimit->isChecked());
cfg.setAnimationCacheFrameSizeLimit(intCachedFramesSizeLimit->value());
cfg.setUseAnimationCacheRegionOfInterest(chkUseRegionOfInterest->isChecked());
cfg.setAnimationCacheRegionOfInterestMargin(intRegionOfInterestMargin->value() / 100.0);
}
void PerformanceTab::selectSwapDir()
{
KisImageConfig cfg(true);
QString swapDir = cfg.swapDir();
swapDir = QFileDialog::getExistingDirectory(0, i18nc("@title:window", "Select a swap directory"), swapDir);
if (swapDir.isEmpty()) {
return;
}
lblSwapFileLocation->setText(swapDir);
}
void PerformanceTab::slotThreadsLimitChanged(int value)
{
KisSignalsBlocker b(sliderFrameClonesLimit);
sliderFrameClonesLimit->setValue(qMin(m_lastUsedClonesLimit, value));
m_lastUsedThreadsLimit = value;
}
void PerformanceTab::slotFrameClonesLimitChanged(int value)
{
KisSignalsBlocker b(sliderThreadsLimit);
sliderThreadsLimit->setValue(qMax(m_lastUsedThreadsLimit, value));
m_lastUsedClonesLimit = value;
}
//---------------------------------------------------------------------------------------------------
#include "KoColor.h"
#include "opengl/KisOpenGLModeProber.h"
#include "opengl/KisScreenInformationAdapter.h"
#include
#include
QString colorSpaceString(KisSurfaceColorSpace cs, int depth)
{
const QString csString =
#ifdef HAVE_HDR
cs == KisSurfaceColorSpace::bt2020PQColorSpace ? "Rec. 2020 PQ" :
cs == KisSurfaceColorSpace::scRGBColorSpace ? "Rec. 709 Linear" :
#endif
cs == KisSurfaceColorSpace::sRGBColorSpace ? "sRGB" :
cs == KisSurfaceColorSpace::DefaultColorSpace ? "sRGB" :
"Unknown Color Space";
return QString("%1 (%2 bit)").arg(csString).arg(depth);
}
int formatToIndex(KisConfig::RootSurfaceFormat fmt)
{
return fmt == KisConfig::BT2020_PQ ? 1 :
fmt == KisConfig::BT709_G10 ? 2 :
0;
}
KisConfig::RootSurfaceFormat indexToFormat(int value)
{
return value == 1 ? KisConfig::BT2020_PQ :
value == 2 ? KisConfig::BT709_G10 :
KisConfig::BT709_G22;
}
DisplaySettingsTab::DisplaySettingsTab(QWidget *parent, const char *name)
: WdgDisplaySettings(parent, name)
{
KisConfig cfg(true);
const QString rendererOpenGLText = i18nc("canvas renderer", "OpenGL");
const QString rendererSoftwareText = i18nc("canvas renderer", "Software Renderer (very slow)");
#ifdef Q_OS_WIN
const QString rendererOpenGLESText = i18nc("canvas renderer", "Direct3D 11 via ANGLE");
#else
const QString rendererOpenGLESText = i18nc("canvas renderer", "OpenGL ES");
#endif
const KisOpenGL::OpenGLRenderer renderer = KisOpenGL::getCurrentOpenGLRenderer();
lblCurrentRenderer->setText(renderer == KisOpenGL::RendererOpenGLES ? rendererOpenGLESText :
renderer == KisOpenGL::RendererDesktopGL ? rendererOpenGLText :
renderer == KisOpenGL::RendererSoftware ? rendererSoftwareText :
i18nc("canvas renderer", "Unknown"));
cmbPreferredRenderer->clear();
const KisOpenGL::OpenGLRenderers supportedRenderers = KisOpenGL::getSupportedOpenGLRenderers();
const bool onlyOneRendererSupported =
supportedRenderers == KisOpenGL::RendererDesktopGL ||
supportedRenderers == KisOpenGL::RendererOpenGLES ||
supportedRenderers == KisOpenGL::RendererSoftware;
if (!onlyOneRendererSupported) {
QString qtPreferredRendererText;
if (KisOpenGL::getQtPreferredOpenGLRenderer() == KisOpenGL::RendererOpenGLES) {
qtPreferredRendererText = rendererOpenGLESText;
} else if (KisOpenGL::getQtPreferredOpenGLRenderer() == KisOpenGL::RendererSoftware) {
qtPreferredRendererText = rendererSoftwareText;
} else {
qtPreferredRendererText = rendererOpenGLText;
}
cmbPreferredRenderer->addItem(i18nc("canvas renderer", "Auto (%1)", qtPreferredRendererText), KisOpenGL::RendererAuto);
cmbPreferredRenderer->setCurrentIndex(0);
} else {
cmbPreferredRenderer->setEnabled(false);
}
if (supportedRenderers & KisOpenGL::RendererDesktopGL) {
cmbPreferredRenderer->addItem(rendererOpenGLText, KisOpenGL::RendererDesktopGL);
if (KisOpenGL::getUserPreferredOpenGLRendererConfig() == KisOpenGL::RendererDesktopGL) {
cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
}
}
#ifdef Q_OS_WIN
if (supportedRenderers & KisOpenGL::RendererOpenGLES) {
cmbPreferredRenderer->addItem(rendererOpenGLESText, KisOpenGL::RendererOpenGLES);
if (KisOpenGL::getUserPreferredOpenGLRendererConfig() == KisOpenGL::RendererOpenGLES) {
cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
}
}
if (supportedRenderers & KisOpenGL::RendererSoftware) {
cmbPreferredRenderer->addItem(rendererSoftwareText, KisOpenGL::RendererSoftware);
if (KisOpenGL::getUserPreferredOpenGLRendererConfig() == KisOpenGL::RendererSoftware) {
cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
}
}
#endif
if (!(supportedRenderers &
(KisOpenGL::RendererDesktopGL |
KisOpenGL::RendererOpenGLES |
KisOpenGL::RendererSoftware))) {
grpOpenGL->setEnabled(false);
grpOpenGL->setChecked(false);
chkUseTextureBuffer->setEnabled(false);
chkDisableVsync->setEnabled(false);
cmbFilterMode->setEnabled(false);
} else {
grpOpenGL->setEnabled(true);
grpOpenGL->setChecked(cfg.useOpenGL());
chkUseTextureBuffer->setEnabled(cfg.useOpenGL());
chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer());
chkDisableVsync->setVisible(cfg.showAdvancedOpenGLSettings());
chkDisableVsync->setEnabled(cfg.useOpenGL());
chkDisableVsync->setChecked(cfg.disableVSync());
cmbFilterMode->setEnabled(cfg.useOpenGL());
cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode());
// Don't show the high quality filtering mode if it's not available
if (!KisOpenGL::supportsLoD()) {
cmbFilterMode->removeItem(3);
}
}
lblCurrentDisplayFormat->setText("");
lblCurrentRootSurfaceFormat->setText("");
lblHDRWarning->setText("");
cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpace::sRGBColorSpace, 8));
#ifdef HAVE_HDR
cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpace::bt2020PQColorSpace, 10));
cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpace::scRGBColorSpace, 16));
#endif
cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
QOpenGLContext *context = QOpenGLContext::currentContext();
if (!context) {
context = QOpenGLContext::globalShareContext();
}
if (context) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
QScreen *screen = QGuiApplication::screenAt(rect().center());
#else
QScreen *screen = 0;
#endif
KisScreenInformationAdapter adapter(context);
if (screen && adapter.isValid()) {
KisScreenInformationAdapter::ScreenInfo info = adapter.infoForScreen(screen);
if (info.isValid()) {
QStringList toolTip;
toolTip << i18n("Display Id: %1", info.screen->name());
toolTip << i18n("Display Name: %1 %2", info.screen->manufacturer(), info.screen->model());
toolTip << i18n("Min Luminance: %1", info.minLuminance);
toolTip << i18n("Max Luminance: %1", info.maxLuminance);
toolTip << i18n("Max Full Frame Luminance: %1", info.maxFullFrameLuminance);
toolTip << i18n("Red Primary: %1, %2", info.redPrimary[0], info.redPrimary[1]);
toolTip << i18n("Green Primary: %1, %2", info.greenPrimary[0], info.greenPrimary[1]);
toolTip << i18n("Blue Primary: %1, %2", info.bluePrimary[0], info.bluePrimary[1]);
toolTip << i18n("White Point: %1, %2", info.whitePoint[0], info.whitePoint[1]);
lblCurrentDisplayFormat->setToolTip(toolTip.join('\n'));
lblCurrentDisplayFormat->setText(colorSpaceString(info.colorSpace, info.bitsPerColor));
} else {
lblCurrentDisplayFormat->setToolTip("");
lblCurrentDisplayFormat->setText(i18n("Unknown"));
}
} else {
lblCurrentDisplayFormat->setToolTip("");
lblCurrentDisplayFormat->setText(i18n("Unknown"));
qWarning() << "Failed to fetch display info:" << adapter.errorString();
}
const QSurfaceFormat currentFormat = KisOpenGLModeProber::instance()->surfaceformatInUse();
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
KisSurfaceColorSpace colorSpace = currentFormat.colorSpace();
#else
KisSurfaceColorSpace colorSpace = KisSurfaceColorSpace::DefaultColorSpace;
#endif
lblCurrentRootSurfaceFormat->setText(colorSpaceString(colorSpace, currentFormat.redBufferSize()));
cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(cfg.rootSurfaceFormat()));
connect(cmbPreferedRootSurfaceFormat, SIGNAL(currentIndexChanged(int)), SLOT(slotPreferredSurfaceFormatChanged(int)));
slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
}
#ifndef HAVE_HDR
grpHDRSettings->setVisible(false);
tabWidget->removeTab(tabWidget->indexOf(tabHDR));
#endif
const QStringList openglWarnings = KisOpenGL::getOpenGLWarnings();
if (openglWarnings.isEmpty()) {
lblOpenGLWarnings->setVisible(false);
} else {
QString text("⚠ ");
text.append(i18n("Warning(s):"));
text.append("");
Q_FOREACH (const QString &warning, openglWarnings) {
text.append("");
text.append(warning.toHtmlEscaped());
text.append(" ");
}
text.append(" ");
lblOpenGLWarnings->setText(text);
lblOpenGLWarnings->setVisible(true);
}
if (qApp->applicationName() == "kritasketch" || qApp->applicationName() == "kritagemini") {
grpOpenGL->setVisible(false);
grpOpenGL->setMaximumHeight(0);
}
KisImageConfig imageCfg(false);
KoColor c;
c.fromQColor(imageCfg.selectionOverlayMaskColor());
c.setOpacity(1.0);
btnSelectionOverlayColor->setColor(c);
sldSelectionOverlayOpacity->setRange(0.0, 1.0, 2);
sldSelectionOverlayOpacity->setSingleStep(0.05);
sldSelectionOverlayOpacity->setValue(imageCfg.selectionOverlayMaskColor().alphaF());
intCheckSize->setValue(cfg.checkSize());
chkMoving->setChecked(cfg.scrollCheckers());
KoColor ck1(KoColorSpaceRegistry::instance()->rgb8());
ck1.fromQColor(cfg.checkersColor1());
colorChecks1->setColor(ck1);
KoColor ck2(KoColorSpaceRegistry::instance()->rgb8());
ck2.fromQColor(cfg.checkersColor2());
colorChecks2->setColor(ck2);
KoColor cb(KoColorSpaceRegistry::instance()->rgb8());
cb.fromQColor(cfg.canvasBorderColor());
canvasBorder->setColor(cb);
hideScrollbars->setChecked(cfg.hideScrollbars());
chkCurveAntialiasing->setChecked(cfg.antialiasCurves());
chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline());
chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor());
chkHidePopups->setChecked(cfg.hidePopups());
connect(grpOpenGL, SIGNAL(toggled(bool)), SLOT(slotUseOpenGLToggled(bool)));
KoColor gridColor(KoColorSpaceRegistry::instance()->rgb8());
gridColor.fromQColor(cfg.getPixelGridColor());
pixelGridColorButton->setColor(gridColor);
pixelGridDrawingThresholdBox->setValue(cfg.getPixelGridDrawingThreshold() * 100);
}
void DisplaySettingsTab::setDefault()
{
KisConfig cfg(true);
cmbPreferredRenderer->setCurrentIndex(0);
if (!(KisOpenGL::getSupportedOpenGLRenderers() &
(KisOpenGL::RendererDesktopGL | KisOpenGL::RendererOpenGLES))) {
grpOpenGL->setEnabled(false);
grpOpenGL->setChecked(false);
chkUseTextureBuffer->setEnabled(false);
chkDisableVsync->setEnabled(false);
cmbFilterMode->setEnabled(false);
}
else {
grpOpenGL->setEnabled(true);
grpOpenGL->setChecked(cfg.useOpenGL(true));
chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer(true));
chkUseTextureBuffer->setEnabled(true);
chkDisableVsync->setEnabled(true);
chkDisableVsync->setChecked(cfg.disableVSync(true));
cmbFilterMode->setEnabled(true);
cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode(true));
}
chkMoving->setChecked(cfg.scrollCheckers(true));
KisImageConfig imageCfg(false);
KoColor c;
c.fromQColor(imageCfg.selectionOverlayMaskColor(true));
c.setOpacity(1.0);
btnSelectionOverlayColor->setColor(c);
sldSelectionOverlayOpacity->setValue(imageCfg.selectionOverlayMaskColor(true).alphaF());
intCheckSize->setValue(cfg.checkSize(true));
KoColor ck1(KoColorSpaceRegistry::instance()->rgb8());
ck1.fromQColor(cfg.checkersColor1(true));
colorChecks1->setColor(ck1);
KoColor ck2(KoColorSpaceRegistry::instance()->rgb8());
ck2.fromQColor(cfg.checkersColor2(true));
colorChecks2->setColor(ck2);
KoColor cvb(KoColorSpaceRegistry::instance()->rgb8());
cvb.fromQColor(cfg.canvasBorderColor(true));
canvasBorder->setColor(cvb);
hideScrollbars->setChecked(cfg.hideScrollbars(true));
chkCurveAntialiasing->setChecked(cfg.antialiasCurves(true));
chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline(true));
chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor(true));
chkHidePopups->setChecked(cfg.hidePopups(true));
KoColor gridColor(KoColorSpaceRegistry::instance()->rgb8());
gridColor.fromQColor(cfg.getPixelGridColor(true));
pixelGridColorButton->setColor(gridColor);
pixelGridDrawingThresholdBox->setValue(cfg.getPixelGridDrawingThreshold(true) * 100);
cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
}
void DisplaySettingsTab::slotUseOpenGLToggled(bool isChecked)
{
chkUseTextureBuffer->setEnabled(isChecked);
chkDisableVsync->setEnabled(isChecked);
cmbFilterMode->setEnabled(isChecked);
}
void DisplaySettingsTab::slotPreferredSurfaceFormatChanged(int index)
{
Q_UNUSED(index);
QOpenGLContext *context = QOpenGLContext::currentContext();
if (context) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
QScreen *screen = QGuiApplication::screenAt(rect().center());
#else
QScreen *screen = 0;
#endif
KisScreenInformationAdapter adapter(context);
if (adapter.isValid()) {
KisScreenInformationAdapter::ScreenInfo info = adapter.infoForScreen(screen);
if (info.isValid()) {
if (cmbPreferedRootSurfaceFormat->currentIndex() != formatToIndex(KisConfig::BT709_G22) &&
info.colorSpace == KisSurfaceColorSpace::sRGBColorSpace) {
lblHDRWarning->setText(i18n("WARNING: current display doesn't support HDR rendering"));
} else {
lblHDRWarning->setText("");
}
}
}
}
}
//---------------------------------------------------------------------------------------------------
FullscreenSettingsTab::FullscreenSettingsTab(QWidget* parent) : WdgFullscreenSettingsBase(parent)
{
KisConfig cfg(true);
chkDockers->setChecked(cfg.hideDockersFullscreen());
chkMenu->setChecked(cfg.hideMenuFullscreen());
chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen());
chkStatusbar->setChecked(cfg.hideStatusbarFullscreen());
chkTitlebar->setChecked(cfg.hideTitlebarFullscreen());
chkToolbar->setChecked(cfg.hideToolbarFullscreen());
}
void FullscreenSettingsTab::setDefault()
{
KisConfig cfg(true);
chkDockers->setChecked(cfg.hideDockersFullscreen(true));
chkMenu->setChecked(cfg.hideMenuFullscreen(true));
chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen(true));
chkStatusbar->setChecked(cfg.hideStatusbarFullscreen(true));
chkTitlebar->setChecked(cfg.hideTitlebarFullscreen(true));
chkToolbar->setChecked(cfg.hideToolbarFullscreen(true));
}
//---------------------------------------------------------------------------------------------------
KisDlgPreferences::KisDlgPreferences(QWidget* parent, const char* name)
: KPageDialog(parent)
{
Q_UNUSED(name);
setWindowTitle(i18n("Configure Krita"));
setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults);
setFaceType(KPageDialog::List);
// General
KoVBox *vbox = new KoVBox();
KPageWidgetItem *page = new KPageWidgetItem(vbox, i18n("General"));
page->setObjectName("general");
page->setHeader(i18n("General"));
page->setIcon(KisIconUtils::loadIcon("go-home"));
m_pages << page;
addPage(page);
m_general = new GeneralTab(vbox);
// Shortcuts
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Keyboard Shortcuts"));
page->setObjectName("shortcuts");
page->setHeader(i18n("Shortcuts"));
page->setIcon(KisIconUtils::loadIcon("document-export"));
m_pages << page;
addPage(page);
m_shortcutSettings = new ShortcutSettingsTab(vbox);
connect(this, SIGNAL(accepted()), m_shortcutSettings, SLOT(saveChanges()));
connect(this, SIGNAL(rejected()), m_shortcutSettings, SLOT(cancelChanges()));
// Canvas input settings
m_inputConfiguration = new KisInputConfigurationPage();
page = addPage(m_inputConfiguration, i18n("Canvas Input Settings"));
page->setHeader(i18n("Canvas Input"));
page->setObjectName("canvasinput");
page->setIcon(KisIconUtils::loadIcon("configure"));
m_pages << page;
// Display
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Display"));
page->setObjectName("display");
page->setHeader(i18n("Display"));
page->setIcon(KisIconUtils::loadIcon("preferences-desktop-display"));
m_pages << page;
addPage(page);
m_displaySettings = new DisplaySettingsTab(vbox);
// Color
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Color Management"));
page->setObjectName("colormanagement");
page->setHeader(i18n("Color"));
page->setIcon(KisIconUtils::loadIcon("preferences-desktop-color"));
m_pages << page;
addPage(page);
m_colorSettings = new ColorSettingsTab(vbox);
// Performance
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Performance"));
page->setObjectName("performance");
page->setHeader(i18n("Performance"));
page->setIcon(KisIconUtils::loadIcon("applications-system"));
m_pages << page;
addPage(page);
m_performanceSettings = new PerformanceTab(vbox);
// Tablet
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Tablet settings"));
page->setObjectName("tablet");
page->setHeader(i18n("Tablet"));
page->setIcon(KisIconUtils::loadIcon("document-edit"));
m_pages << page;
addPage(page);
m_tabletSettings = new TabletSettingsTab(vbox);
// full-screen mode
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Canvas-only settings"));
page->setObjectName("canvasonly");
page->setHeader(i18n("Canvas-only"));
page->setIcon(KisIconUtils::loadIcon("folder-pictures"));
m_pages << page;
addPage(page);
m_fullscreenSettings = new FullscreenSettingsTab(vbox);
// Author profiles
m_authorPage = new KoConfigAuthorPage();
page = addPage(m_authorPage, i18nc("@title:tab Author page", "Author" ));
page->setObjectName("author");
page->setHeader(i18n("Author"));
page->setIcon(KisIconUtils::loadIcon("im-user"));
m_pages << page;
QPushButton *restoreDefaultsButton = button(QDialogButtonBox::RestoreDefaults);
restoreDefaultsButton->setText(i18nc("@action:button", "Restore Defaults"));
connect(this, SIGNAL(accepted()), m_inputConfiguration, SLOT(saveChanges()));
connect(this, SIGNAL(rejected()), m_inputConfiguration, SLOT(revertChanges()));
KisPreferenceSetRegistry *preferenceSetRegistry = KisPreferenceSetRegistry::instance();
QStringList keys = preferenceSetRegistry->keys();
keys.sort();
Q_FOREACH(const QString &key, keys) {
KisAbstractPreferenceSetFactory *preferenceSetFactory = preferenceSetRegistry->value(key);
KisPreferenceSet* preferenceSet = preferenceSetFactory->createPreferenceSet();
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, preferenceSet->name());
page->setHeader(preferenceSet->header());
page->setIcon(preferenceSet->icon());
addPage(page);
preferenceSet->setParent(vbox);
preferenceSet->loadPreferences();
connect(restoreDefaultsButton, SIGNAL(clicked(bool)), preferenceSet, SLOT(loadDefaultPreferences()), Qt::UniqueConnection);
connect(this, SIGNAL(accepted()), preferenceSet, SLOT(savePreferences()), Qt::UniqueConnection);
}
connect(restoreDefaultsButton, SIGNAL(clicked(bool)), this, SLOT(slotDefault()));
KisConfig cfg(true);
QString currentPageName = cfg.readEntry("KisDlgPreferences/CurrentPage");
Q_FOREACH(KPageWidgetItem *page, m_pages) {
if (page->objectName() == currentPageName) {
setCurrentPage(page);
break;
}
}
}
KisDlgPreferences::~KisDlgPreferences()
{
KisConfig cfg(true);
cfg.writeEntry("KisDlgPreferences/CurrentPage", currentPage()->objectName());
}
void KisDlgPreferences::showEvent(QShowEvent *event){
KPageDialog::showEvent(event);
button(QDialogButtonBox::Cancel)->setAutoDefault(false);
button(QDialogButtonBox::Ok)->setAutoDefault(false);
button(QDialogButtonBox::RestoreDefaults)->setAutoDefault(false);
button(QDialogButtonBox::Cancel)->setDefault(false);
button(QDialogButtonBox::Ok)->setDefault(false);
button(QDialogButtonBox::RestoreDefaults)->setDefault(false);
}
void KisDlgPreferences::slotDefault()
{
if (currentPage()->objectName() == "general") {
m_general->setDefault();
}
else if (currentPage()->objectName() == "shortcuts") {
m_shortcutSettings->setDefault();
}
else if (currentPage()->objectName() == "display") {
m_displaySettings->setDefault();
}
else if (currentPage()->objectName() == "colormanagement") {
m_colorSettings->setDefault();
}
else if (currentPage()->objectName() == "performance") {
m_performanceSettings->load(true);
}
else if (currentPage()->objectName() == "tablet") {
m_tabletSettings->setDefault();
}
else if (currentPage()->objectName() == "canvasonly") {
m_fullscreenSettings->setDefault();
}
else if (currentPage()->objectName() == "canvasinput") {
m_inputConfiguration->setDefaults();
}
}
bool KisDlgPreferences::editPreferences()
{
KisDlgPreferences* dialog;
dialog = new KisDlgPreferences();
bool baccept = (dialog->exec() == Accepted);
if (baccept) {
// General settings
KisConfig cfg(false);
cfg.setNewCursorStyle(dialog->m_general->cursorStyle());
cfg.setNewOutlineStyle(dialog->m_general->outlineStyle());
cfg.setShowRootLayer(dialog->m_general->showRootLayer());
cfg.setShowOutlineWhilePainting(dialog->m_general->showOutlineWhilePainting());
cfg.setForceAlwaysFullSizedOutline(!dialog->m_general->m_changeBrushOutline->isChecked());
cfg.setSessionOnStartup(dialog->m_general->sessionOnStartup());
cfg.setSaveSessionOnQuit(dialog->m_general->saveSessionOnQuit());
KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
group.writeEntry("DontUseNativeFileDialog", !dialog->m_general->m_chkNativeFileDialog->isChecked());
cfg.writeEntry("maximumBrushSize", dialog->m_general->intMaxBrushSize->value());
cfg.writeEntry("mdi_viewmode", dialog->m_general->mdiMode());
cfg.setMDIBackgroundColor(dialog->m_general->m_mdiColor->color().toXML());
cfg.setMDIBackgroundImage(dialog->m_general->m_backgroundimage->text());
cfg.setAutoSaveInterval(dialog->m_general->autoSaveInterval());
cfg.writeEntry("autosavefileshidden", dialog->m_general->chkHideAutosaveFiles->isChecked());
cfg.setBackupFile(dialog->m_general->m_backupFileCheckBox->isChecked());
cfg.writeEntry("backupfilelocation", dialog->m_general->cmbBackupFileLocation->currentIndex());
cfg.writeEntry("backupfilesuffix", dialog->m_general->txtBackupFileSuffix->text());
cfg.writeEntry("numberofbackupfiles", dialog->m_general->intNumBackupFiles->value());
cfg.setShowCanvasMessages(dialog->m_general->showCanvasMessages());
cfg.setCompressKra(dialog->m_general->compressKra());
cfg.setUseZip64(dialog->m_general->useZip64());
const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
kritarc.setValue("EnableHiDPI", dialog->m_general->m_chkHiDPI->isChecked());
#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
kritarc.setValue("EnableHiDPIFractionalScaling", dialog->m_general->m_chkHiDPIFractionalScaling->isChecked());
#endif
kritarc.setValue("EnableSingleApplication", dialog->m_general->m_chkSingleApplication->isChecked());
kritarc.setValue("LogUsage", dialog->m_general->chkUsageLogging->isChecked());
cfg.setToolOptionsInDocker(dialog->m_general->toolOptionsInDocker());
cfg.writeEntry("useCreamyAlphaDarken", (bool)!dialog->m_general->cmbFlowMode->currentIndex());
cfg.setKineticScrollingEnabled(dialog->m_general->kineticScrollingEnabled());
cfg.setKineticScrollingGesture(dialog->m_general->kineticScrollingGesture());
cfg.setKineticScrollingSensitivity(dialog->m_general->kineticScrollingSensitivity());
cfg.setKineticScrollingHideScrollbars(dialog->m_general->kineticScrollingHiddenScrollbars());
cfg.setSwitchSelectionCtrlAlt(dialog->m_general->switchSelectionCtrlAlt());
cfg.setDisableTouchOnCanvas(!dialog->m_general->chkEnableTouch->isChecked());
cfg.setDisableTouchRotation(!dialog->m_general->chkEnableTouchRotation->isChecked());
cfg.setActivateTransformToolAfterPaste(dialog->m_general->chkEnableTranformToolAfterPaste->isChecked());
cfg.setConvertToImageColorspaceOnImport(dialog->m_general->convertToImageColorspaceOnImport());
cfg.setUndoStackLimit(dialog->m_general->undoStackSize());
cfg.setFavoritePresets(dialog->m_general->favoritePresets());
cfg.writeEntry(KisResourceCacheDb::dbLocationKey, dialog->m_general->m_urlCacheDbLocation->fileName());
cfg.writeEntry(KisResourceLocator::resourceLocationKey, dialog->m_general->m_urlResourceFolder->fileName());
// Color settings
cfg.setUseSystemMonitorProfile(dialog->m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
for (int i = 0; i < QApplication::screens().count(); ++i) {
if (dialog->m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked()) {
int currentIndex = dialog->m_colorSettings->m_monitorProfileWidgets[i]->currentIndex();
QString monitorid = dialog->m_colorSettings->m_monitorProfileWidgets[i]->itemData(currentIndex).toString();
cfg.setMonitorForScreen(i, monitorid);
}
else {
cfg.setMonitorProfile(i,
dialog->m_colorSettings->m_monitorProfileWidgets[i]->currentUnsqueezedText(),
dialog->m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
}
}
cfg.setWorkingColorSpace(dialog->m_colorSettings->m_page->cmbWorkingColorSpace->currentItem().id());
KisImageConfig cfgImage(false);
cfgImage.setDefaultProofingConfig(dialog->m_colorSettings->m_page->proofingSpaceSelector->currentColorSpace(),
dialog->m_colorSettings->m_page->cmbProofingIntent->currentIndex(),
dialog->m_colorSettings->m_page->ckbProofBlackPoint->isChecked(),
dialog->m_colorSettings->m_page->gamutAlarm->color(),
(double)dialog->m_colorSettings->m_page->sldAdaptationState->value()/20);
cfg.setUseBlackPointCompensation(dialog->m_colorSettings->m_page->chkBlackpoint->isChecked());
cfg.setAllowLCMSOptimization(dialog->m_colorSettings->m_page->chkAllowLCMSOptimization->isChecked());
cfg.setForcePaletteColors(dialog->m_colorSettings->m_page->chkForcePaletteColor->isChecked());
cfg.setPasteBehaviour(dialog->m_colorSettings->m_pasteBehaviourGroup.checkedId());
cfg.setRenderIntent(dialog->m_colorSettings->m_page->cmbMonitorIntent->currentIndex());
// Tablet settings
cfg.setPressureTabletCurve( dialog->m_tabletSettings->m_page->pressureCurve->curve().toString() );
cfg.setUseRightMiddleTabletButtonWorkaround(
dialog->m_tabletSettings->m_page->chkUseRightMiddleClickWorkaround->isChecked());
#if defined Q_OS_WIN && (!defined USE_QT_TABLET_WINDOWS || defined QT_HAS_WINTAB_SWITCH)
#ifdef USE_QT_TABLET_WINDOWS
// ask Qt if WinInk is actually available
const bool isWinInkAvailable = true;
#else
const bool isWinInkAvailable = KisTabletSupportWin8::isAvailable();
#endif
if (isWinInkAvailable) {
cfg.setUseWin8PointerInput(dialog->m_tabletSettings->m_page->radioWin8PointerInput->isChecked());
}
#endif
dialog->m_performanceSettings->save();
if (!cfg.useOpenGL() && dialog->m_displaySettings->grpOpenGL->isChecked())
cfg.setCanvasState("TRY_OPENGL");
if (dialog->m_displaySettings->grpOpenGL->isChecked()) {
KisOpenGL::OpenGLRenderer renderer = static_cast(
dialog->m_displaySettings->cmbPreferredRenderer->itemData(
dialog->m_displaySettings->cmbPreferredRenderer->currentIndex()).toInt());
KisOpenGL::setUserPreferredOpenGLRendererConfig(renderer);
} else {
KisOpenGL::setUserPreferredOpenGLRendererConfig(KisOpenGL::RendererNone);
}
cfg.setUseOpenGLTextureBuffer(dialog->m_displaySettings->chkUseTextureBuffer->isChecked());
cfg.setOpenGLFilteringMode(dialog->m_displaySettings->cmbFilterMode->currentIndex());
cfg.setDisableVSync(dialog->m_displaySettings->chkDisableVsync->isChecked());
cfg.setRootSurfaceFormat(&kritarc, indexToFormat(dialog->m_displaySettings->cmbPreferedRootSurfaceFormat->currentIndex()));
cfg.setCheckSize(dialog->m_displaySettings->intCheckSize->value());
cfg.setScrollingCheckers(dialog->m_displaySettings->chkMoving->isChecked());
cfg.setCheckersColor1(dialog->m_displaySettings->colorChecks1->color().toQColor());
cfg.setCheckersColor2(dialog->m_displaySettings->colorChecks2->color().toQColor());
cfg.setCanvasBorderColor(dialog->m_displaySettings->canvasBorder->color().toQColor());
cfg.setHideScrollbars(dialog->m_displaySettings->hideScrollbars->isChecked());
KoColor c = dialog->m_displaySettings->btnSelectionOverlayColor->color();
c.setOpacity(dialog->m_displaySettings->sldSelectionOverlayOpacity->value());
cfgImage.setSelectionOverlayMaskColor(c.toQColor());
cfg.setAntialiasCurves(dialog->m_displaySettings->chkCurveAntialiasing->isChecked());
cfg.setAntialiasSelectionOutline(dialog->m_displaySettings->chkSelectionOutlineAntialiasing->isChecked());
cfg.setShowSingleChannelAsColor(dialog->m_displaySettings->chkChannelsAsColor->isChecked());
cfg.setHidePopups(dialog->m_displaySettings->chkHidePopups->isChecked());
cfg.setHideDockersFullscreen(dialog->m_fullscreenSettings->chkDockers->checkState());
cfg.setHideMenuFullscreen(dialog->m_fullscreenSettings->chkMenu->checkState());
cfg.setHideScrollbarsFullscreen(dialog->m_fullscreenSettings->chkScrollbars->checkState());
cfg.setHideStatusbarFullscreen(dialog->m_fullscreenSettings->chkStatusbar->checkState());
cfg.setHideTitlebarFullscreen(dialog->m_fullscreenSettings->chkTitlebar->checkState());
cfg.setHideToolbarFullscreen(dialog->m_fullscreenSettings->chkToolbar->checkState());
cfg.setCursorMainColor(dialog->m_general->cursorColorBtutton->color().toQColor());
cfg.setPixelGridColor(dialog->m_displaySettings->pixelGridColorButton->color().toQColor());
cfg.setPixelGridDrawingThreshold(dialog->m_displaySettings->pixelGridDrawingThresholdBox->value() / 100);
dialog->m_authorPage->apply();
cfg.logImportantSettings();
}
delete dialog;
return baccept;
}
diff --git a/libs/widgetutils/KoFileDialog.cpp b/libs/widgetutils/KoFileDialog.cpp
index ecd6e0a963..8ecdae12a5 100644
--- a/libs/widgetutils/KoFileDialog.cpp
+++ b/libs/widgetutils/KoFileDialog.cpp
@@ -1,432 +1,433 @@
/* This file is part of the KDE project
Copyright (C) 2013 - 2014 Yue Liu
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 "KoFileDialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class Q_DECL_HIDDEN KoFileDialog::Private
{
public:
Private(QWidget *parent_,
KoFileDialog::DialogType dialogType_,
const QString caption_,
const QString defaultDir_,
const QString dialogName_)
: parent(parent_)
, type(dialogType_)
, dialogName(dialogName_)
, caption(caption_)
, defaultDirectory(defaultDir_)
, filterList(QStringList())
, defaultFilter(QString())
, swapExtensionOrder(false)
{
}
~Private()
{
}
QWidget *parent;
KoFileDialog::DialogType type;
QString dialogName;
QString caption;
QString defaultDirectory;
QString proposedFileName;
QStringList filterList;
QString defaultFilter;
QScopedPointer fileDialog;
QString mimeType;
bool swapExtensionOrder;
};
KoFileDialog::KoFileDialog(QWidget *parent,
KoFileDialog::DialogType type,
const QString &dialogName)
: d(new Private(parent, type, "", getUsedDir(dialogName), dialogName))
{
}
KoFileDialog::~KoFileDialog()
{
delete d;
}
void KoFileDialog::setCaption(const QString &caption)
{
d->caption = caption;
}
void KoFileDialog::setDefaultDir(const QString &defaultDir, bool force)
{
if (!defaultDir.isEmpty()) {
if (d->defaultDirectory.isEmpty() || force) {
QFileInfo f(defaultDir);
if (f.isDir()) {
d->defaultDirectory = defaultDir;
}
else {
d->defaultDirectory = f.absolutePath();
}
}
if (!QFileInfo(defaultDir).isDir()) {
d->proposedFileName = QFileInfo(defaultDir).fileName();
}
}
}
void KoFileDialog::setImageFilters()
{
QStringList imageFilters;
// add filters for all formats supported by QImage
Q_FOREACH (const QByteArray &format, QImageReader::supportedImageFormats()) {
imageFilters << QLatin1String("image/") + format;
}
setMimeTypeFilters(imageFilters);
}
void KoFileDialog::setMimeTypeFilters(const QStringList &mimeTypeList, QString defaultMimeType)
{
d->filterList = getFilterStringListFromMime(mimeTypeList, true);
QString defaultFilter;
if (!defaultMimeType.isEmpty()) {
QString suffix = KisMimeDatabase::suffixesForMimeType(defaultMimeType).first();
if (!d->proposedFileName.isEmpty()) {
d->proposedFileName = QFileInfo(d->proposedFileName).completeBaseName() + "." + suffix;
}
QStringList defaultFilters = getFilterStringListFromMime(QStringList() << defaultMimeType, false);
if (defaultFilters.size() > 0) {
defaultFilter = defaultFilters.first();
}
}
d->defaultFilter = defaultFilter;
}
QString KoFileDialog::selectedNameFilter() const
{
return d->fileDialog->selectedNameFilter();
}
QString KoFileDialog::selectedMimeType() const
{
return d->mimeType;
}
void KoFileDialog::createFileDialog()
{
d->fileDialog.reset(new QFileDialog(d->parent, d->caption, d->defaultDirectory + "/" + d->proposedFileName));
KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
bool dontUseNative = true;
#ifdef Q_OS_UNIX
if (qgetenv("XDG_CURRENT_DESKTOP") == "KDE") {
dontUseNative = false;
}
#endif
#ifdef Q_OS_WIN
dontUseNative = false;
#endif
d->fileDialog->setOption(QFileDialog::DontUseNativeDialog, group.readEntry("DontUseNativeFileDialog", dontUseNative));
d->fileDialog->setOption(QFileDialog::DontConfirmOverwrite, false);
d->fileDialog->setOption(QFileDialog::HideNameFilterDetails, dontUseNative ? true : false);
#ifdef Q_OS_MACOS
+ d->fileDialog->setOption(QFileDialog::DontUseNativeDialog, true));
QList urls = d->fileDialog->sidebarUrls();
QUrl volumes = QUrl::fromLocalFile("/Volumes");
if (!urls.contains(volumes)) {
urls.append(volumes);
}
d->fileDialog->setSidebarUrls(urls);
#endif
if (d->type == SaveFile) {
d->fileDialog->setAcceptMode(QFileDialog::AcceptSave);
d->fileDialog->setFileMode(QFileDialog::AnyFile);
}
else { // open / import
d->fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
if (d->type == ImportDirectory || d->type == OpenDirectory){
d->fileDialog->setFileMode(QFileDialog::Directory);
d->fileDialog->setOption(QFileDialog::ShowDirsOnly, true);
}
else { // open / import file(s)
if (d->type == OpenFile
|| d->type == ImportFile)
{
d->fileDialog->setFileMode(QFileDialog::ExistingFile);
}
else { // files
d->fileDialog->setFileMode(QFileDialog::ExistingFiles);
}
}
}
d->fileDialog->setNameFilters(d->filterList);
if (!d->proposedFileName.isEmpty()) {
QString mime = KisMimeDatabase::mimeTypeForFile(d->proposedFileName, d->type == KoFileDialog::SaveFile ? false : true);
QString description = KisMimeDatabase::descriptionForMimeType(mime);
Q_FOREACH(const QString &filter, d->filterList) {
if (filter.startsWith(description)) {
d->fileDialog->selectNameFilter(filter);
break;
}
}
}
else if (!d->defaultFilter.isEmpty()) {
d->fileDialog->selectNameFilter(d->defaultFilter);
}
if (d->type == ImportDirectory ||
d->type == ImportFile || d->type == ImportFiles ||
d->type == SaveFile) {
d->fileDialog->setWindowModality(Qt::WindowModal);
}
}
QString KoFileDialog::filename()
{
QString url;
createFileDialog();
if (d->fileDialog->exec() == QDialog::Accepted) {
url = d->fileDialog->selectedFiles().first();
}
if (!url.isEmpty()) {
QString suffix = QFileInfo(url).suffix();
if (KisMimeDatabase::mimeTypeForSuffix(suffix).isEmpty()) {
suffix = "";
}
if (d->type == SaveFile && suffix.isEmpty()) {
QString selectedFilter;
// index 0 is all supported; if that is chosen, saveDocument will automatically make it .kra
for (int i = 1; i < d->filterList.size(); ++i) {
if (d->filterList[i].startsWith(d->fileDialog->selectedNameFilter())) {
selectedFilter = d->filterList[i];
break;
}
}
int start = selectedFilter.indexOf("*.") + 1;
int end = selectedFilter.indexOf(" ", start);
int n = end - start;
QString extension = selectedFilter.mid(start, n);
if (!(extension.contains(".") || url.endsWith("."))) {
extension = "." + extension;
}
url = url + extension;
}
d->mimeType = KisMimeDatabase::mimeTypeForFile(url, d->type == KoFileDialog::SaveFile ? false : true);
saveUsedDir(url, d->dialogName);
}
return url;
}
QStringList KoFileDialog::filenames()
{
QStringList urls;
createFileDialog();
if (d->fileDialog->exec() == QDialog::Accepted) {
urls = d->fileDialog->selectedFiles();
}
if (urls.size() > 0) {
saveUsedDir(urls.first(), d->dialogName);
}
return urls;
}
QStringList KoFileDialog::splitNameFilter(const QString &nameFilter, QStringList *mimeList)
{
Q_ASSERT(mimeList);
QStringList filters;
QString description;
if (nameFilter.contains("(")) {
description = nameFilter.left(nameFilter.indexOf("(") -1).trimmed();
}
QStringList entries = nameFilter.mid(nameFilter.indexOf("(") + 1).split(" ",QString::SkipEmptyParts );
entries.sort();
Q_FOREACH (QString entry, entries) {
entry = entry.remove("*");
entry = entry.remove(")");
QString mimeType = KisMimeDatabase::mimeTypeForSuffix(entry);
if (mimeType != "application/octet-stream") {
if (!mimeList->contains(mimeType)) {
mimeList->append(mimeType);
filters.append(KisMimeDatabase::descriptionForMimeType(mimeType) + " ( *" + entry + " )");
}
}
else {
filters.append(entry.remove(".").toUpper() + " " + description + " ( *." + entry + " )");
}
}
return filters;
}
const QStringList KoFileDialog::getFilterStringListFromMime(const QStringList &_mimeList,
bool withAllSupportedEntry)
{
QStringList mimeSeen;
// 1
QString allSupported;
// 2
QString kritaNative;
// 3
QString ora;
QStringList ret;
QStringList mimeList = _mimeList;
mimeList.sort();
Q_FOREACH(const QString &mimeType, mimeList) {
if (!mimeSeen.contains(mimeType)) {
QString description = KisMimeDatabase::descriptionForMimeType(mimeType);
if (description.isEmpty() && !mimeType.isEmpty()) {
description = mimeType.split("/")[1];
if (description.startsWith("x-")) {
description = description.remove(0, 2);
}
}
QString oneFilter;
QStringList patterns = KisMimeDatabase::suffixesForMimeType(mimeType);
QStringList globPatterns;
Q_FOREACH(const QString &pattern, patterns) {
if (pattern.startsWith(".")) {
globPatterns << "*" + pattern;
}
else if (pattern.startsWith("*.")) {
globPatterns << pattern;
}
else {
globPatterns << "*." + pattern;
}
}
Q_FOREACH(const QString &glob, globPatterns) {
if (d->swapExtensionOrder) {
oneFilter.prepend(glob + " ");
if (withAllSupportedEntry) {
allSupported.prepend(glob + " ");
}
#ifdef Q_OS_LINUX
if (qgetenv("XDG_CURRENT_DESKTOP") == "GNOME") {
oneFilter.prepend(glob.toUpper() + " ");
if (withAllSupportedEntry) {
allSupported.prepend(glob.toUpper() + " ");
}
}
#endif
}
else {
oneFilter.append(glob + " ");
if (withAllSupportedEntry) {
allSupported.append(glob + " ");
}
#ifdef Q_OS_LINUX
if (qgetenv("XDG_CURRENT_DESKTOP") == "GNOME") {
oneFilter.append(glob.toUpper() + " ");
if (withAllSupportedEntry) {
allSupported.append(glob.toUpper() + " ");
}
}
#endif
}
}
Q_ASSERT(!description.isEmpty());
oneFilter = description + " ( " + oneFilter + ")";
if (mimeType == "application/x-krita") {
kritaNative = oneFilter;
continue;
}
if (mimeType == "image/openraster") {
ora = oneFilter;
continue;
}
else {
ret << oneFilter;
}
mimeSeen << mimeType;
}
}
ret.sort();
ret.removeDuplicates();
if (!ora.isEmpty()) ret.prepend(ora);
if (!kritaNative.isEmpty()) ret.prepend(kritaNative);
if (!allSupported.isEmpty()) ret.prepend(i18n("All supported formats") + " ( " + allSupported + (")"));
return ret;
}
QString KoFileDialog::getUsedDir(const QString &dialogName)
{
if (dialogName.isEmpty()) return "";
KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
QString dir = group.readEntry(dialogName, "");
return dir;
}
void KoFileDialog::saveUsedDir(const QString &fileName,
const QString &dialogName)
{
if (dialogName.isEmpty()) return;
QFileInfo fileInfo(fileName);
KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
group.writeEntry(dialogName, fileInfo.absolutePath());
}
diff --git a/plugins/assistants/Assistants/ConcentricEllipseAssistant.h b/plugins/assistants/Assistants/ConcentricEllipseAssistant.h
index 5d1be96fba..4854d6150b 100644
--- a/plugins/assistants/Assistants/ConcentricEllipseAssistant.h
+++ b/plugins/assistants/Assistants/ConcentricEllipseAssistant.h
@@ -1,63 +1,63 @@
/*
* Copyright (c) 2008 Cyrille Berger
* Copyright (c) 2010 Geoffry Song
* Copyright (c) 2017 Scott Petrovic
*
* 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; 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 Lesser 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.
*/
#ifndef _CONCENTRIC_ELLIPSE_ASSISTANT_H_
#define _CONCENTRIC_ELLIPSE_ASSISTANT_H_
#include "kis_painting_assistant.h"
#include "Ellipse.h"
#include
#include
class ConcentricEllipseAssistant : public KisPaintingAssistant
{
public:
ConcentricEllipseAssistant();
KisPaintingAssistantSP clone(QMap &handleMap) const override;
QPointF adjustPosition(const QPointF& point, const QPointF& strokeBegin) override;
QPointF getEditorPosition() const override;
int numHandles() const override { return 3; }
bool isAssistantComplete() const override;
- void transform(const QTransform &transform);
+ void transform(const QTransform &transform) override;
protected:
QRect boundingRect() const override;
void drawAssistant(QPainter& gc, const QRectF& updateRect, const KisCoordinatesConverter* converter, bool cached, KisCanvas2* canvas, bool assistantVisible=true, bool previewVisible=true) override;
void drawCache(QPainter& gc, const KisCoordinatesConverter *converter, bool assistantVisible=true) override;
private:
QPointF project(const QPointF& pt, const QPointF& strokeBegin) const;
mutable Ellipse m_ellipse;
mutable Ellipse m_extraEllipse;
explicit ConcentricEllipseAssistant(const ConcentricEllipseAssistant &rhs, QMap &handleMap);
};
class ConcentricEllipseAssistantFactory : public KisPaintingAssistantFactory
{
public:
ConcentricEllipseAssistantFactory();
~ConcentricEllipseAssistantFactory() override;
QString id() const override;
QString name() const override;
KisPaintingAssistant* createPaintingAssistant() const override;
};
#endif
diff --git a/plugins/impex/psd/psd_resource_section.cpp b/plugins/impex/psd/psd_resource_section.cpp
index e7e63eca82..dceaa44d42 100644
--- a/plugins/impex/psd/psd_resource_section.cpp
+++ b/plugins/impex/psd/psd_resource_section.cpp
@@ -1,228 +1,229 @@
/*
* Copyright (c) 2009 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 "psd_resource_section.h"
#include
#include
#include
#include "psd_utils.h"
#include "psd_resource_block.h"
PSDImageResourceSection::PSDImageResourceSection()
{
}
PSDImageResourceSection::~PSDImageResourceSection()
{
resources.clear();
}
bool PSDImageResourceSection::read(QIODevice* io)
{
quint32 resourceSectionLength = 0;
if (!psdread(io, &resourceSectionLength)) {
error = "Could not read image resource section length";
return false;
}
dbgFile << "Image Resource Sectionlength:" << resourceSectionLength << ", starts at:" << io->pos();
QByteArray ba = io->read(resourceSectionLength);
if ((quint32)ba.size() != resourceSectionLength) {
error = "Could not read all resources";
return false;
}
QBuffer buf;
buf.setBuffer(&ba);
buf.open(QBuffer::ReadOnly);
while (!buf.atEnd()) {
- QScopedPointer block(new PSDResourceBlock());
+ PSDResourceBlock *block = new PSDResourceBlock();
if (!block->read(&buf)) {
error = "Error reading block: " + block->error;
dbgFile << error << ", skipping.";
+ delete block;
continue;
}
dbgFile << "resource block created. Type:" << block->identifier
<< "name" << block->name
<< "size" << block->dataSize
<< "," << buf.bytesAvailable() << "bytes to go";
- resources[(PSDResourceID)block->identifier] = block.take();
+ resources[(PSDResourceID)block->identifier] = block;
}
dbgFile << "Read" << resources.size() << "Image Resource Blocks";
return valid();
}
bool PSDImageResourceSection::write(QIODevice* io)
{
Q_UNUSED(io);
if (!valid()) {
error = "Resource Section is Invalid";
return false;
}
// First write all the sections
QByteArray ba;
QBuffer buf;
buf.setBuffer(&ba);
buf.open(QBuffer::WriteOnly);
Q_FOREACH (PSDResourceBlock* block, resources) {
if (!block->write(&buf)) {
error = block->error;
return false;
}
}
buf.close();
// Then get the size
quint32 resourceBlockLength = ba.size();
dbgFile << "resource section has size" << resourceBlockLength;
psdwrite(io, resourceBlockLength);
// and write the whole buffer;
return (io->write(ba.constData(), ba.size()) == resourceBlockLength);
}
bool PSDImageResourceSection::valid()
{
return true;
}
QString PSDImageResourceSection::idToString(PSDImageResourceSection::PSDResourceID id)
{
switch(id) {
case UNKNOWN: return "Unknown";
case PS2_IMAGE_INFO : return "0x03e8 - Obsolete - ps 2.0 image info";
case MAC_PRINT_INFO : return "0x03e9 - Optional - Mac print manager print info record";
case PS2_COLOR_TAB : return "0x03eb - Obsolete - ps 2.0 indexed colour table";
case RESN_INFO : return "0x03ed - ResolutionInfo structure";
case ALPHA_NAMES : return "0x03ee - Alpha channel names";
case DISPLAY_INFO : return "0x03ef - DisplayInfo structure";
case CAPTION : return "0x03f0 - Optional - Caption string";
case BORDER_INFO : return "0x03f1 - Border info";
case BACKGROUND_COL : return "0x03f2 - Background colour";
case PRINT_FLAGS : return "0x03f3 - Print flags";
case GREY_HALFTONE : return "0x03f4 - Greyscale and multichannel halftoning info";
case COLOR_HALFTONE : return "0x03f5 - Colour halftoning info";
case DUOTONE_HALFTONE : return "0x03f6 - Duotone halftoning info";
case GREY_XFER : return "0x03f7 - Greyscale and multichannel transfer functions";
case COLOR_XFER : return "0x03f8 - Colour transfer functions";
case DUOTONE_XFER : return "0x03f9 - Duotone transfer functions";
case DUOTONE_INFO : return "0x03fa - Duotone image information";
case EFFECTIVE_BW : return "0x03fb - Effective black & white values for dot range";
case OBSOLETE_01 : return "0x03fc - Obsolete";
case EPS_OPT : return "0x03fd - EPS options";
case QUICK_MASK : return "0x03fe - Quick mask info";
case OBSOLETE_02 : return "0x03ff - Obsolete";
case LAYER_STATE : return "0x0400 - Layer state info";
case WORKING_PATH : return "0x0401 - Working path (not saved)";
case LAYER_GROUP : return "0x0402 - Layers group info";
case OBSOLETE_03 : return "0x0403 - Obsolete";
case IPTC_NAA_DATA : return "0x0404 - IPTC-NAA record (IMV4.pdf)";
case IMAGE_MODE_RAW : return "0x0405 - Image mode for raw format files";
case JPEG_QUAL : return "0x0406 - JPEG quality";
case GRID_GUIDE : return "0x0408 - Grid & guide info";
case THUMB_RES : return "0x0409 - Thumbnail resource";
case COPYRIGHT_FLG : return "0x040a - Copyright flag";
case URL : return "0x040b - URL string";
case THUMB_RES2 : return "0x040c - Thumbnail resource";
case GLOBAL_ANGLE : return "0x040d - Global angle";
case COLOR_SAMPLER : return "0x040e - Colour samplers resource";
case ICC_PROFILE : return "0x040f - ICC Profile";
case WATERMARK : return "0x0410 - Watermark";
case ICC_UNTAGGED : return "0x0411 - Do not use ICC profile flag";
case EFFECTS_VISIBLE : return "0x0412 - Show / hide all effects layers";
case SPOT_HALFTONE : return "0x0413 - Spot halftone";
case DOC_IDS : return "0x0414 - Document specific IDs";
case ALPHA_NAMES_UNI : return "0x0415 - Unicode alpha names";
case IDX_COL_TAB_CNT : return "0x0416 - Indexed colour table count";
case IDX_TRANSPARENT : return "0x0417 - Index of transparent colour (if any)";
case GLOBAL_ALT : return "0x0419 - Global altitude";
case SLICES : return "0x041a - Slices";
case WORKFLOW_URL_UNI : return "0x041b - Workflow URL - Unicode string";
case JUMP_TO_XPEP : return "0x041c - Jump to XPEP (?)";
case ALPHA_ID : return "0x041d - Alpha IDs";
case URL_LIST_UNI : return "0x041e - URL list - unicode";
case VERSION_INFO : return "0x0421 - Version info";
case EXIF_DATA : return "0x0422 - (Photoshop 7.0) EXIF data 1. See http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf";
case EXIF_DATA_3 : return "0x0423 - (Photoshop 7.0) EXIF data 3. See http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf";
case XMP_DATA : return "0x0424 - XMP data block";
case CAPTION_DIGEST : return "0x0425 - (Photoshop 7.0) Caption digest. 16 bytes: RSA Data Security, MD5 message-digest algorithm";
case PRINT_SCALE : return "0x0426 - (Photoshop 7.0) Print scale. 2 bytes style (0 = centered, 1 = size to fit, 2 = user defined). 4 bytes x location (floating point). 4 bytes y location (floating point). 4 bytes scale (floating point)";
case PIXEL_ASPECT_RATION : return "0x0428 - (Photoshop CS) Pixel Aspect Ratio. 4 bytes (version = 1 or 2), 8 bytes double, x / y of a pixel. Version 2, attempting to correct values for NTSC and PAL, previously off by a factor of approx. 5%.";
case LAYER_COMPS : return "0x0429 - (Photoshop CS) Layer Comps. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure)";
case ALTERNATE_DUOTONE : return "0x042A - (Photoshop CS) Alternate Duotone Colors. 2 bytes (version = 1), 2 bytes count, following is repeated for each count: [ Color: 2 bytes for space followed by 4 * 2 byte color component ], following this is another 2 byte count, usually 256, followed by Lab colors one byte each for L, a, b. This resource is not read or used by Photoshop.";
case ALTERNATE_SPOT : return "0x042B - (Photoshop CS)Alternate Spot Colors. 2 bytes (version = 1), 2 bytes channel count, following is repeated for each count: 4 bytes channel ID, Color: 2 bytes for space followed by 4 * 2 byte color component. This resource is not read or used by Photoshop.";
case LAYER_SELECTION_ID : return "0x042D - (Photoshop CS2) Layer Selection ID(s). 2 bytes count, following is repeated for each count: 4 bytes layer ID";
case HDR_TONING : return "0x042E - (Photoshop CS2) HDR Toning information";
case CS2_PRINT_INFO : return "0x042F - (Photoshop CS2) Print info";
case LAYER_GROUP_ENABLED_ID: return "0x0430 - (Photoshop CS2) Layer Group(s) Enabled ID. 1 byte for each layer in the document, repeated by length of the resource. NOTE: Layer groups have start and end markers";
case COLOR_SAMPLERS : return "0x0431 - (Photoshop CS3) Color samplers resource. Also see ID 1038 for old format. See See Color samplers resource format.";
case MEASUREMENT_SCALE : return "0x0432 - (Photoshop CS3) Measurement Scale. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure)";
case TIMELINE_INFO : return "0x0433 - (Photoshop CS3) Timeline Information. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure)";
case SHEET_DISCLOSURE : return "0x0434 - (Photoshop CS3) Sheet Disclosure. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure)";
case CS3_DISPLAY_INFO : return "0x0435 - (Photoshop CS3) DisplayInfo structure to support floating point clors. Also see ID 1007. See Appendix A in Photoshop API Guide.pdf .";
case ONION_SKINS : return "0x0436 - (Photoshop CS3) Onion Skins. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure)";
case COUNT_INFO : return "0x0438 - (Photoshop CS4) Count Information. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure) Information about the count in the document. See the Count Tool.";
case CS5_PRINT_INFO : return "0x043A - (Photoshop CS5) Print Information. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure) Information about the current print settings in the document. The color management options.";
case CS5_PRINT_STYLE : return "0x043B - (Photoshop CS5) Print Style. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure) Information about the current print style in the document. The printing marks, labels, ornaments, etc.";
case CS5_NSPrintInfo : return "0x043C - (Photoshop CS5) Macintosh NSPrintInfo. Variable OS specific info for Macintosh. NSPrintInfo. It is recommended that you do not interpret or use this data.";
case CS5_WIN_DEVMODE : return "0x043D - (Photoshop CS5) Windows DEVMODE. Variable OS specific info for Windows. DEVMODE. It is recommended that you do not interpret or use this data.";
case CS6_AUTOSAVE_FILE_PATH : return "0x043E - (Photoshop CS6) Auto Save File Path. Unicode string. It is recommended that you do not interpret or use this data.";
case CS6_AUTOSAVE_FORMAT : return "0x043F - (Photoshop CS6) Auto Save Format. Unicode string. It is recommended that you do not interpret or use this data.";
case CC_PATH_SELECTION_SATE : return "0x0440 - (Photoshop CC) Path Selection State. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure) Information about the current path selection state.";
case PATH_INFO_FIRST : return "0x07d0 - First path info block";
case PATH_INFO_LAST : return "0x0bb6 - Last path info block";
case CLIPPING_PATH : return "0x0bb7 - Name of clipping path";
case CC_ORIGIN_PATH_INFO : return "0x0BB8 (Photoshop CC) Origin Path Info. 4 bytes (descriptor version = 16), Descriptor (see See Descriptor structure) Information about the origin path data.";
case PLUGIN_RESOURCE_START : return "0x0FA0-0x1387 Plug-In resource(s). Resources added by a plug-in. See the plug-in API found in the SDK documentation ";
case PLUGIN_RESOURCE_END : return "Last plug-in resource";
case IMAGE_READY_VARS : return "0x1B58 Image Ready variables. XML representation of variables definition";
case IMAGE_READY_DATA_SETS : return "0x1B59 Image Ready data sets";
case LIGHTROOM_WORKFLOW : return "0x1F40 (Photoshop CS3) Lightroom workflow, if present the document is in the middle of a Lightroom workflow.";
case PRINT_FLAGS_2 : return "0x2710 - Print flags";
default: {
if (id > PATH_INFO_FIRST && id < PATH_INFO_LAST) return "Path Info Block";
if (id > PLUGIN_RESOURCE_START && id < PLUGIN_RESOURCE_END) return "Plug-In Resource";
}
};
return QString("Unknown Resource Block: %1").arg(id);
}
diff --git a/plugins/paintops/libpaintop/kis_compositeop_option.cpp b/plugins/paintops/libpaintop/kis_compositeop_option.cpp
index e96c68c23f..be6f25c2e4 100644
--- a/plugins/paintops/libpaintop/kis_compositeop_option.cpp
+++ b/plugins/paintops/libpaintop/kis_compositeop_option.cpp
@@ -1,113 +1,118 @@
/*
* Copyright (c) 2011 Silvio Heinrich
*
* 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_compositeop_option.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_signals_blocker.h"
KisCompositeOpOption::KisCompositeOpOption(bool createConfigWidget):
KisPaintOpOption(KisPaintOpOption::GENERAL, true),
m_createConfigWidget(createConfigWidget),
m_eraserMode(false)
{
m_checkable = false;
m_currCompositeOpID = KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
if (createConfigWidget) {
QWidget* widget = new QWidget();
Ui_wdgCompositeOpOption ui;
ui.setupUi(widget);
ui.bnEraser->setIcon(KisIconUtils::loadIcon("draw-eraser"));
m_label = ui.lbChoosenMode;
m_list = ui.list;
m_bnEraser = ui.bnEraser;
+ // show current compositeOp on UI at the start
+ KoID compositeOp = KoCompositeOpRegistry::instance().getKoID(m_currCompositeOpID);
+ m_label->setText(compositeOp.name());
+
+
setConfigurationPage(widget);
connect(ui.list , SIGNAL(clicked(QModelIndex)), this, SLOT(slotCompositeOpChanged(QModelIndex)));
connect(ui.bnEraser, SIGNAL(toggled(bool)) , this, SLOT(slotEraserToggled(bool)));
}
setObjectName("KisCompositeOpOption");
}
KisCompositeOpOption::~KisCompositeOpOption()
{
}
void KisCompositeOpOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const
{
setting->setProperty("CompositeOp", m_currCompositeOpID);
setting->setProperty("EraserMode", m_eraserMode);
}
void KisCompositeOpOption::readOptionSetting(const KisPropertiesConfigurationSP setting)
{
QString ompositeOpID = setting->getString("CompositeOp", KoCompositeOpRegistry::instance().getDefaultCompositeOp().id());
KoID compositeOp = KoCompositeOpRegistry::instance().getKoID(ompositeOpID);
changeCompositeOp(compositeOp);
const bool eraserMode = setting->getBool("EraserMode", false);
slotEraserToggled(eraserMode);
}
void KisCompositeOpOption::changeCompositeOp(const KoID& compositeOp)
{
if (compositeOp.id() == m_currCompositeOpID)
return;
m_currCompositeOpID = compositeOp.id();
if (m_createConfigWidget) {
m_label->setText(compositeOp.name());
}
emitSettingChanged();
}
void KisCompositeOpOption::slotCompositeOpChanged(const QModelIndex& index)
{
Q_UNUSED(index);
KoID compositeOp = m_list->selectedCompositeOp();
changeCompositeOp(compositeOp);
}
void KisCompositeOpOption::slotEraserToggled(bool toggled)
{
if (m_bnEraser->isChecked() != toggled) {
KisSignalsBlocker b(m_bnEraser);
m_bnEraser->setChecked(toggled);
}
m_eraserMode = toggled;
emitSettingChanged();
}
diff --git a/plugins/tools/svgtexttool/SvgTextEditor.cpp b/plugins/tools/svgtexttool/SvgTextEditor.cpp
index 67124cfba9..c68ceb2010 100644
--- a/plugins/tools/svgtexttool/SvgTextEditor.cpp
+++ b/plugins/tools/svgtexttool/SvgTextEditor.cpp
@@ -1,1224 +1,1225 @@
/* This file is part of the KDE project
*
* Copyright 2017 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 "SvgTextEditor.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
#include
#include "kis_font_family_combo_box.h"
#include "FontSizeAction.h"
#include "kis_signals_blocker.h"
SvgTextEditor::SvgTextEditor(QWidget *parent, Qt::WindowFlags flags)
: KXmlGuiWindow(parent, flags)
, m_page(new QWidget(this))
#ifndef Q_OS_WIN
, m_charSelectDialog(new KoDialog(this))
#endif
{
m_textEditorWidget.setupUi(m_page);
setCentralWidget(m_page);
m_textEditorWidget.chkVertical->setVisible(false);
#ifndef Q_OS_WIN
KCharSelect *charSelector = new KCharSelect(m_charSelectDialog, 0, KCharSelect::AllGuiElements);
m_charSelectDialog->setMainWidget(charSelector);
connect(charSelector, SIGNAL(currentCharChanged(QChar)), SLOT(insertCharacter(QChar)));
m_charSelectDialog->hide();
m_charSelectDialog->setButtons(KoDialog::Close);
#endif
connect(m_textEditorWidget.buttons, SIGNAL(accepted()), this, SLOT(save()));
connect(m_textEditorWidget.buttons, SIGNAL(rejected()), this, SLOT(slotCloseEditor()));
connect(m_textEditorWidget.buttons, SIGNAL(clicked(QAbstractButton*)), this, SLOT(dialogButtonClicked(QAbstractButton*)));
KConfigGroup cg(KSharedConfig::openConfig(), "SvgTextTool");
actionCollection()->setConfigGroup("SvgTextTool");
actionCollection()->setComponentName("svgtexttool");
actionCollection()->setComponentDisplayName(i18n("Text Tool"));
QByteArray state;
if (cg.hasKey("WindowState")) {
state = cg.readEntry("State", state);
state = QByteArray::fromBase64(state);
// One day will need to load the version number, but for now, assume 0
restoreState(state);
}
setAcceptDrops(true);
//setStandardToolBarMenuEnabled(true);
#ifdef Q_OS_MACOS
setUnifiedTitleAndToolBarOnMac(true);
#endif
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
m_syntaxHighlighter = new BasicXMLSyntaxHighlighter(m_textEditorWidget.svgTextEdit);
m_textEditorWidget.svgTextEdit->setFont(QFontDatabase().systemFont(QFontDatabase::FixedFont));
createActions();
// If we have customized the toolbars, load that first
setLocalXMLFile(KoResourcePaths::locateLocal("data", "svgtexttool.xmlgui"));
setXMLFile(":/kxmlgui5/svgtexttool.xmlgui");
guiFactory()->addClient(this);
// Create and plug toolbar list for Settings menu
QList toolbarList;
Q_FOREACH (QWidget* it, guiFactory()->containers("ToolBar")) {
KToolBar * toolBar = ::qobject_cast(it);
if (toolBar) {
toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
KToggleAction* act = new KToggleAction(i18n("Show %1 Toolbar", toolBar->windowTitle()), this);
actionCollection()->addAction(toolBar->objectName().toUtf8(), act);
act->setCheckedState(KGuiItem(i18n("Hide %1 Toolbar", toolBar->windowTitle())));
connect(act, SIGNAL(toggled(bool)), this, SLOT(slotToolbarToggled(bool)));
act->setChecked(!toolBar->isHidden());
toolbarList.append(act);
}
}
plugActionList("toolbarlist", toolbarList);
connect(m_textEditorWidget.textTab, SIGNAL(currentChanged(int)), this, SLOT(switchTextEditorTab()));
switchTextEditorTab();
m_textEditorWidget.richTextEdit->document()->setDefaultStyleSheet("p {margin:0px;}");
applySettings();
}
SvgTextEditor::~SvgTextEditor()
{
KConfigGroup g(KSharedConfig::openConfig(), "SvgTextTool");
QByteArray ba = saveState();
g.writeEntry("windowState", ba.toBase64());
}
void SvgTextEditor::setShape(KoSvgTextShape *shape)
{
m_shape = shape;
if (m_shape) {
KoSvgTextShapeMarkupConverter converter(m_shape);
QString svg;
QString styles;
QTextDocument *doc = m_textEditorWidget.richTextEdit->document();
if (converter.convertToSvg(&svg, &styles)) {
m_textEditorWidget.svgTextEdit->setPlainText(svg);
m_textEditorWidget.svgStylesEdit->setPlainText(styles);
m_textEditorWidget.svgTextEdit->document()->setModified(false);
if (shape->isRichTextPreferred() &&
converter.convertSvgToDocument(svg, doc)) {
m_textEditorWidget.richTextEdit->setDocument(doc);
KisSignalsBlocker b(m_textEditorWidget.textTab);
m_textEditorWidget.textTab->setCurrentIndex(Richtext);
doc->clearUndoRedoStacks();
switchTextEditorTab(false);
} else {
KisSignalsBlocker b(m_textEditorWidget.textTab);
m_textEditorWidget.textTab->setCurrentIndex(SvgSource);
switchTextEditorTab(false);
}
}
else {
QMessageBox::warning(this, i18n("Conversion failed"), "Could not get svg text from the shape:\n" + converter.errors().join('\n') + "\n" + converter.warnings().join('\n'));
}
}
-
+ KisFontComboBoxes* fontComboBox = qobject_cast(qobject_cast(actionCollection()->action("svg_font"))->defaultWidget());
+ fontComboBox->setInitialized();
}
void SvgTextEditor::save()
{
if (m_shape) {
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QString svg;
QString styles = m_textEditorWidget.svgStylesEdit->document()->toPlainText();
KoSvgTextShapeMarkupConverter converter(m_shape);
if (!converter.convertDocumentToSvg(m_textEditorWidget.richTextEdit->document(), &svg)) {
qWarning()<<"new converter doesn't work!";
}
m_textEditorWidget.richTextEdit->document()->setModified(false);
emit textUpdated(m_shape, svg, styles, true);
}
else {
emit textUpdated(m_shape, m_textEditorWidget.svgTextEdit->document()->toPlainText(), m_textEditorWidget.svgStylesEdit->document()->toPlainText(), false);
m_textEditorWidget.svgTextEdit->document()->setModified(false);
}
}
}
void SvgTextEditor::switchTextEditorTab(bool convertData)
{
KoSvgTextShape shape;
KoSvgTextShapeMarkupConverter converter(&shape);
if (m_currentEditor) {
disconnect(m_currentEditor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setModified(bool)));
}
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
//first, make buttons checkable
enableRichTextActions(true);
enableSvgTextActions(false);
//then connect the cursor change to the checkformat();
connect(m_textEditorWidget.richTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(checkFormat()));
connect(m_textEditorWidget.richTextEdit, SIGNAL(textChanged()), this, SLOT(slotFixUpEmptyTextBlock()));
checkFormat();
if (m_shape && convertData) {
QTextDocument *doc = m_textEditorWidget.richTextEdit->document();
if (!converter.convertSvgToDocument(m_textEditorWidget.svgTextEdit->document()->toPlainText(), doc)) {
qWarning()<<"new converter svgToDoc doesn't work!";
}
m_textEditorWidget.richTextEdit->setDocument(doc);
doc->clearUndoRedoStacks();
}
m_currentEditor = m_textEditorWidget.richTextEdit;
}
else {
//first, make buttons uncheckable
enableRichTextActions(false);
enableSvgTextActions(true);
disconnect(m_textEditorWidget.richTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(checkFormat()));
// Convert the rich text to svg and styles strings
if (m_shape && convertData) {
QString svg;
QString styles;
if (!converter.convertDocumentToSvg(m_textEditorWidget.richTextEdit->document(), &svg)) {
qWarning()<<"new converter docToSVG doesn't work!";
}
m_textEditorWidget.svgTextEdit->setPlainText(svg);
}
m_currentEditor = m_textEditorWidget.svgTextEdit;
}
connect(m_currentEditor->document(), SIGNAL(modificationChanged(bool)), SLOT(setModified(bool)));
}
void SvgTextEditor::checkFormat()
{
QTextCharFormat format = m_textEditorWidget.richTextEdit->textCursor().charFormat();
QTextBlockFormat blockFormat = m_textEditorWidget.richTextEdit->textCursor().blockFormat();
// checkboxes do not emit signals on manual switching, so we
// can avoid blocking them
if (format.fontWeight() > QFont::Normal) {
actionCollection()->action("svg_weight_bold")->setChecked(true);
} else {
actionCollection()->action("svg_weight_bold")->setChecked(false);
}
actionCollection()->action("svg_format_italic")->setChecked(format.fontItalic());
actionCollection()->action("svg_format_underline")->setChecked(format.fontUnderline());
actionCollection()->action("svg_format_strike_through")->setChecked(format.fontStrikeOut());
{
FontSizeAction *fontSizeAction = qobject_cast(actionCollection()->action("svg_font_size"));
KisSignalsBlocker b(fontSizeAction);
fontSizeAction->setFontSize(format.font().pointSize());
}
{
KoColor fg(format.foreground().color(), KoColorSpaceRegistry::instance()->rgb8());
KoColorPopupAction *fgColorPopup = qobject_cast(actionCollection()->action("svg_format_textcolor"));
KisSignalsBlocker b(fgColorPopup);
fgColorPopup->setCurrentColor(fg);
}
{
KoColor bg(format.foreground().color(), KoColorSpaceRegistry::instance()->rgb8());
KoColorPopupAction *bgColorPopup = qobject_cast(actionCollection()->action("svg_background_color"));
KisSignalsBlocker b(bgColorPopup);
bgColorPopup->setCurrentColor(bg);
}
{
KisFontComboBoxes* fontComboBox = qobject_cast(qobject_cast(actionCollection()->action("svg_font"))->defaultWidget());
KisSignalsBlocker b(fontComboBox);
fontComboBox->setCurrentFont(format.font());
}
{
QDoubleSpinBox *spnLineHeight = qobject_cast(qobject_cast(actionCollection()->action("svg_line_height"))->defaultWidget());
KisSignalsBlocker b(spnLineHeight);
if (blockFormat.lineHeightType() == QTextBlockFormat::SingleHeight) {
spnLineHeight->setValue(100.0);
} else if(blockFormat.lineHeightType() == QTextBlockFormat::ProportionalHeight) {
spnLineHeight->setValue(double(blockFormat.lineHeight()));
}
}
{
QDoubleSpinBox* spnLetterSpacing = qobject_cast(qobject_cast(actionCollection()->action("svg_letter_spacing"))->defaultWidget());
KisSignalsBlocker b(spnLetterSpacing);
spnLetterSpacing->setValue(format.fontLetterSpacing());
}
}
void SvgTextEditor::slotFixUpEmptyTextBlock()
{
if (m_textEditorWidget.richTextEdit->document()->isEmpty()) {
QTextCursor cursor = m_textEditorWidget.richTextEdit->textCursor();
QTextCharFormat format = cursor.blockCharFormat();
{
FontSizeAction *fontSizeAction = qobject_cast(actionCollection()->action("svg_font_size"));
KisFontComboBoxes* fontComboBox = qobject_cast(qobject_cast(actionCollection()->action("svg_font"))->defaultWidget());
format.setFont(fontComboBox->currentFont(fontSizeAction->fontSize()));
}
{
KoColorPopupAction *fgColorPopup = qobject_cast(actionCollection()->action("svg_format_textcolor"));
format.setForeground(fgColorPopup->currentColor());
}
{
//KoColorPopupAction *bgColorPopup = qobject_cast(actionCollection()->action("svg_background_color"));
//format.setBackground(bgColorPopup->currentColor());
}
KisSignalsBlocker b(m_textEditorWidget.richTextEdit);
cursor.setBlockCharFormat(format);
}
}
void SvgTextEditor::undo()
{
m_currentEditor->undo();
}
void SvgTextEditor::redo()
{
m_currentEditor->redo();
}
void SvgTextEditor::cut()
{
m_currentEditor->cut();
}
void SvgTextEditor::copy()
{
m_currentEditor->copy();
}
void SvgTextEditor::paste()
{
m_currentEditor->paste();
}
void SvgTextEditor::selectAll()
{
m_currentEditor->selectAll();
}
void SvgTextEditor::deselect()
{
QTextCursor cursor(m_currentEditor->textCursor());
cursor.clearSelection();
m_currentEditor->setTextCursor(cursor);
}
void SvgTextEditor::find()
{
QDialog *findDialog = new QDialog(this);
findDialog->setWindowTitle(i18n("Find Text"));
QFormLayout *layout = new QFormLayout();
findDialog->setLayout(layout);
QLineEdit *lnSearchKey = new QLineEdit();
layout->addRow(i18n("Find:"), lnSearchKey);
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
findDialog->layout()->addWidget(buttons);
connect(buttons, SIGNAL(accepted()), findDialog, SLOT(accept()));
connect(buttons, SIGNAL(rejected()), findDialog, SLOT(reject()));
if (findDialog->exec()==QDialog::Accepted) {
m_searchKey = lnSearchKey->text();
m_currentEditor->find(m_searchKey);
}
}
void SvgTextEditor::findNext()
{
if (!m_currentEditor->find(m_searchKey)) {
QTextCursor cursor(m_currentEditor->textCursor());
cursor.movePosition(QTextCursor::Start);
m_currentEditor->setTextCursor(cursor);
m_currentEditor->find(m_searchKey);
}
}
void SvgTextEditor::findPrev()
{
if (!m_currentEditor->find(m_searchKey,QTextDocument::FindBackward)) {
QTextCursor cursor(m_currentEditor->textCursor());
cursor.movePosition(QTextCursor::End);
m_currentEditor->setTextCursor(cursor);
m_currentEditor->find(m_searchKey,QTextDocument::FindBackward);
}
}
void SvgTextEditor::replace()
{
QDialog *findDialog = new QDialog(this);
findDialog->setWindowTitle(i18n("Find and Replace all"));
QFormLayout *layout = new QFormLayout();
findDialog->setLayout(layout);
QLineEdit *lnSearchKey = new QLineEdit();
QLineEdit *lnReplaceKey = new QLineEdit();
layout->addRow(i18n("Find:"), lnSearchKey);
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
layout->addRow(i18n("Replace:"), lnReplaceKey);
findDialog->layout()->addWidget(buttons);
connect(buttons, SIGNAL(accepted()), findDialog, SLOT(accept()));
connect(buttons, SIGNAL(rejected()), findDialog, SLOT(reject()));
if (findDialog->exec()==QDialog::Accepted) {
QString search = lnSearchKey->text();
QString replace = lnReplaceKey->text();
QTextCursor cursor(m_currentEditor->textCursor());
cursor.movePosition(QTextCursor::Start);
m_currentEditor->setTextCursor(cursor);
while(m_currentEditor->find(search)) {
m_currentEditor->textCursor().removeSelectedText();
m_currentEditor->textCursor().insertText(replace);
}
}
}
void SvgTextEditor::zoomOut()
{
m_currentEditor->zoomOut();
}
void SvgTextEditor::zoomIn()
{
m_currentEditor->zoomIn();
}
#ifndef Q_OS_WIN
void SvgTextEditor::showInsertSpecialCharacterDialog()
{
m_charSelectDialog->setVisible(!m_charSelectDialog->isVisible());
}
void SvgTextEditor::insertCharacter(const QChar &c)
{
m_currentEditor->textCursor().insertText(QString(c));
}
#endif
void SvgTextEditor::setTextBold(QFont::Weight weight)
{
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QTextCharFormat format;
QTextCursor oldCursor = setTextSelection();
if (m_textEditorWidget.richTextEdit->textCursor().charFormat().fontWeight() > QFont::Normal && weight==QFont::Bold) {
format.setFontWeight(QFont::Normal);
} else {
format.setFontWeight(weight);
}
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
} else {
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
}
void SvgTextEditor::setTextWeightLight()
{
if (m_textEditorWidget.richTextEdit->textCursor().charFormat().fontWeight() < QFont::Normal) {
setTextBold(QFont::Normal);
} else {
setTextBold(QFont::Light);
}
}
void SvgTextEditor::setTextWeightNormal()
{
setTextBold(QFont::Normal);
}
void SvgTextEditor::setTextWeightDemi()
{
if (m_textEditorWidget.richTextEdit->textCursor().charFormat().fontWeight() != QFont::Normal) {
setTextBold(QFont::Normal);
} else {
setTextBold(QFont::DemiBold);
}
}
void SvgTextEditor::setTextWeightBlack()
{
if (m_textEditorWidget.richTextEdit->textCursor().charFormat().fontWeight()>QFont::Normal) {
setTextBold(QFont::Normal);
} else {
setTextBold(QFont::Black);
}
}
void SvgTextEditor::setTextItalic(QFont::Style style)
{
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
QString fontStyle = "inherit";
if (style == QFont::StyleItalic) {
fontStyle = "italic";
} else if(style == QFont::StyleOblique) {
fontStyle = "oblique";
}
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QTextCharFormat format;
QTextCursor origCursor = setTextSelection();
format.setFontItalic(!m_textEditorWidget.richTextEdit->textCursor().charFormat().fontItalic());
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(origCursor);
}
else {
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
}
void SvgTextEditor::setTextDecoration(KoSvgText::TextDecoration decor)
{
QTextCursor cursor = setTextSelection();
QTextCharFormat currentFormat = m_textEditorWidget.richTextEdit->textCursor().charFormat();
QTextCharFormat format;
QString textDecoration = "inherit";
if (decor == KoSvgText::DecorationUnderline) {
textDecoration = "underline";
if (currentFormat.fontUnderline()) {
format.setFontUnderline(false);
}
else {
format.setFontUnderline(true);
}
format.setFontOverline(false);
format.setFontStrikeOut(false);
}
else if (decor == KoSvgText::DecorationLineThrough) {
textDecoration = "line-through";
format.setFontUnderline(false);
format.setFontOverline(false);
if (currentFormat.fontStrikeOut()) {
format.setFontStrikeOut(false);
}
else {
format.setFontStrikeOut(true);
}
}
else if (decor == KoSvgText::DecorationOverline) {
textDecoration = "overline";
format.setFontUnderline(false);
if (currentFormat.fontOverline()) {
format.setFontOverline(false);
}
else {
format.setFontOverline(true);
}
format.setFontStrikeOut(false);
}
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
}
else {
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
m_textEditorWidget.richTextEdit->setTextCursor(cursor);
}
void SvgTextEditor::setTextUnderline()
{
setTextDecoration(KoSvgText::DecorationUnderline);
}
void SvgTextEditor::setTextOverline()
{
setTextDecoration(KoSvgText::DecorationOverline);
}
void SvgTextEditor::setTextStrikethrough()
{
setTextDecoration(KoSvgText::DecorationLineThrough);
}
void SvgTextEditor::setTextSubscript()
{
QTextCharFormat format = m_textEditorWidget.richTextEdit->textCursor().charFormat();
if (format.verticalAlignment()==QTextCharFormat::AlignSubScript) {
format.setVerticalAlignment(QTextCharFormat::AlignNormal);
} else {
format.setVerticalAlignment(QTextCharFormat::AlignSubScript);
}
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
}
void SvgTextEditor::setTextSuperScript()
{
QTextCharFormat format = m_textEditorWidget.richTextEdit->textCursor().charFormat();
if (format.verticalAlignment()==QTextCharFormat::AlignSuperScript) {
format.setVerticalAlignment(QTextCharFormat::AlignNormal);
} else {
format.setVerticalAlignment(QTextCharFormat::AlignSuperScript);
}
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
}
void SvgTextEditor::increaseTextSize()
{
QTextCursor oldCursor = setTextSelection();
QTextCharFormat format;
int pointSize = m_textEditorWidget.richTextEdit->textCursor().charFormat().font().pointSize();
if (pointSize<0) {
pointSize = m_textEditorWidget.richTextEdit->textCursor().charFormat().font().pixelSize();
}
format.setFontPointSize(pointSize+1.0);
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::decreaseTextSize()
{
QTextCursor oldCursor = setTextSelection();
QTextCharFormat format;
int pointSize = m_textEditorWidget.richTextEdit->textCursor().charFormat().font().pointSize();
if (pointSize<1) {
pointSize = m_textEditorWidget.richTextEdit->textCursor().charFormat().font().pixelSize();
}
format.setFontPointSize(qMax(pointSize-1.0, 1.0));
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::setLineHeight(double lineHeightPercentage)
{
QTextCursor oldCursor = setTextSelection();
QTextBlockFormat format = m_textEditorWidget.richTextEdit->textCursor().blockFormat();
format.setLineHeight(lineHeightPercentage, QTextBlockFormat::ProportionalHeight);
m_textEditorWidget.richTextEdit->textCursor().mergeBlockFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::setLetterSpacing(double letterSpacing)
{
QTextCursor cursor = setTextSelection();
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QTextCharFormat format;
format.setFontLetterSpacingType(QFont::AbsoluteSpacing);
format.setFontLetterSpacing(letterSpacing);
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(cursor);
}
else {
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
}
void SvgTextEditor::alignLeft()
{
QTextCursor oldCursor = setTextSelection();
QTextBlockFormat format = m_textEditorWidget.richTextEdit->textCursor().blockFormat();
format.setAlignment(Qt::AlignLeft);
m_textEditorWidget.richTextEdit->textCursor().mergeBlockFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::alignRight()
{
QTextCursor oldCursor = setTextSelection();
QTextBlockFormat format = m_textEditorWidget.richTextEdit->textCursor().blockFormat();
format.setAlignment(Qt::AlignRight);
m_textEditorWidget.richTextEdit->textCursor().mergeBlockFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::alignCenter()
{
QTextCursor oldCursor = setTextSelection();
QTextBlockFormat format = m_textEditorWidget.richTextEdit->textCursor().blockFormat();
format.setAlignment(Qt::AlignCenter);
m_textEditorWidget.richTextEdit->textCursor().mergeBlockFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::alignJustified()
{
QTextCursor oldCursor = setTextSelection();
QTextBlockFormat format = m_textEditorWidget.richTextEdit->textCursor().blockFormat();
format.setAlignment(Qt::AlignJustify);
m_textEditorWidget.richTextEdit->textCursor().mergeBlockFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
void SvgTextEditor::setSettings()
{
KoDialog settingsDialog(this);
Ui_WdgSvgTextSettings textSettings;
QWidget *settingsPage = new QWidget(&settingsDialog, 0);
settingsDialog.setMainWidget(settingsPage);
textSettings.setupUi(settingsPage);
// get the settings and initialize the dialog
KConfigGroup cfg(KSharedConfig::openConfig(), "SvgTextTool");
QStringList selectedWritingSystems = cfg.readEntry("selectedWritingSystems", "").split(",");
QList scripts = QFontDatabase().writingSystems();
QStandardItemModel *writingSystemsModel = new QStandardItemModel(&settingsDialog);
for (int s = 0; s < scripts.size(); s ++) {
QString writingSystem = QFontDatabase().writingSystemName(scripts.at(s));
QStandardItem *script = new QStandardItem(writingSystem);
script->setCheckable(true);
script->setCheckState(selectedWritingSystems.contains(QString::number(scripts.at(s))) ? Qt::Checked : Qt::Unchecked);
script->setData((int)scripts.at(s));
writingSystemsModel->appendRow(script);
}
textSettings.lwScripts->setModel(writingSystemsModel);
EditorMode mode = (EditorMode)cfg.readEntry("EditorMode", (int)Both);
switch(mode) {
case(RichText):
textSettings.radioRichText->setChecked(true);
break;
case(SvgSource):
textSettings.radioSvgSource->setChecked(true);
break;
case(Both):
textSettings.radioBoth->setChecked(true);
}
QColor background = cfg.readEntry("colorEditorBackground", qApp->palette().window().color());
textSettings.colorEditorBackground->setColor(background);
textSettings.colorEditorForeground->setColor(cfg.readEntry("colorEditorForeground", qApp->palette().text().color()));
textSettings.colorKeyword->setColor(cfg.readEntry("colorKeyword", QColor(background.value() < 100 ? Qt::cyan : Qt::blue)));
textSettings.chkBoldKeyword->setChecked(cfg.readEntry("BoldKeyword", true));
textSettings.chkItalicKeyword->setChecked(cfg.readEntry("ItalicKeyword", false));
textSettings.colorElement->setColor(cfg.readEntry("colorElement", QColor(background.value() < 100 ? Qt::magenta : Qt::darkMagenta)));
textSettings.chkBoldElement->setChecked(cfg.readEntry("BoldElement", true));
textSettings.chkItalicElement->setChecked(cfg.readEntry("ItalicElement", false));
textSettings.colorAttribute->setColor(cfg.readEntry("colorAttribute", QColor(background.value() < 100 ? Qt::green : Qt::darkGreen)));
textSettings.chkBoldAttribute->setChecked(cfg.readEntry("BoldAttribute", true));
textSettings.chkItalicAttribute->setChecked(cfg.readEntry("ItalicAttribute", true));
textSettings.colorValue->setColor(cfg.readEntry("colorValue", QColor(background.value() < 100 ? Qt::red: Qt::darkRed)));
textSettings.chkBoldValue->setChecked(cfg.readEntry("BoldValue", true));
textSettings.chkItalicValue->setChecked(cfg.readEntry("ItalicValue", false));
textSettings.colorComment->setColor(cfg.readEntry("colorComment", QColor(background.value() < 100 ? Qt::lightGray : Qt::gray)));
textSettings.chkBoldComment->setChecked(cfg.readEntry("BoldComment", false));
textSettings.chkItalicComment->setChecked(cfg.readEntry("ItalicComment", false));
settingsDialog.setButtons(KoDialog::Ok | KoDialog::Cancel);
if (settingsDialog.exec() == QDialog::Accepted) {
// save and set the settings
QStringList writingSystems;
for (int i = 0; i < writingSystemsModel->rowCount(); i++) {
QStandardItem *item = writingSystemsModel->item(i);
if (item->checkState() == Qt::Checked) {
writingSystems.append(QString::number(item->data().toInt()));
}
}
cfg.writeEntry("selectedWritingSystems", writingSystems.join(','));
if (textSettings.radioRichText->isChecked()) {
cfg.writeEntry("EditorMode", (int)Richtext);
}
else if (textSettings.radioSvgSource->isChecked()) {
cfg.writeEntry("EditorMode", (int)SvgSource);
}
else if (textSettings.radioBoth->isChecked()) {
cfg.writeEntry("EditorMode", (int)Both);
}
cfg.writeEntry("colorEditorBackground", textSettings.colorEditorBackground->color());
cfg.writeEntry("colorEditorForeground", textSettings.colorEditorForeground->color());
cfg.writeEntry("colorKeyword", textSettings.colorKeyword->color());
cfg.writeEntry("BoldKeyword", textSettings.chkBoldKeyword->isChecked());
cfg.writeEntry("ItalicKeyWord", textSettings.chkItalicKeyword->isChecked());
cfg.writeEntry("colorElement", textSettings.colorElement->color());
cfg.writeEntry("BoldElement", textSettings.chkBoldElement->isChecked());
cfg.writeEntry("ItalicElement", textSettings.chkItalicElement->isChecked());
cfg.writeEntry("colorAttribute", textSettings.colorAttribute->color());
cfg.writeEntry("BoldAttribute", textSettings.chkBoldAttribute->isChecked());
cfg.writeEntry("ItalicAttribute", textSettings.chkItalicAttribute->isChecked());
cfg.writeEntry("colorValue", textSettings.colorValue->color());
cfg.writeEntry("BoldValue", textSettings.chkBoldValue->isChecked());
cfg.writeEntry("ItalicValue", textSettings.chkItalicValue->isChecked());
cfg.writeEntry("colorComment", textSettings.colorComment->color());
cfg.writeEntry("BoldComment", textSettings.chkBoldComment->isChecked());
cfg.writeEntry("ItalicComment", textSettings.chkItalicComment->isChecked());
applySettings();
}
}
void SvgTextEditor::slotToolbarToggled(bool)
{
}
void SvgTextEditor::setFontColor(const KoColor &c)
{
QColor color = c.toQColor();
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QTextCursor oldCursor = setTextSelection();
QTextCharFormat format;
format.setForeground(QBrush(color));
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
}
else {
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
}
void SvgTextEditor::setBackgroundColor(const KoColor &c)
{
QColor color = c.toQColor();
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
void SvgTextEditor::setModified(bool modified)
{
if (modified) {
m_textEditorWidget.buttons->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Discard);
}
else {
m_textEditorWidget.buttons->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Close);
}
}
void SvgTextEditor::dialogButtonClicked(QAbstractButton *button)
{
if (m_textEditorWidget.buttons->standardButton(button) == QDialogButtonBox::Discard) {
if (QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("You have modified the text. Discard changes?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
close();
}
}
}
void SvgTextEditor::setFont(const QString &fontName)
{
QFont font;
font.fromString(fontName);
QTextCharFormat curFormat = m_textEditorWidget.richTextEdit->textCursor().charFormat();
font.setPointSize(curFormat.font().pointSize());
QTextCharFormat format;
//This disables the style being set from the font-comboboxes too, so we need to rethink how we use that.
format.setFontFamily(font.family());
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QTextCursor oldCursor = setTextSelection();
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
} else {
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
}
void SvgTextEditor::setFontSize(qreal fontSize)
{
if (m_textEditorWidget.textTab->currentIndex() == Richtext) {
QTextCursor oldCursor = setTextSelection();
QTextCharFormat format;
format.setFontPointSize(fontSize);
m_textEditorWidget.richTextEdit->mergeCurrentCharFormat(format);
m_textEditorWidget.richTextEdit->setTextCursor(oldCursor);
} else {
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
}
void SvgTextEditor::setBaseline(KoSvgText::BaselineShiftMode)
{
QTextCursor cursor = m_textEditorWidget.svgTextEdit->textCursor();
if (cursor.hasSelection()) {
QString selectionModified = "" + cursor.selectedText() + " ";
cursor.removeSelectedText();
cursor.insertText(selectionModified);
}
}
void SvgTextEditor::wheelEvent(QWheelEvent *event)
{
if (event->modifiers() & Qt::ControlModifier) {
int numDegrees = event->delta() / 8;
int numSteps = numDegrees / 7;
m_textEditorWidget.svgTextEdit->zoomOut(numSteps);
event->accept();
}
}
QTextCursor SvgTextEditor::setTextSelection()
{
QTextCursor orignalCursor(m_textEditorWidget.richTextEdit->textCursor());
if (!orignalCursor.hasSelection()){
m_textEditorWidget.richTextEdit->selectAll();
}
return orignalCursor;
}
void SvgTextEditor::applySettings()
{
KConfigGroup cfg(KSharedConfig::openConfig(), "SvgTextTool");
EditorMode mode = (EditorMode)cfg.readEntry("EditorMode", (int)Both);
QWidget *richTab = m_textEditorWidget.richTab;
QWidget *svgTab = m_textEditorWidget.svgTab;
m_page->setUpdatesEnabled(false);
m_textEditorWidget.textTab->clear();
switch(mode) {
case(RichText):
m_textEditorWidget.textTab->addTab(richTab, i18n("Rich text"));
break;
case(SvgSource):
m_textEditorWidget.textTab->addTab(svgTab, i18n("SVG Source"));
break;
case(Both):
m_textEditorWidget.textTab->addTab(richTab, i18n("Rich text"));
m_textEditorWidget.textTab->addTab(svgTab, i18n("SVG Source"));
}
m_syntaxHighlighter->setFormats();
QPalette palette = m_textEditorWidget.svgTextEdit->palette();
QColor background = cfg.readEntry("colorEditorBackground", qApp->palette().window().color());
palette.setBrush(QPalette::Active, QPalette::Background, QBrush(background));
m_textEditorWidget.richTextEdit->setStyleSheet(QString("background-color:%1").arg(background.name()));
m_textEditorWidget.svgStylesEdit->setStyleSheet(QString("background-color:%1").arg(background.name()));
m_textEditorWidget.svgTextEdit->setStyleSheet(QString("background-color:%1").arg(background.name()));
QColor foreground = cfg.readEntry("colorEditorForeground", qApp->palette().text().color());
palette.setBrush(QPalette::Active, QPalette::Text, QBrush(foreground));
QStringList selectedWritingSystems = cfg.readEntry("selectedWritingSystems", "").split(",");
QVector writingSystems;
for (int i=0; i(actionCollection()->action("svg_font_size"));
KisFontComboBoxes* fontComboBox = qobject_cast(qobject_cast(actionCollection()->action("svg_font"))->defaultWidget());
const QFont oldFont = fontComboBox->currentFont(fontSizeAction->fontSize());
fontComboBox->refillComboBox(writingSystems);
fontComboBox->setCurrentFont(oldFont);
}
m_page->setUpdatesEnabled(true);
}
QAction *SvgTextEditor::createAction(const QString &name, const char *member)
{
QAction *action = new QAction(this);
KisActionRegistry *actionRegistry = KisActionRegistry::instance();
actionRegistry->propertizeAction(name, action);
actionCollection()->addAction(name, action);
QObject::connect(action, SIGNAL(triggered(bool)), this, member);
return action;
}
void SvgTextEditor::createActions()
{
KisActionRegistry *actionRegistry = KisActionRegistry::instance();
// File: new, open, save, save as, close
KStandardAction::save(this, SLOT(save()), actionCollection());
KStandardAction::close(this, SLOT(slotCloseEditor()), actionCollection());
// Edit
KStandardAction::undo(this, SLOT(undo()), actionCollection());
KStandardAction::redo(this, SLOT(redo()), actionCollection());
KStandardAction::cut(this, SLOT(cut()), actionCollection());
KStandardAction::copy(this, SLOT(copy()), actionCollection());
KStandardAction::paste(this, SLOT(paste()), actionCollection());
KStandardAction::selectAll(this, SLOT(selectAll()), actionCollection());
KStandardAction::deselect(this, SLOT(deselect()), actionCollection());
KStandardAction::find(this, SLOT(find()), actionCollection());
KStandardAction::findNext(this, SLOT(findNext()), actionCollection());
KStandardAction::findPrev(this, SLOT(findPrev()), actionCollection());
KStandardAction::replace(this, SLOT(replace()), actionCollection());
// View
// WISH: we cannot zoom-in/out in rech-text mode
m_svgTextActions << KStandardAction::zoomOut(this, SLOT(zoomOut()), actionCollection());
m_svgTextActions << KStandardAction::zoomIn(this, SLOT(zoomIn()), actionCollection());
#ifndef Q_OS_WIN
// Insert:
QAction * insertAction = createAction("svg_insert_special_character",
SLOT(showInsertSpecialCharacterDialog()));
insertAction->setCheckable(true);
insertAction->setChecked(false);
#endif
// Format:
m_richTextActions << createAction("svg_weight_bold",
SLOT(setTextBold()));
m_richTextActions << createAction("svg_format_italic",
SLOT(setTextItalic()));
m_richTextActions << createAction("svg_format_underline",
SLOT(setTextUnderline()));
m_richTextActions << createAction("svg_format_strike_through",
SLOT(setTextStrikethrough()));
m_richTextActions << createAction("svg_format_superscript",
SLOT(setTextSuperScript()));
m_richTextActions << createAction("svg_format_subscript",
SLOT(setTextSubscript()));
m_richTextActions << createAction("svg_weight_light",
SLOT(setTextWeightLight()));
m_richTextActions << createAction("svg_weight_normal",
SLOT(setTextWeightNormal()));
m_richTextActions << createAction("svg_weight_demi",
SLOT(setTextWeightDemi()));
m_richTextActions << createAction("svg_weight_black",
SLOT(setTextWeightBlack()));
m_richTextActions << createAction("svg_increase_font_size",
SLOT(increaseTextSize()));
m_richTextActions << createAction("svg_decrease_font_size",
SLOT(decreaseTextSize()));
m_richTextActions << createAction("svg_align_left",
SLOT(alignLeft()));
m_richTextActions << createAction("svg_align_right",
SLOT(alignRight()));
m_richTextActions << createAction("svg_align_center",
SLOT(alignCenter()));
// m_richTextActions << createAction("svg_align_justified",
// SLOT(alignJustified()));
// Settings
m_richTextActions << createAction("svg_settings",
SLOT(setSettings()));
QWidgetAction *fontComboAction = new QWidgetAction(this);
fontComboAction->setToolTip(i18n("Font"));
KisFontComboBoxes *fontCombo = new KisFontComboBoxes();
connect(fontCombo, SIGNAL(fontChanged(QString)), SLOT(setFont(QString)));
fontComboAction->setDefaultWidget(fontCombo);
actionCollection()->addAction("svg_font", fontComboAction);
m_richTextActions << fontComboAction;
actionRegistry->propertizeAction("svg_font", fontComboAction);
QWidgetAction *fontSizeAction = new FontSizeAction(this);
fontSizeAction->setToolTip(i18n("Size"));
connect(fontSizeAction, SIGNAL(fontSizeChanged(qreal)), this, SLOT(setFontSize(qreal)));
actionCollection()->addAction("svg_font_size", fontSizeAction);
m_richTextActions << fontSizeAction;
actionRegistry->propertizeAction("svg_font_size", fontSizeAction);
KoColorPopupAction *fgColor = new KoColorPopupAction(this);
fgColor->setCurrentColor(QColor(Qt::black));
fgColor->setToolTip(i18n("Text Color"));
connect(fgColor, SIGNAL(colorChanged(KoColor)), SLOT(setFontColor(KoColor)));
actionCollection()->addAction("svg_format_textcolor", fgColor);
m_richTextActions << fgColor;
actionRegistry->propertizeAction("svg_format_textcolor", fgColor);
KoColorPopupAction *bgColor = new KoColorPopupAction(this);
bgColor->setCurrentColor(QColor(Qt::white));
bgColor->setToolTip(i18n("Background Color"));
connect(bgColor, SIGNAL(colorChanged(KoColor)), SLOT(setBackgroundColor(KoColor)));
actionCollection()->addAction("svg_background_color", bgColor);
actionRegistry->propertizeAction("svg_background_color", bgColor);
m_richTextActions << bgColor;
QWidgetAction *colorPickerAction = new QWidgetAction(this);
colorPickerAction->setToolTip(i18n("Pick a Color"));
KisScreenColorPicker *colorPicker = new KisScreenColorPicker(false);
connect(colorPicker, SIGNAL(sigNewColorPicked(KoColor)), fgColor, SLOT(setCurrentColor(KoColor)));
connect(colorPicker, SIGNAL(sigNewColorPicked(KoColor)), SLOT(setFontColor(KoColor)));
colorPickerAction->setDefaultWidget(colorPicker);
actionCollection()->addAction("svg_pick_color", colorPickerAction);
m_richTextActions << colorPickerAction;
actionRegistry->propertizeAction("svg_pick_color", colorPickerAction);
QWidgetAction *lineHeight = new QWidgetAction(this);
QDoubleSpinBox *spnLineHeight = new QDoubleSpinBox();
spnLineHeight->setToolTip(i18n("Line height"));
spnLineHeight->setRange(0.0, 1000.0);
spnLineHeight->setSingleStep(10.0);
spnLineHeight->setSuffix(i18n("%"));
connect(spnLineHeight, SIGNAL(valueChanged(double)), SLOT(setLineHeight(double)));
lineHeight->setDefaultWidget(spnLineHeight);
actionCollection()->addAction("svg_line_height", lineHeight);
m_richTextActions << lineHeight;
actionRegistry->propertizeAction("svg_line_height", lineHeight);
QWidgetAction *letterSpacing = new QWidgetAction(this);
QDoubleSpinBox *spnletterSpacing = new QDoubleSpinBox();
spnletterSpacing->setToolTip(i18n("Letter Spacing"));
spnletterSpacing->setRange(-20.0, 20.0);
spnletterSpacing->setSingleStep(0.5);
connect(spnletterSpacing, SIGNAL(valueChanged(double)), SLOT(setLetterSpacing(double)));
letterSpacing->setDefaultWidget(spnletterSpacing);
actionCollection()->addAction("svg_letter_spacing", letterSpacing);
m_richTextActions << letterSpacing;
actionRegistry->propertizeAction("svg_letter_spacing", letterSpacing);
}
void SvgTextEditor::enableRichTextActions(bool enable)
{
Q_FOREACH(QAction *action, m_richTextActions) {
action->setEnabled(enable);
}
}
void SvgTextEditor::enableSvgTextActions(bool enable)
{
Q_FOREACH(QAction *action, m_svgTextActions) {
action->setEnabled(enable);
}
}
void SvgTextEditor::slotCloseEditor()
{
close();
emit textEditorClosed();
}
diff --git a/plugins/tools/svgtexttool/kis_font_family_combo_box.cpp b/plugins/tools/svgtexttool/kis_font_family_combo_box.cpp
index 0de9b7ce97..9fc7aae48f 100644
--- a/plugins/tools/svgtexttool/kis_font_family_combo_box.cpp
+++ b/plugins/tools/svgtexttool/kis_font_family_combo_box.cpp
@@ -1,215 +1,303 @@
/* This file is part of the KDE project
*
- Copyright 2017 Wolthera van Hövell tot Westerflier
-
- 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.
-*/
+ * Copyright 2017 Wolthera van Hövell tot Westerflier
+ *
+ * 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 "kis_font_family_combo_box.h"
#include
#include
#include
#include
#include
#include
#include
#include
+#include
+#include
+#include
+
+PinnedFontsSeparator::PinnedFontsSeparator(QAbstractItemDelegate *_default, QWidget *parent) :
+ QStyledItemDelegate(parent), m_separatorIndex(0), m_separatorAdded(false), m_defaultDelegate(_default)
+{
+}
+
+void PinnedFontsSeparator::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ if (index.row() == m_separatorIndex && m_separatorAdded) {
+ QRect viewRect = option.rect;
+ painter->setPen(Qt::gray);
+ painter->drawLine((viewRect.topLeft() + viewRect.bottomLeft()) / 2 + QPoint(5, 0),
+ (viewRect.topRight() + viewRect.bottomRight()) / 2 - QPoint(5, 0));
+ } else {
+ m_defaultDelegate->paint(painter, option, index);
+ }
+}
+
+QSize PinnedFontsSeparator::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ return QStyledItemDelegate::sizeHint(option, index) * 1.25;
+}
+
+void PinnedFontsSeparator::setSeparatorIndex(int index)
+{
+ m_separatorIndex = index;
+}
+
+void PinnedFontsSeparator::setSeparatorAdded()
+{
+ m_separatorAdded = true;
+}
KisFontFamilyComboBox::KisFontFamilyComboBox(QWidget *parent)
- :QComboBox(parent)
+ : QComboBox(parent), m_initilized(false), m_initializeFromConfig(false)
{
setEditable(true);
completer()->setCompletionMode(QCompleter::InlineCompletion);
completer()->setCaseSensitivity(Qt::CaseInsensitive);
- //The following are all helper fonts for LaTeX that no one but LaTeX would use
- //but because many people use LaTeX, they do show up on quite a few systems.
+ // The following are all helper fonts for LaTeX that no one but LaTeX would use
+ // but because many people use LaTeX, they do show up on quite a few systems.
m_blacklistedFonts << "bbold10" << "cmbsy10" << "cmmib10"
- << "cmss10" << "cmex10" << "cmmi10"
- << "cmr10" << "cmsy10" << "eufb10"
- << "eufm10" << "eurb10" << "eurm10"
- << "esint10" << "eufm10" << "eusb10"
- << "eusm10" << "lasy10" << "lasyb10"
- << "msam10" << "msbm10" << "rsfs10"
- << "stmary10"<< "wasy10" << "wasyb10";
+ << "cmss10" << "cmex10" << "cmmi10"
+ << "cmr10" << "cmsy10" << "eufb10"
+ << "eufm10" << "eurb10" << "eurm10"
+ << "esint10" << "eufm10" << "eusb10"
+ << "eusm10" << "lasy10" << "lasyb10"
+ << "msam10" << "msbm10" << "rsfs10"
+ << "stmary10" << "wasy10" << "wasyb10";
refillComboBox();
+ QFontComboBox *temp = new QFontComboBox();
+ m_fontSeparator = new PinnedFontsSeparator(temp->itemDelegate(), this);
+ temp->setEnabled(true);
+ temp->hide();
+ m_separatorIndex = 0;
+ m_pinnedFonts = KisConfig(true).readList("PinnedFonts", QStringList{});
}
void KisFontFamilyComboBox::refillComboBox(QVector writingSystems)
{
QFontDatabase fonts = QFontDatabase();
- int maxWidth = 0;
+ int maxWidth = 0;
this->clear();
QStringList duplicateFonts;
QStringList filteredFonts;
- if (writingSystems.isEmpty()){
+ if (writingSystems.isEmpty()) {
writingSystems.append(QFontDatabase::Any);
}
- for (int i=0; ifontMetrics().width(family+" "+fonts.writingSystemSample(QFontDatabase::Any));
- if (width>maxWidth) {
+ int width = 1.5 * view()->fontMetrics()
+ .width(family + " " + fonts.writingSystemSample(QFontDatabase::Any));
+ if (width > maxWidth) {
maxWidth = width;
}
}
}
}
this->addItems(filteredFonts);
- if (this->count()>this->maxVisibleItems()) {
+ if (this->count() > this->maxVisibleItems()) {
maxWidth += view()->style()->pixelMetric(QStyle::PixelMetric::PM_ScrollBarExtent);
}
view()->setMinimumWidth(maxWidth);
+} // KisFontFamilyComboBox::refillComboBox
+
+void KisFontFamilyComboBox::setTopFont(const QString &family)
+{
+ if (family.isEmpty() || !m_initilized || m_pinnedFonts.contains(family)) {
+ return;
+ }
+
+ if (m_pinnedFonts.count() > 4) {
+ this->removeItem(4);
+ m_pinnedFonts.pop_back();
+ m_separatorIndex--;
+ }
+
+ if (m_pinnedFonts.isEmpty()) {
+ this->insertSeparator(0);
+ m_fontSeparator->setSeparatorAdded();
+ }
+
+ m_pinnedFonts.push_front(family);
+ this->insertItem(0, family);
+ m_separatorIndex++;
+ m_fontSeparator->setSeparatorIndex(m_separatorIndex);
+ KisConfig(false).writeList("PinnedFonts", m_pinnedFonts);
}
+void KisFontFamilyComboBox::setInitialized()
+{
+ m_initilized = true;
+
+ for(int i=m_pinnedFonts.count()-1; i>=0; i--){
+ this->insertItem(0, m_pinnedFonts[i]);
+ m_separatorIndex++;
+ }
+
+ if(m_pinnedFonts.count() > 0){
+ this->insertSeparator(m_separatorIndex);
+ m_fontSeparator->setSeparatorIndex(m_separatorIndex);
+ m_fontSeparator->setSeparatorAdded();
+ }
+
+ this->setItemDelegate(m_fontSeparator);
+}
KisFontComboBoxes::KisFontComboBoxes(QWidget *parent)
- :QWidget(parent)
+ : QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout();
this->setLayout(layout);
- QFontComboBox *temp = new QFontComboBox(this);
m_family = new KisFontFamilyComboBox();
- m_family->setItemDelegate(temp->itemDelegate());
m_family->setMinimumWidth(100);
m_family->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
layout->addWidget(m_family);
m_styles = new QComboBox();
layout->addWidget(m_styles);
fontFamilyChanged();
m_family->setToolTip(i18n("Font Family"));
m_styles->setToolTip(i18n("Font Style"));
connect(m_family, SIGNAL(currentTextChanged(QString)), this, SLOT(fontFamilyChanged()));
connect(m_family, SIGNAL(currentTextChanged(QString)), this, SLOT(fontChange()));
connect(m_styles, SIGNAL(activated(int)), this, SLOT(fontChange()));
- temp->setEnabled(false);
- temp->hide();
}
void KisFontComboBoxes::setCurrentFont(QFont font)
{
setCurrentFamily(font.family());
setCurrentStyle(QFontDatabase().styleString(font));
}
void KisFontComboBoxes::setCurrentFamily(const QString family)
{
m_family->setCurrentText(family);
fontFamilyChanged();
}
void KisFontComboBoxes::setCurrentStyle(QString style)
{
QString properStyle = QString();
- for(int i=0; icount(); i++) {
+ for (int i = 0; i < m_styles->count(); i++) {
QString item = m_styles->itemText(i);
if (item == style) {
properStyle = style;
} else if (item.contains(style, Qt::CaseInsensitive)) {
properStyle = item;
} else if (item.contains("regular", Qt::CaseInsensitive)) {
properStyle = item;
}
}
m_styles->setCurrentText(properStyle);
-
}
QString KisFontComboBoxes::currentFamily() const
{
return m_family->currentText();
}
QString KisFontComboBoxes::currentStyle() const
{
return m_styles->currentText();
}
QFont KisFontComboBoxes::currentFont(int pointSize) const
{
return QFontDatabase().font(m_family->currentText(), m_styles->currentText(), pointSize);
}
void KisFontComboBoxes::refillComboBox(QVector writingSystems)
{
- KisFontFamilyComboBox *cmb = qobject_cast(m_family);
+ KisFontFamilyComboBox *cmb = qobject_cast(m_family);
cmb->refillComboBox(writingSystems);
}
void KisFontComboBoxes::fontFamilyChanged()
{
QString currentText = m_styles->currentText();
QFontDatabase fonts;
const QString family = m_family->currentText();
- int maxWidth = 0;
+ int maxWidth = 0;
m_styles->clear();
QStringList styles;
+ KisFontFamilyComboBox *cmb = qobject_cast(m_family);
+ cmb->setTopFont(family);
+
if (fonts.styles(family).isEmpty()) {
- styles.append("Normal");
+ styles.append("Normal");
}
- Q_FOREACH(const QString style, fonts.styles(family)) {
- int b = fonts.weight(family, style);
+
+ Q_FOREACH (const QString style, fonts.styles(family)) {
+ int b = fonts.weight(family, style);
int bindex = 0;
- for (int i=0; ifonts.weight(family, styles.at(i))) {
+ for (int i = 0; i < styles.size(); i++) {
+ if (b > fonts.weight(family, styles.at(i))) {
bindex = i;
}
}
if (!styles.contains(style)) {
styles.insert(bindex, style);
- maxWidth = qMax(m_styles->view()->fontMetrics().width(style+" "), maxWidth);
+ maxWidth = qMax(m_styles->view()->fontMetrics().width(style + " "), maxWidth);
}
}
m_styles->addItems(styles);
- if (m_styles->count()>m_styles->maxVisibleItems()) {
+ if (m_styles->count() > m_styles->maxVisibleItems()) {
maxWidth += m_styles->view()->style()->pixelMetric(QStyle::PixelMetric::PM_ScrollBarExtent);
}
m_styles->view()->setMinimumWidth(maxWidth);
if (styles.contains(currentText)) {
m_styles->setCurrentText(currentText);
}
-}
+} // KisFontComboBoxes::fontFamilyChanged
void KisFontComboBoxes::fontChange()
{
emit fontChanged(currentFont(10).toString());
}
+
+void KisFontComboBoxes::setInitialized()
+{
+ KisFontFamilyComboBox *cmb = qobject_cast(m_family);
+ cmb->setInitialized();
+}
diff --git a/plugins/tools/svgtexttool/kis_font_family_combo_box.h b/plugins/tools/svgtexttool/kis_font_family_combo_box.h
index 12ab44f537..fd8b9619c6 100644
--- a/plugins/tools/svgtexttool/kis_font_family_combo_box.h
+++ b/plugins/tools/svgtexttool/kis_font_family_combo_box.h
@@ -1,96 +1,117 @@
/* This file is part of the KDE project
*
- Copyright 2017 Wolthera van Hövell tot Westerflier
-
- 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.
-*/
+ * Copyright 2017 Wolthera van Hövell tot Westerflier
+ *
+ * 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 KIS_FONT_FAMILY_COMBO_BOX_H
#define KIS_FONT_FAMILY_COMBO_BOX_H
-#include
-#include
-#include
-#include
-#include
+#include
+#include
+#include
+#include
+#include
+#include
/**
* @brief The KisFontComboBoxes class
* This is a little widget with two comboboxes.
* One is for the font family, and the other for the style, using the power of QFontDataBase.
* This allows us to limit the amount of fonts visible in the fonts drop down,
* as that can be a quite intense number when you have several 'style complete' fonts.
*/
class KisFontComboBoxes : public QWidget
{
Q_OBJECT
public:
KisFontComboBoxes(QWidget *parent = 0);
/**
* @brief setCurrentFont
* sets the style and font comboboxes appropriately.
* @param font the QFont to set.
*/
void setCurrentFont(QFont font);
void setCurrentFamily(const QString family);
void setCurrentStyle(QString style);
- //Current family name.
+ // Current family name.
QString currentFamily() const;
- //Current style
+ // Current style
QString currentStyle() const;
+
/**
* @brief currentFont the current QFont from both family and style combinations
* @param pointSize as this widget has no idea about point size, input desired point size.
* @return
*/
QFont currentFont(int pointSize = 10) const;
void refillComboBox(QVector writingSystems = QVector());
+ void setInitialized();
+
Q_SIGNALS:
void fontChanged(QString);
private Q_SLOTS:
void fontFamilyChanged();
void fontChange();
private:
QComboBox *m_family;
QComboBox *m_styles;
};
+class PinnedFontsSeparator : public QStyledItemDelegate {
+public:
+ PinnedFontsSeparator(QAbstractItemDelegate *_default, QWidget *parent = nullptr);
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+ void setSeparatorIndex(int index);
+ void setSeparatorAdded();
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+
+private:
+ int m_separatorIndex;
+ bool m_separatorAdded;
+ QAbstractItemDelegate *m_defaultDelegate;
+};
+
/**
* @brief The KisFontFamilyComboBox class
* A QCombobox that limits the amount of fonts it contains.
* Amongst others it blacklists certain fonts, it also filters
* out 'style' fonts, like those used for Bold and Italic,
* and it allows you to limit the amount of fonts to certain writing systems
*/
class KisFontFamilyComboBox : public QComboBox
{
Q_OBJECT
public:
KisFontFamilyComboBox(QWidget *parent = 0);
- //List of writing systems to use. If empty will default to "all"
+ // List of writing systems to use. If empty will default to "all"
void refillComboBox(QVector writingSystems = QVector());
+ void setTopFont(const QString &family);
+ void setInitialized();
private:
-
- QStringList m_blacklistedFonts;
-
+ QStringList m_pinnedFonts, m_blacklistedFonts;
+ bool m_initilized, m_initializeFromConfig;
+ int m_separatorIndex;
+ PinnedFontsSeparator *m_fontSeparator;
};
#endif // KIS_FONT_FAMILY_COMBO_BOX_H