Commit d86cf191 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Merge remote-tracking branch 'origin' into rempt/T379-resource-management

parents 63823205 fbc110c4
......@@ -69,11 +69,11 @@ endif()
# define common versions of Krita applications, used to generate kritaversion.h
# update these version for every release:
set(KRITA_VERSION_STRING "4.1.0-pre-alpha")
set(KRITA_VERSION_STRING "4.2.0-pre-alpha")
# Major version: 3 for 3.x, 4 for 4.x, etc.
set(KRITA_STABLE_VERSION_MAJOR 4)
# Minor version: 0 for 4.0, 1 for 4.1, etc.
set(KRITA_STABLE_VERSION_MINOR 1)
set(KRITA_STABLE_VERSION_MINOR 2)
# Bugfix release version, or 0 for before the first stable release
set(KRITA_VERSION_RELEASE 0)
# the 4th digit, really only used for the Windows installer:
......
......@@ -75,6 +75,20 @@ public:
return m_projection;
}
void tryCopyFrom(const KisSafeProjection &rhs) {
QMutexLocker locker(&m_lock);
if (!rhs.m_projection) return;
if (!m_reusablePaintDevice) {
m_reusablePaintDevice = new KisPaintDevice(*rhs.m_projection);
m_projection = m_reusablePaintDevice;
} else {
m_projection = m_reusablePaintDevice;
m_projection->makeCloneFromRough(rhs.m_projection, rhs.m_projection->extent());
}
}
void freeDevice() {
QMutexLocker locker(&m_lock);
m_projection = 0;
......@@ -158,6 +172,8 @@ KisLayer::KisLayer(const KisLayer& rhs)
m_d->metaDataStore = new KisMetaData::Store(*rhs.m_d->metaDataStore);
m_d->channelFlags = rhs.m_d->channelFlags;
m_d->safeProjection.tryCopyFrom(rhs.m_d->safeProjection);
setName(rhs.name());
m_d->projectionPlane = toQShared(new KisLayerProjectionPlane(this));
......
......@@ -34,7 +34,7 @@ public:
: KisExportCheckBase(id, level, customWarning)
{
if (customWarning.isEmpty()) {
m_warning = i18nc("image conversion warning", "The image has <b>more than one layer</b>. Only the flattened image will be saved.");
m_warning = i18nc("image conversion warning", "The image has <b>more than one layer or a mask or an active selection</b>. Only the flattened image will be saved.");
}
}
......
......@@ -74,7 +74,7 @@ void KisDecorationsManager::setView(QPointer<KisView> imageView)
}
if (m_imageView && !referenceImagesDecoration()) {
KisReferenceImagesDecoration *deco = new KisReferenceImagesDecoration(m_imageView);
KisReferenceImagesDecoration *deco = new KisReferenceImagesDecoration(m_imageView, imageView->document());
m_imageView->canvasBase()->addDecoration(deco);
}
......
......@@ -1702,26 +1702,21 @@ void KisDocument::setAssistants(const QList<KisPaintingAssistantSP> &value)
d->assistants = value;
}
KisSharedPtr<KisReferenceImagesLayer> KisDocument::getOrCreateReferenceImagesLayer(KisImageSP targetImage)
{
if (!d->referenceImagesLayer) {
if (targetImage.isNull()) targetImage = d->image;
d->referenceImagesLayer = new KisReferenceImagesLayer(shapeController(), targetImage);
targetImage->addNode(d->referenceImagesLayer, targetImage->root());
}
return d->referenceImagesLayer;
}
// TODO: change signature to return a shared pointer
KisReferenceImagesLayer *KisDocument::referenceImagesLayer() const
KisSharedPtr<KisReferenceImagesLayer> KisDocument::referenceImagesLayer() const
{
return d->referenceImagesLayer.data();
}
void KisDocument::setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer)
void KisDocument::setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer, bool updateImage)
{
if (updateImage) {
if (layer) {
d->image->addNode(layer);
} else {
d->image->removeNode(d->referenceImagesLayer);
}
}
d->referenceImagesLayer = layer;
}
......
......@@ -590,19 +590,12 @@ public:
/// @replace the current list of assistants with @param value
void setAssistants(const QList<KisPaintingAssistantSP> &value);
/**
* Get existing reference images layer or create new if none exists.
*
* TODO: use setReferenceImagesLayer() combined with undo commands instead
*/
KRITAUI_DEPRECATED KisSharedPtr<KisReferenceImagesLayer> getOrCreateReferenceImagesLayer(KisImageSP targetImage = KisImageSP());
/**
* Get existing reference images layer or null if none exists.
*/
KisReferenceImagesLayer *referenceImagesLayer() const;
KisSharedPtr<KisReferenceImagesLayer> referenceImagesLayer() const;
void setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer);
void setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer, bool updateImage);
bool save(bool showWarnings, KisPropertiesConfigurationSP exportConfiguration);
......
......@@ -423,7 +423,7 @@ bool KisImportExportManager::askUserAboutExportConfiguration(
{
// prevents the animation renderer from running this code
if (QThread::currentThread() != qApp->thread()) return false;
const QString mimeUserDescription = KisMimeDatabase::descriptionForMimeType(to);
......@@ -438,7 +438,11 @@ bool KisImportExportManager::askUserAboutExportConfiguration(
errors = checker.errors();
}
KisConfigWidget *wdg = filter->createConfigurationWidget(0, from, to);
KisConfigWidget *wdg = 0;
if (QThread::currentThread() == qApp->thread()) {
wdg = filter->createConfigurationWidget(0, from, to);
}
// 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()) {
......
......@@ -71,6 +71,8 @@ private:
const QRectF boundingWidgetRect = q->view()->viewConverter()->imageToWidget(boundingImageRect);
widgetRect = boundingWidgetRect.intersected(q->view()->rect());
if (widgetRect.isNull()) return;
buffer.position = widgetRect.topLeft();
buffer.image = QImage(widgetRect.size().toSize(), QImage::Format_ARGB32);
buffer.image.fill(Qt::transparent);
......@@ -93,21 +95,26 @@ private:
}
};
KisReferenceImagesDecoration::KisReferenceImagesDecoration(QPointer<KisView> parent)
KisReferenceImagesDecoration::KisReferenceImagesDecoration(QPointer<KisView> parent, KisDocument *document)
: KisCanvasDecoration("referenceImagesDecoration", parent)
, d(new Private(this))
{}
{
connect(document->image().data(), SIGNAL(sigNodeAddedAsync(KisNodeSP)), this, SLOT(slotNodeAdded(KisNodeSP)));
auto referenceImageLayer = document->referenceImagesLayer();
if (referenceImageLayer) {
setReferenceImageLayer(referenceImageLayer);
}
}
KisReferenceImagesDecoration::~KisReferenceImagesDecoration()
{}
void KisReferenceImagesDecoration::addReferenceImage(KisReferenceImage *referenceImage)
{
KisSharedPtr<KisReferenceImagesLayer> layer = view()->document()->getOrCreateReferenceImagesLayer();
KIS_SAFE_ASSERT_RECOVER_RETURN(layer);
KUndo2Command *cmd = layer->addReferenceImage(referenceImage);
view()->document()->addCommand(cmd);
KisDocument *document = view()->document();
KUndo2Command *cmd = KisReferenceImagesLayer::addReferenceImages(document, {referenceImage});
document->addCommand(cmd);
}
bool KisReferenceImagesDecoration::documentHasReferenceImages() const
......@@ -118,22 +125,25 @@ bool KisReferenceImagesDecoration::documentHasReferenceImages() const
void KisReferenceImagesDecoration::drawDecoration(QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter */*converter*/, KisCanvas2 */*canvas*/)
{
KisSharedPtr<KisReferenceImagesLayer> layer = d->layer.toStrongRef();
if (layer.isNull()) {
layer = d->layer = view()->document()->referenceImagesLayer();
if (layer.isNull()) return;
connect(layer.data(), SIGNAL(sigUpdateCanvas(const QRectF&)), this, SLOT(slotReferenceImagesChanged(const QRectF&)));
d->updateBufferByWidgetCoordinates(updateRect);
} else {
if (!layer.isNull()) {
QTransform transform = view()->viewConverter()->imageToWidgetTransform();
if (!KisAlgebra2D::fuzzyMatrixCompare(transform, d->previousTransform, 1e-4)) {
d->previousTransform = transform;
d->updateBufferByWidgetCoordinates(QRectF(0, 0, view()->width(), view()->height()));
}
gc.drawImage(d->buffer.position, d->buffer.image);
}
}
void KisReferenceImagesDecoration::slotNodeAdded(KisNodeSP node)
{
auto *referenceImagesLayer = dynamic_cast<KisReferenceImagesLayer*>(node.data());
gc.drawImage(d->buffer.position, d->buffer.image);
if (referenceImagesLayer) {
setReferenceImageLayer(referenceImagesLayer);
}
}
void KisReferenceImagesDecoration::slotReferenceImagesChanged(const QRectF &dirtyRect)
......@@ -143,3 +153,12 @@ void KisReferenceImagesDecoration::slotReferenceImagesChanged(const QRectF &dirt
QRectF documentRect = view()->viewConverter()->imageToDocument(dirtyRect);
view()->canvasBase()->updateCanvas(documentRect);
}
void KisReferenceImagesDecoration::setReferenceImageLayer(KisSharedPtr<KisReferenceImagesLayer> layer)
{
d->layer = layer;
connect(
layer.data(), SIGNAL(sigUpdateCanvas(const QRectF&)),
this, SLOT(slotReferenceImagesChanged(const QRectF&))
);
}
......@@ -26,6 +26,7 @@
#include <kis_shared_ptr.h>
class KisReferenceImagesDecoration;
class KisReferenceImagesLayer;
typedef KisSharedPtr<KisReferenceImagesDecoration> KisReferenceImagesDecorationSP;
#include <kis_coordinates_converter.h>
......@@ -41,7 +42,7 @@ class KisReferenceImagesDecoration : public KisCanvasDecoration
{
Q_OBJECT
public:
KisReferenceImagesDecoration(QPointer<KisView> parent);
KisReferenceImagesDecoration(QPointer<KisView> parent, KisDocument *document);
~KisReferenceImagesDecoration() override;
void addReferenceImage(KisReferenceImage *referenceImage);
......@@ -49,6 +50,7 @@ public:
bool documentHasReferenceImages() const;
private Q_SLOTS:
void slotNodeAdded(KisNodeSP);
void slotReferenceImagesChanged(const QRectF &dirtyRect);
protected:
......@@ -57,6 +59,8 @@ protected:
private:
struct Private;
const QScopedPointer<Private> d;
void setReferenceImageLayer(KisSharedPtr<KisReferenceImagesLayer> layer);
};
#endif // KISREFERENCEIMAGESDECORATION_H
......@@ -115,7 +115,7 @@ public:
, canvas(&viewConverter, resourceManager, _q, document->shapeController())
, zoomManager(_q, &this->viewConverter, &this->canvasController)
, paintingAssistantsDecoration(new KisPaintingAssistantsDecoration(_q))
, referenceImagesDecoration(new KisReferenceImagesDecoration(_q))
, referenceImagesDecoration(new KisReferenceImagesDecoration(_q, document))
, floatingMessageCompressor(100, KisSignalCompressor::POSTPONE)
{
}
......
......@@ -245,6 +245,8 @@ void KisDisplayColorConverter::Private::setCurrentNode(KisNodeSP node)
}
}
nodeColorSpace = 0;
if (node) {
KisPaintDeviceSP device = findValidDevice(node);
......@@ -252,7 +254,7 @@ void KisDisplayColorConverter::Private::setCurrentNode(KisNodeSP node)
device->compositionSourceColorSpace() :
node->colorSpace();
KIS_ASSERT_RECOVER_NOOP(nodeColorSpace);
KIS_SAFE_ASSERT_RECOVER_NOOP(nodeColorSpace);
if (device) {
q->connect(device, SIGNAL(profileChanged(const KoColorProfile*)),
......@@ -261,7 +263,9 @@ void KisDisplayColorConverter::Private::setCurrentNode(KisNodeSP node)
SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
}
} else {
}
if (!nodeColorSpace) {
nodeColorSpace = KoColorSpaceRegistry::instance()->rgb8();
}
......
......@@ -18,30 +18,78 @@
*/
#include <KoShapeCreateCommand.h>
#include <KoShapeDeleteCommand.h>
#include <kis_node_visitor.h>
#include <kis_processing_visitor.h>
#include <kis_shape_layer_canvas.h>
#include "KisReferenceImagesLayer.h"
#include "KisReferenceImage.h"
#include "KisDocument.h"
struct AddReferenceImageCommand : KoShapeCreateCommand
struct AddReferenceImagesCommand : KoShapeCreateCommand
{
AddReferenceImageCommand(KisReferenceImagesLayer *layer, KisReferenceImage* referenceImage)
: KoShapeCreateCommand(layer->shapeController(), {referenceImage}, layer, nullptr, kundo2_i18n("Add reference image"))
AddReferenceImagesCommand(KisDocument *document, KisSharedPtr<KisReferenceImagesLayer> layer, const QList<KoShape*> referenceImages)
: KoShapeCreateCommand(layer->shapeController(), referenceImages, layer.data(), nullptr, kundo2_i18n("Add reference image"))
, m_document(document)
, m_layer(layer)
{}
void redo() override {
auto layer = m_document->referenceImagesLayer();
KIS_SAFE_ASSERT_RECOVER_NOOP(!layer || layer == m_layer)
if (!layer) {
m_document->setReferenceImagesLayer(m_layer, true);
}
KoShapeCreateCommand::redo();
}
void undo() override {
KoShapeCreateCommand::undo();
if (m_layer->shapeCount() == 0) {
m_document->setReferenceImagesLayer(nullptr, true);
}
}
private:
KisReferenceImagesLayer *m_layer;
KisDocument *m_document;
KisSharedPtr<KisReferenceImagesLayer> m_layer;
};
struct RemoveReferenceImagesCommand : KoShapeDeleteCommand
{
RemoveReferenceImagesCommand(KisDocument *document, KisSharedPtr<KisReferenceImagesLayer> layer, QList<KoShape *> referenceImages)
: KoShapeDeleteCommand(layer->shapeController(), referenceImages)
, m_document(document)
, m_layer(layer)
{}
void redo() override {
KoShapeDeleteCommand::redo();
if (m_layer->shapeCount() == 0) {
m_document->setReferenceImagesLayer(nullptr, true);
}
}
void undo() override {
auto layer = m_document->referenceImagesLayer();
KIS_SAFE_ASSERT_RECOVER_NOOP(!layer || layer == m_layer)
if (!layer) {
m_document->setReferenceImagesLayer(m_layer, true);
}
KoShapeDeleteCommand::undo();
}
private:
KisDocument *m_document;
KisSharedPtr<KisReferenceImagesLayer> m_layer;
};
class ReferenceImagesCanvas : public KisShapeLayerCanvasBase
......@@ -83,9 +131,19 @@ KisReferenceImagesLayer::KisReferenceImagesLayer(const KisReferenceImagesLayer &
: KisShapeLayer(rhs, rhs.shapeController(), new ReferenceImagesCanvas(this, rhs.image()))
{}
KUndo2Command * KisReferenceImagesLayer::addReferenceImage(KisReferenceImage *referenceImage)
KUndo2Command * KisReferenceImagesLayer::addReferenceImages(KisDocument *document, const QList<KoShape*> referenceImages)
{
KisSharedPtr<KisReferenceImagesLayer> layer = document->referenceImagesLayer();
if (!layer) {
layer = new KisReferenceImagesLayer(document->shapeController(), document->image());
}
return new AddReferenceImagesCommand(document, layer, referenceImages);
}
KUndo2Command * KisReferenceImagesLayer::removeReferenceImages(KisDocument *document, QList<KoShape*> referenceImages)
{
return new AddReferenceImageCommand(this, referenceImage);
return new RemoveReferenceImagesCommand(document, this, referenceImages);
}
QVector<KisReferenceImage*> KisReferenceImagesLayer::referenceImages() const
......
......@@ -32,7 +32,8 @@ public:
KisReferenceImagesLayer(KoShapeBasedDocumentBase* shapeController, KisImageWSP image);
KisReferenceImagesLayer(const KisReferenceImagesLayer &rhs);
KUndo2Command * addReferenceImage(KisReferenceImage *referenceImage);
static KUndo2Command * addReferenceImages(KisDocument *document, QList<KoShape*> referenceImages);
KUndo2Command * removeReferenceImages(KisDocument *document, QList<KoShape*> referenceImages);
QVector<KisReferenceImage*> referenceImages() const;
QRectF boundingImageRect() const;
......@@ -58,8 +59,9 @@ Q_SIGNALS:
private:
void signalUpdate(const QRectF &rect);
friend struct AddReferenceImageCommand;
friend struct ReferenceImagesCanvas;
friend struct AddReferenceImagesCommand;
friend struct RemoveReferenceImagesCommand;
friend class ReferenceImagesCanvas;
};
......
......@@ -104,6 +104,8 @@ void KisDummiesFacadeBase::slotLayersChanged()
void KisDummiesFacadeBase::slotNodeActivationRequested(KisNodeSP node)
{
if (!node->graphListener()) return;
if (!node->inherits("KisSelectionMask") && !node->inherits("KisReferenceImagesLayer")) {
emit sigActivateNode(node);
}
......
......@@ -623,6 +623,11 @@ void KisNodeManager::slotSomethingActivatedNodeImpl(KisNodeSP node)
void KisNodeManager::slotNonUiActivatedNode(KisNodeSP node)
{
if (node == activeNode()) return;
// the node must still be in the graph, some asynchronous
// signals may easily break this requirement
KIS_SAFE_ASSERT_RECOVER_RETURN(!node || node->graphListener());
slotSomethingActivatedNodeImpl(node);
if (node) {
......@@ -637,6 +642,10 @@ void KisNodeManager::slotUiActivatedNode(KisNodeSP node)
{
if (node == activeNode()) return;
// the node must still be in the graph, some asynchronous
// signals may easily break this requirement
KIS_SAFE_ASSERT_RECOVER_RETURN(!node || node->graphListener());
slotSomethingActivatedNodeImpl(node);
if (node) {
......
......@@ -383,7 +383,7 @@ void KisToolPaint::addPickerJob(const PickingJob &pickingJob)
if (!fromCurrentNode) {
auto *kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
KIS_SAFE_ASSERT_RECOVER_RETURN(kisCanvas);
auto *referencesLayer = kisCanvas->imageView()->document()->referenceImagesLayer();
KisSharedPtr<KisReferenceImagesLayer> referencesLayer = kisCanvas->imageView()->document()->referenceImagesLayer();
if (referencesLayer) {
QColor color = referencesLayer->getPixel(imagePoint);
if (color.isValid() && color.alpha() != 0) {
......
......@@ -329,6 +329,8 @@ void KoResourceTaggingManager::tagSearchLineEditTextChanged(const QString& lineE
///FIXME: fix completer
// d->tagCompleter = new QCompleter(tagNamesList(lineEditText),this);
// d->tagSearchLineEdit->setCompleter(d->tagCompleter);
emit updateView();
}
void KoResourceTaggingManager::tagSaveButtonPressed()
......
......@@ -280,6 +280,7 @@ bool Python::libraryLoad()
s_pythonLibrary = 0;
return false;
}
dbgScript << QString("Loaded %1").arg(s_pythonLibrary->fileName());
}
#endif
return true;
......@@ -318,7 +319,7 @@ bool Python::setPath(const QStringList& scriptPaths)
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!Py_IsInitialized(), false);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!isPythonPathSet, false);
bool runningInBundle = (KoResourcePaths::getApplicationRoot().toLower().contains(".mount_krita") || KoResourcePaths::getApplicationRoot().toLower().contains("krita.app"));
bool runningInBundle = ((!qgetenv("APPDIR").isNull() && KoResourcePaths::getApplicationRoot().toLower().contains(qgetenv("APPDIR"))) || KoResourcePaths::getApplicationRoot().toLower().contains("krita.app"));
dbgScript << "Python::setPath. Script paths:" << scriptPaths << runningInBundle;
#ifdef Q_OS_WIN
......@@ -367,7 +368,7 @@ bool Python::setPath(const QStringList& scriptPaths)
}
#else
// If using a system Python install, respect the current PYTHONPATH
if (KoResourcePaths::getApplicationRoot().toLower().contains(".mount_krita")) {
if (runningInBundle) {
// We're running from an appimage, so we need our local python
QString p = QFileInfo(PYKRITA_PYTHON_LIBRARY).fileName();
QString p2 = p.remove("lib").remove("m.so");
......@@ -393,12 +394,10 @@ bool Python::setPath(const QStringList& scriptPaths)
joinedPaths.toWCharArray(joinedPathsWChars.data());
Py_SetPath(joinedPathsWChars.data());
#else
if (KoResourcePaths::getApplicationRoot().contains(".mount_Krita")) {
if (runningInBundle) {
QVector<wchar_t> joinedPathsWChars(joinedPaths.size() + 1, 0);
joinedPaths.toWCharArray(joinedPathsWChars.data());
PyRun_SimpleString("import sys; import os");
QString pathCommand = QString("sys.path += '") + joinedPaths + QString("'.split(os.pathsep)");
PyRun_SimpleString(pathCommand.toUtf8().constData());
Py_SetPath(joinedPathsWChars.data());
}
else {
qputenv("PYTHONPATH", joinedPaths.toLocal8Bit());
......
......@@ -1184,7 +1184,7 @@ KisNodeSP KisKraLoader::loadReferenceImagesLayer(const KoXmlElement &elem, KisIm
KisSharedPtr<KisReferenceImagesLayer> layer =
new KisReferenceImagesLayer(m_d->document->shapeController(), image);
m_d->document->setReferenceImagesLayer(layer);
m_d->document->setReferenceImagesLayer(layer, false);
for (QDomElement child = elem.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) {
if (child.nodeName().toLower() == "referenceimage") {
......
......@@ -5,7 +5,7 @@ X-KDE-Library=highpass
X-Python-2-Compatible=false
Name=Highpass Filter
Name[ca]=Filtre passaalt
Name[ca@valencia]=Filtre passa-alt
Name[ca@valencia]=Filtre passaalt
Name[cs]=Filtr s horní propustí
Name[de]=Hochpassfilter
Name[el]=Υψιπερατό φίλτρο
......@@ -25,7 +25,7 @@ Name[zh_CN]=高通滤镜
Name[zh_TW]=高通濾鏡
Comment=Highpass Filter, based on http://registry.gimp.org/node/7385
Comment[ca]=Filtre passaalt, basat en el http://registry.gimp.org/node/7385
Comment[ca@valencia]=Filtre passa-alt, basat en el http://registry.gimp.org/node/7385
Comment[ca@valencia]=Filtre passaalt, basat en el http://registry.gimp.org/node/7385
Comment[cs]=Filtr s horní propustí založený na http://registry.gimp.org/node/7385
Comment[de]=Hochpassfilter, Grundlage ist http://registry.gimp.org/node/7385
Comment[el]=Υψιπερατό φίλτρο, με βάση το http://registry.gimp.org/node/7385
......
......@@ -99,7 +99,7 @@ void KisToolColorPicker::pickColor(const QPointF &pos)
if (m_optionsWidget->cmbSources->currentIndex() == SAMPLE_MERGED) {
auto *kisCanvas = dynamic_cast<KisCanvas2 *>(canvas());
KIS_SAFE_ASSERT_RECOVER_RETURN(kisCanvas);
KisReferenceImagesLayer *referenceImageLayer =
KisSharedPtr<KisReferenceImagesLayer> referenceImageLayer =
kisCanvas->imageView()->document()->referenceImagesLayer();
if (referenceImageLayer) {
......
......@@ -24,6 +24,7 @@
#include <QMessageBox>
#include <QVector>
#include <KoSelection.h>
#include <KoShapeRegistry.h>
#include <KoShapeManager.h>
#include <KoShapeController.h>
......@@ -34,6 +35,7 @@
#include <KisViewManager.h>
#include <KisDocument.h>
#include <KisReferenceImagesLayer.h>
#include <kis_image.h>
#include "ToolReferenceImagesWidget.h"
#include "KisReferenceImageCollection.h"
......@@ -50,11 +52,15 @@ ToolReferenceImages::~ToolReferenceImages()
void ToolReferenceImages::activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes)
{
// Add code here to initialize your tool when it got activated
DefaultTool::activate(toolActivation, shapes);
KisReferenceImagesLayer *layer = getOrCreateReferenceImagesLayer();
connect(layer, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()));
auto kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
connect(kisCanvas->image(), SIGNAL(sigNodeAddedAsync(KisNodeSP)), this, SLOT(slotNodeAdded(KisNodeSP)));
auto referenceImageLayer = document()->referenceImagesLayer();
if (referenceImageLayer) {
setReferenceImageLayer(referenceImageLayer);
}
}
void ToolReferenceImages::deactivate()
......@@ -62,6 +68,21 @@ void ToolReferenceImages::deactivate()
DefaultTool::deactivate();
}
void ToolReferenceImages::slotNodeAdded(KisNodeSP node)
{
auto *referenceImagesLayer = dynamic_cast<KisReferenceImagesLayer*>(node.data());
if (referenceImagesLayer) {
setReferenceImageLayer(referenceImagesLayer);
}
}
void ToolReferenceImages::setReferenceImageLayer(KisSharedPtr<KisReferenceImagesLayer> layer)
{
m_layer = layer;
connect(layer.data(), SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()));
}
void ToolReferenceImages::addReferenceImage()
{
auto kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
......@@ -80,19 +101,22 @@ void ToolReferenceImages::addReferenceImage()
if (!QFileInfo(filename).exists()) return;
auto *reference = KisReferenceImage::fromFile(filename, *kisCanvas->coordinatesConverter());
KisReferenceImagesLayer *layer = getOrCreateReferenceImagesLayer();
kisCanvas->imageView()->document()->addCommand(layer->addReferenceImage(reference));
KisDocument *doc = document();
doc->addCommand(KisReferenceImagesLayer::addReferenceImages(doc, {reference}));
}
void ToolReferenceImages::removeAllReferenceImages()
{
KisReferenceImagesLayer *layer = getOrCreateReferenceImagesLayer();
canvas()->addCommand(canvas()->shapeController()->removeShapes(layer->shapes()));
auto layer = m_layer.toStrongRef();
if (!layer) return;
canvas()->addCommand(layer->removeReferenceImages(document(), layer->shapes()));
}
void ToolReferenceImages::loadReferenceImages()
{
auto kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
auto kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
KIS_ASSERT_RECOVER_RETURN(kisCanvas)
KoFileDialog dialog(kisCanvas->viewManager()->mainWindow(), KoFileDialog::OpenFile, "OpenReferenceImageCollection");
......@@ -116,11 +140,13 @@ void ToolReferenceImages::loadReferenceImages()
KisReferenceImageCollection collection;
if (collection.load(&file)) {
KisReferenceImagesLayer *layer = referenceImagesLayer();
Q_FOREACH(KisReferenceImage *reference, collection.referenceImages()) {
layer->addShape(reference);
QList<KoShape*> shapes;
Q_FOREACH(auto *reference, collection.referenceImages()) {
shapes.append(reference);
}
KisDocument *doc = document();
doc->addCommand(KisReferenceImagesLayer::addReferenceImages(doc, shapes));
} else {
QMessageBox::critical(nullptr, i18nc("@title:window", "Krita"), i18n("Could not load reference images from '%1'.", filename));
}
......@@ -129,6 +155,9 @@ void ToolReferenceImages::loadReferenceImages()
void ToolReferenceImages::saveReferenceImages()
{
auto layer = m_layer.toStrongRef();
if (!layer || layer->shapeCount() == 0) return;
auto kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
KIS_ASSERT_RECOVER_RETURN(kisCanvas)
......@@ -150,7 +179,7 @@ void ToolReferenceImages::saveReferenceImages()
return;
}
KisReferenceImageCollection collection(referenceImagesLayer()->referenceImages());
KisReferenceImageCollection collection(layer->referenceImages());
bool ok = collection.save(&file);
file.close();
......@@ -161,7 +190,9 @@ void ToolReferenceImages::saveReferenceImages()
void ToolReferenceImages::slotSelectionChanged()
{
KisReferenceImagesLayer *layer = getOrCreateReferenceImagesLayer();
auto layer = m_layer.toStrongRef();
if (!layer) return;
m_optionsWidget->selectionChanged(layer->shapeManager()->selection());
updateActions();
}
......@@ -192,24 +223,8 @@ bool ToolReferenceImages::isValidForCurrentLayer() const
KoShapeManager *ToolReferenceImages::shapeManager() const
{
auto layer = referenceImagesLayer();
return layer ? referenceImagesLayer()->shapeManager() : nullptr;
}
KisReferenceImagesLayer *ToolReferenceImages::referenceImagesLayer() const
{
auto kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
KisDocument *document = kisCanvas->imageView()->document();