Commit 54d3dc15 authored by Anna Medonosová's avatar Anna Medonosová

Saving Mirror Tool state to KRA

Summary:
Saving Mirror Tool state to KRA file, wished for in bug 339515.

BUG:339515

Test Plan:
  - Set up mirror lines. Save, close and reopen. Expected result: the mirror lines and options should be automatically set and activated.
  - Open multiple files, with and without mirror lines. Expected result: Every open document should have separate configuration. Toolbar actions should affect only the currently active view.

Reviewers: #krita, rempt

Reviewed By: #krita, rempt

Subscribers: rempt

Tags: #krita

Differential Revision: https://phabricator.kde.org/D18254
parent 7dc0c433
......@@ -43,7 +43,8 @@ set(kritaui_LIB_SRCS
canvas/kis_snap_config.cpp
canvas/kis_snap_line_strategy.cpp
canvas/KisSnapPointStrategy.cpp
dialogs/kis_about_application.cpp
canvas/KisMirrorAxisConfig.cpp
dialogs/kis_about_application.cpp
dialogs/kis_dlg_adj_layer_props.cc
dialogs/kis_dlg_adjustment_layer.cc
dialogs/kis_dlg_filter.cpp
......
......@@ -121,6 +121,8 @@
#include "kis_async_action_feedback.h"
#include "KisCloneDocumentStroke.h"
#include <KisMirrorAxisConfig.h>
// Define the protocol used here for embedded documents' URL
// This used to "store" but QUrl didn't like it,
......@@ -256,6 +258,7 @@ public:
, autoSaveTimer(new QTimer(q))
, undoStack(new UndoStack(q))
, guidesConfig(rhs.guidesConfig)
, mirrorAxisConfig(rhs.mirrorAxisConfig)
, m_bAutoDetectedMime(rhs.m_bAutoDetectedMime)
, m_url(rhs.m_url)
, m_file(rhs.m_file)
......@@ -302,6 +305,7 @@ public:
KUndo2Stack *undoStack = 0;
KisGuidesConfig guidesConfig;
KisMirrorAxisConfig mirrorAxisConfig;
bool m_bAutoDetectedMime = false; // whether the mimetype in the arguments was detected by the part itself
QUrl m_url; // local url - the one displayed to the user.
......@@ -1585,6 +1589,23 @@ void KisDocument::setGuidesConfig(const KisGuidesConfig &data)
emit sigGuidesConfigChanged(d->guidesConfig);
}
const KisMirrorAxisConfig& KisDocument::mirrorAxisConfig() const
{
return d->mirrorAxisConfig;
}
void KisDocument::setMirrorAxisConfig(const KisMirrorAxisConfig &config)
{
if (d->mirrorAxisConfig == config) {
return;
}
d->mirrorAxisConfig = config;
setModified(true);
emit sigMirrorAxisConfigChanged();
}
void KisDocument::resetURL() {
setUrl(QUrl());
setLocalFilePath(QString());
......
......@@ -64,6 +64,7 @@ class KisUndoStore;
class KisPart;
class KisGridConfig;
class KisGuidesConfig;
class KisMirrorAxisConfig;
class QDomDocument;
class KisReferenceImagesLayer;
......@@ -350,6 +351,9 @@ public:
const KisGuidesConfig& guidesConfig() const;
void setGuidesConfig(const KisGuidesConfig &data);
const KisMirrorAxisConfig& mirrorAxisConfig() const;
void setMirrorAxisConfig(const KisMirrorAxisConfig& config);
QList<KoColorSet *> &paletteList();
void setPaletteList(const QList<KoColorSet *> &paletteList);
......@@ -452,6 +456,8 @@ Q_SIGNALS:
void sigReferenceImagesChanged();
void sigMirrorAxisConfigChanged();
private Q_SLOTS:
void finishExportInBackground();
void slotChildCompletedSavingInBackground(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
......
/*
* Copyright (c) 2019 Anna Medonosova <anna.medonosova@gmail.com>
*
* 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.1 of the License.
*
* 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.
*/
#include <kis_dom_utils.h>
#include <QPointF>
#include "KisMirrorAxisConfig.h"
class Q_DECL_HIDDEN KisMirrorAxisConfig::Private
{
public:
Private()
: mirrorHorizontal(false)
, mirrorVertical(false)
, lockHorizontal(false)
, lockVertical(false)
, hideVerticalDecoration(false)
, hideHorizontalDecoration(false)
, handleSize(32.f)
, horizontalHandlePosition(64.f)
, verticalHandlePosition(64.f)
{}
bool operator==(const Private& rhs) {
return mirrorHorizontal == rhs.mirrorHorizontal &&
mirrorVertical == rhs.mirrorVertical &&
lockHorizontal == rhs.lockHorizontal &&
lockVertical == rhs.lockVertical &&
hideHorizontalDecoration == rhs.hideHorizontalDecoration &&
hideVerticalDecoration == rhs.hideVerticalDecoration &&
handleSize == rhs.handleSize &&
horizontalHandlePosition == rhs.horizontalHandlePosition &&
verticalHandlePosition == rhs.verticalHandlePosition &&
axisPosition == rhs.axisPosition;
}
bool mirrorHorizontal;
bool mirrorVertical;
bool lockHorizontal;
bool lockVertical;
bool hideVerticalDecoration;
bool hideHorizontalDecoration;
float handleSize;
float horizontalHandlePosition;
float verticalHandlePosition;
QPointF axisPosition;
};
KisMirrorAxisConfig::KisMirrorAxisConfig()
: QObject()
, d(new Private())
{
}
KisMirrorAxisConfig::~KisMirrorAxisConfig()
{
}
KisMirrorAxisConfig::KisMirrorAxisConfig(const KisMirrorAxisConfig &rhs)
: QObject()
, d(new Private(*rhs.d))
{
}
KisMirrorAxisConfig &KisMirrorAxisConfig::operator=(const KisMirrorAxisConfig &rhs)
{
if (&rhs != this) {
*d = *rhs.d;
}
return *this;
}
bool KisMirrorAxisConfig::operator==(const KisMirrorAxisConfig &rhs) const
{
return *d == *rhs.d;
}
bool KisMirrorAxisConfig::mirrorHorizontal()
{
return d->mirrorHorizontal;
}
void KisMirrorAxisConfig::setMirrorHorizontal(bool state)
{
d->mirrorHorizontal = state;
}
bool KisMirrorAxisConfig::mirrorVertical()
{
return d->mirrorVertical;
}
void KisMirrorAxisConfig::setMirrorVertical(bool state)
{
d->mirrorVertical = state;
}
bool KisMirrorAxisConfig::lockHorizontal()
{
return d->lockHorizontal;
}
void KisMirrorAxisConfig::setLockHorizontal(bool state)
{
d->lockHorizontal = state;
}
bool KisMirrorAxisConfig::lockVertical()
{
return d->lockVertical;
}
void KisMirrorAxisConfig::setLockVertical(bool state)
{
d->lockVertical = state;
}
bool KisMirrorAxisConfig::hideVerticalDecoration()
{
return d->hideVerticalDecoration;
}
void KisMirrorAxisConfig::setHideVerticalDecoration(bool state)
{
d->hideVerticalDecoration = state;
}
bool KisMirrorAxisConfig::hideHorizontalDecoration()
{
return d->hideHorizontalDecoration;
}
void KisMirrorAxisConfig::setHideHorizontalDecoration(bool state)
{
d->hideHorizontalDecoration = state;
}
float KisMirrorAxisConfig::handleSize()
{
return d->handleSize;
}
void KisMirrorAxisConfig::setHandleSize(float size)
{
d->handleSize = size;
}
float KisMirrorAxisConfig::horizontalHandlePosition()
{
return d->horizontalHandlePosition;
}
void KisMirrorAxisConfig::setHorizontalHandlePosition(float position)
{
d->horizontalHandlePosition = position;
}
float KisMirrorAxisConfig::verticalHandlePosition()
{
return d->verticalHandlePosition;
}
void KisMirrorAxisConfig::setVerticalHandlePosition(float position)
{
d->verticalHandlePosition = position;
}
QPointF KisMirrorAxisConfig::axisPosition()
{
return d->axisPosition;
}
void KisMirrorAxisConfig::setAxisPosition(QPointF position)
{
d->axisPosition = position;
}
QDomElement KisMirrorAxisConfig::saveToXml(QDomDocument &doc, const QString &tag) const
{
QDomElement mirrorAxisElement = doc.createElement(tag);
KisDomUtils::saveValue(&mirrorAxisElement, "mirrorHorizontal", d->mirrorHorizontal);
KisDomUtils::saveValue(&mirrorAxisElement, "mirrorVertical", d->mirrorVertical);
KisDomUtils::saveValue(&mirrorAxisElement, "lockHorizontal", d->lockHorizontal);
KisDomUtils::saveValue(&mirrorAxisElement, "lockVertical", d->lockVertical);
KisDomUtils::saveValue(&mirrorAxisElement, "hideHorizontalDecoration", d->hideHorizontalDecoration);
KisDomUtils::saveValue(&mirrorAxisElement, "hideVerticalDecoration", d->hideVerticalDecoration);
KisDomUtils::saveValue(&mirrorAxisElement, "handleSize", d->handleSize);
KisDomUtils::saveValue(&mirrorAxisElement, "horizontalHandlePosition", d->horizontalHandlePosition);
KisDomUtils::saveValue(&mirrorAxisElement, "verticalHandlePosition", d->verticalHandlePosition);
KisDomUtils::saveValue(&mirrorAxisElement, "axisPosition", d->axisPosition);
return mirrorAxisElement;
}
bool KisMirrorAxisConfig::loadFromXml(const QDomElement &parent)
{
bool result = true;
result &= KisDomUtils::loadValue(parent, "mirrorHorizontal", &d->mirrorHorizontal);
result &= KisDomUtils::loadValue(parent, "mirrorVertical", &d->mirrorVertical);
result &= KisDomUtils::loadValue(parent, "lockHorizontal", &d->lockHorizontal);
result &= KisDomUtils::loadValue(parent, "lockVertical", &d->lockVertical);
result &= KisDomUtils::loadValue(parent, "hideHorizontalDecoration", &d->hideHorizontalDecoration);
result &= KisDomUtils::loadValue(parent, "hideVerticalDecoration", &d->hideVerticalDecoration);
result &= KisDomUtils::loadValue(parent, "handleSize", &d->handleSize);
result &= KisDomUtils::loadValue(parent, "horizontalHandlePosition", &d->horizontalHandlePosition);
result &= KisDomUtils::loadValue(parent, "verticalHandlePosition", &d->verticalHandlePosition);
result &= KisDomUtils::loadValue(parent, "axisPosition", &d->axisPosition);
return result;
}
bool KisMirrorAxisConfig::isDefault() const
{
KisMirrorAxisConfig defaultConfig;
return *this == defaultConfig;
}
/*
* Copyright (c) 2019 Anna Medonosova <anna.medonosova@gmail.com>
*
* 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.1 of the License.
*
* 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 KISMIRRORAXISCONFIG_H
#define KISMIRRORAXISCONFIG_H
#include <QScopedPointer>
#include "kritaui_export.h"
#include <boost/operators.hpp>
class QDomElement;
class QDomDocument;
/**
* @brief The KisMirrorAxisConfig class stores configuration for the KisMirrorAxis
* canvas decoration. Contents are saved to/loaded from KRA documents.
*/
class KRITAUI_EXPORT KisMirrorAxisConfig : public QObject, boost::equality_comparable<KisMirrorAxisConfig>
{
Q_OBJECT
public:
KisMirrorAxisConfig();
~KisMirrorAxisConfig();
KisMirrorAxisConfig(const KisMirrorAxisConfig &rhs);
KisMirrorAxisConfig& operator=(const KisMirrorAxisConfig& rhs);
bool operator==(const KisMirrorAxisConfig& rhs) const;
bool mirrorHorizontal();
void setMirrorHorizontal(bool state);
bool mirrorVertical();
void setMirrorVertical(bool state);
bool lockHorizontal();
void setLockHorizontal(bool state);
bool lockVertical();
void setLockVertical(bool state);
bool hideVerticalDecoration();
void setHideVerticalDecoration(bool state);
bool hideHorizontalDecoration();
void setHideHorizontalDecoration(bool state);
float handleSize();
void setHandleSize(float size);
float horizontalHandlePosition();
void setHorizontalHandlePosition(float position);
float verticalHandlePosition();
void setVerticalHandlePosition(float position);
QPointF axisPosition();
void setAxisPosition(QPointF position);
/**
* @brief saveToXml() function for KisKraSaver
* @param doc
* @param tag
* @return
*/
QDomElement saveToXml(QDomDocument& doc, const QString &tag) const;
/**
* @brief loadFromXml() function for KisKraLoader
* @param parent element
* @return
*/
bool loadFromXml(const QDomElement &parent);
/**
* @brief Check whether the config object was changed, or is the class default.
* @return true, if the object is default; false, if the config was changed
*/
bool isDefault() const;
private:
class Private;
const QScopedPointer<Private> d;
};
#endif // KISMIRRORAXISCONFIG_H
This diff is collapsed.
......@@ -24,6 +24,7 @@
class KisView;
class KisCanvasResourceProvider;
class KisMirrorAxisConfig;
class KisMirrorAxis : public KisCanvasDecoration
{
......@@ -38,12 +39,17 @@ public:
void setHandleSize(float newSize);
void setVisible(bool v) override;
void setMirrorAxisConfig(const KisMirrorAxisConfig& config);
const KisMirrorAxisConfig& mirrorAxisConfig() const;
Q_SIGNALS:
void handleSizeChanged();
void sigConfigChanged();
protected:
void drawDecoration(QPainter& gc, const QRectF& updateArea, const KisCoordinatesConverter* converter, KisCanvas2* canvas) override;
bool eventFilter(QObject* target, QEvent* event) override;
void toggleMirrorActions();
private:
class Private;
......
......@@ -30,8 +30,23 @@
#include "kis_canvas2.h"
#include "kis_mirror_axis.h"
#include <KisMirrorAxisConfig.h>
#include <KisDocument.h>
#include <kis_signals_blocker.h>
class KisMirrorManager::Private
{
public:
Private()
: mirrorAxisDecoration(nullptr)
{}
KisMirrorAxis* mirrorAxisDecoration;
// KisMirrorAxisConfig mirrorAxisConfig() {}
};
KisMirrorManager::KisMirrorManager(KisViewManager* view) : QObject(view)
, d(new Private())
, m_imageView(0)
{
}
......@@ -56,14 +71,20 @@ void KisMirrorManager::setView(QPointer<KisView> imageView)
{
if (m_imageView) {
m_mirrorCanvas->disconnect();
m_imageView->document()->disconnect();
}
m_imageView = imageView;
if (m_imageView) {
connect(m_mirrorCanvas, SIGNAL(toggled(bool)), dynamic_cast<KisCanvasController*>(m_imageView->canvasController()), SLOT(mirrorCanvas(bool)));
connect(m_imageView->document(), SIGNAL(sigMirrorAxisConfigChanged()), this, SLOT(slotDocumentConfigChanged()), Qt::UniqueConnection);
if (!hasDecoration()) {
m_imageView->canvasBase()->addDecoration(new KisMirrorAxis(m_imageView->viewManager()->resourceProvider(), m_imageView));
d->mirrorAxisDecoration = new KisMirrorAxis(m_imageView->viewManager()->resourceProvider(), m_imageView);
connect(d->mirrorAxisDecoration, SIGNAL(sigConfigChanged()), this, SLOT(slotMirrorAxisConfigChanged()), Qt::UniqueConnection);
m_imageView->canvasBase()->addDecoration(d->mirrorAxisDecoration);
}
d->mirrorAxisDecoration->setMirrorAxisConfig(mirrorAxisConfig());
}
updateAction();
}
......@@ -80,6 +101,19 @@ void KisMirrorManager::updateAction()
}
}
void KisMirrorManager::slotDocumentConfigChanged()
{
d->mirrorAxisDecoration->setMirrorAxisConfig(mirrorAxisConfig());
}
void KisMirrorManager::slotMirrorAxisConfigChanged()
{
if (m_imageView) {
KisSignalsBlocker blocker(m_imageView->document());
m_imageView->document()->setMirrorAxisConfig(d->mirrorAxisDecoration->mirrorAxisConfig());
}
}
KisMirrorAxis* KisMirrorManager::hasDecoration() {
if (m_imageView && m_imageView->canvasBase() && m_imageView->canvasBase()->decoration("mirror_axis")) {
......@@ -87,3 +121,8 @@ KisMirrorAxis* KisMirrorManager::hasDecoration() {
}
return 0;
}
const KisMirrorAxisConfig& KisMirrorManager::mirrorAxisConfig() const
{
return m_imageView->document()->mirrorAxisConfig();
}
......@@ -22,13 +22,14 @@
#include <QObject>
#include <QPointer>
#include <QScopedPointer>
#include "KisView.h"
class KisViewManager;
class KActionCollection;
class KisMirrorAxis;
class KisMirrorAxisConfig;
class KisMirrorManager : public QObject
{
......@@ -44,13 +45,17 @@ public:
private Q_SLOTS:
void updateAction();
void slotDocumentConfigChanged();
void slotMirrorAxisConfigChanged();
private:
class Private;
const QScopedPointer<Private> d;
QPointer<KisView> m_imageView;
QAction *m_mirrorCanvas;
KisMirrorAxis* hasDecoration();
const KisMirrorAxisConfig &mirrorAxisConfig() const;
};
#endif // KIS_PAINTING_ASSISTANTS_MANAGER_H
#endif // KIS__MANAGER_H
......@@ -879,6 +879,14 @@ void KisPaintopBox::slotCanvasResourceChanged(int key, const QVariant &value)
m_disablePressureAction->setChecked(value.toBool());
}
if (key == KisCanvasResourceProvider::MirrorHorizontal) {
m_hMirrorAction->setChecked(value.toBool());
}
if (key == KisCanvasResourceProvider::MirrorVertical) {
m_vMirrorAction->setChecked(value.toBool());
}
sender()->blockSignals(false);
}
}
......
......@@ -87,6 +87,7 @@
#include "KisProofingConfiguration.h"
#include "kis_layer_properties_icons.h"
#include "kis_node_view_color_scheme.h"
#include "KisMirrorAxisConfig.h"
/*
......@@ -356,6 +357,8 @@ KisImageSP KisKraLoader::loadXML(const KoXmlElement& element)
loadGrid(e);
} else if (e.tagName() == "guides") {
loadGuides(e);
} else if (e.tagName() == MIRROR_AXIS) {
loadMirrorAxis(e);
} else if (e.tagName() == "assistants") {
loadAssistantsList(e);
} else if (e.tagName() == "audio") {
......@@ -1180,6 +1183,17 @@ void KisKraLoader::loadGuides(const KoXmlElement& elem)
m_d->document->setGuidesConfig(guides);
}
void KisKraLoader::loadMirrorAxis(const KoXmlElement &elem)
{
QDomDocument dom;
KoXml::asQDomElement(dom, elem);
QDomElement domElement = dom.firstChildElement();
KisMirrorAxisConfig mirrorAxis;
mirrorAxis.loadFromXml(domElement);
m_d->document->setMirrorAxisConfig(mirrorAxis);
}
void KisKraLoader::loadAudio(const KoXmlElement& elem, KisImageSP image)
{
QDomDocument dom;
......
......@@ -110,6 +110,7 @@ private:
void loadAssistantsList(const KoXmlElement& elem);
void loadGrid(const KoXmlElement& elem);
void loadGuides(const KoXmlElement& elem);
void loadMirrorAxis(const KoXmlElement& elem);
void loadAudio(const KoXmlElement& elem, KisImageSP image);
private:
......
......@@ -61,6 +61,8 @@
#include "kis_guides_config.h"
#include "KisProofingConfiguration.h"
#include <KisMirrorAxisConfig.h>
#include <QFileInfo>
#include <QDir>
......@@ -138,6 +140,7 @@ QDomElement KisKraSaver::saveXML(QDomDocument& doc, KisImageSP image)
saveAssistantsList(doc, imageElement);
saveGrid(doc, imageElement);
saveGuides(doc, imageElement);
saveMirrorAxis(doc, imageElement);
saveAudio(doc, imageElement);
savePalettesToXML(doc, imageElement);
......@@ -482,6 +485,18 @@ bool KisKraSaver::saveGuides(QDomDocument& doc, QDomElement& element)
return true;
}
bool KisKraSaver::saveMirrorAxis(QDomDocument &doc, QDomElement &element)
{
KisMirrorAxisConfig mirrorAxisConfig = m_d->doc->mirrorAxisConfig();
if (!mirrorAxisConfig.isDefault()) {
QDomElement mirrorAxisElement = mirrorAxisConfig.saveToXml(doc, MIRROR_AXIS);
element.appendChild(mirrorAxisElement);
}
return true;
}
bool KisKraSaver::saveAudio(QDomDocument& doc, QDomElement& element)
{
const KisImageAnimationInterface *interface = m_d->doc->image()->animationInterface();
......
......@@ -58,6 +58,7 @@ private:
bool saveAssistantsList(QDomDocument& doc, QDomElement& element);
bool saveGrid(QDomDocument& doc, QDomElement& element);
bool saveGuides(QDomDocument& doc, QDomElement& element);
bool saveMirrorAxis(QDomDocument& doc, QDomElement& element);
bool saveAudio(QDomDocument& doc, QDomElement& element);
bool saveNodeKeyframes(KoStore *store, QString location, const KisNode *node);
void savePalettesToXML(QDomDocument& doc, QDomElement &element);
......
......@@ -137,6 +137,7 @@ const QString COLORBYTEDATA = "ColorData";
const QString SIMPLECOLORDATA = "SimpleColorData"; // easier 8-bit color data that works well with XML
const QString GLOBALASSISTANTSCOLOR = "GlobalAssistantsColor";
const QString PALETTES = "Palettes";
const QString MIRROR_AXIS = "MirrorAxis";
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment