File indexing completed on 2024-05-12 15:59:07

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 #include <QUrl>
0007 #include <QScopedPointer>
0008 #include <QUuid>
0009 
0010 #include <KoColorSpace.h>
0011 #include <KoColorSpaceRegistry.h>
0012 #include <KoColorTransformation.h>
0013 
0014 #include <KisDocument.h>
0015 #include <KisMimeDatabase.h>
0016 #include <KisPart.h>
0017 #include <kis_image.h>
0018 #include <kis_types.h>
0019 #include <kis_node.h>
0020 #include <kis_paint_layer.h>
0021 #include <kis_group_layer.h>
0022 #include <kis_file_layer.h>
0023 #include <kis_adjustment_layer.h>
0024 #include <kis_generator_layer.h>
0025 #include <kis_clone_layer.h>
0026 #include <kis_shape_layer.h>
0027 #include <KisReferenceImagesLayer.h>
0028 #include <kis_transparency_mask.h>
0029 #include <kis_filter_mask.h>
0030 #include <kis_transform_mask.h>
0031 #include <kis_selection_mask.h>
0032 #include <lazybrush/kis_colorize_mask.h>
0033 #include <kis_layer.h>
0034 #include <kis_meta_data_merge_strategy.h>
0035 #include <kis_meta_data_merge_strategy_registry.h>
0036 #include <kis_filter_strategy.h>
0037 #include <commands/kis_node_compositeop_command.h>
0038 #include <commands/kis_image_layer_add_command.h>
0039 #include <commands/kis_image_layer_remove_command.h>
0040 #include <commands_new/kis_set_layer_style_command.h>
0041 #include <kis_processing_applicator.h>
0042 #include <kis_asl_layer_style_serializer.h>
0043 
0044 #include <kis_raster_keyframe_channel.h>
0045 #include <kis_keyframe.h>
0046 #include "kis_selection.h"
0047 
0048 #include "InfoObject.h"
0049 #include "Krita.h"
0050 #include "Node.h"
0051 #include "Channel.h"
0052 #include "Filter.h"
0053 #include "Selection.h"
0054 
0055 #include "GroupLayer.h"
0056 #include "CloneLayer.h"
0057 #include "FilterLayer.h"
0058 #include "FillLayer.h"
0059 #include "FileLayer.h"
0060 #include "VectorLayer.h"
0061 #include "FilterMask.h"
0062 #include "SelectionMask.h"
0063 #include "TransformMask.h"
0064 
0065 #include "LibKisUtils.h"
0066 
0067 struct Node::Private {
0068     Private() {}
0069     KisImageWSP image;
0070     KisNodeSP node;
0071 };
0072 
0073 Node::Node(KisImageSP image, KisNodeSP node, QObject *parent)
0074     : QObject(parent)
0075     , d(new Private)
0076 {
0077     d->image = image;
0078     d->node = node;
0079 }
0080 
0081 Node *Node::createNode(KisImageSP image, KisNodeSP node, QObject *parent)
0082 {
0083     if (node.isNull()) {
0084         return 0;
0085     }
0086     if (node->inherits("KisGroupLayer")) {
0087         return new GroupLayer(dynamic_cast<KisGroupLayer*>(node.data()));
0088     }
0089     else if (node->inherits("KisCloneLayer")) {
0090         return new CloneLayer(dynamic_cast<KisCloneLayer*>(node.data()));
0091     }
0092     else if (node->inherits("KisFileLayer")) {
0093         return new FileLayer(dynamic_cast<KisFileLayer*>(node.data()));
0094     }
0095     else if (node->inherits("KisAdjustmentLayer")) {
0096         return new FilterLayer(dynamic_cast<KisAdjustmentLayer*>(node.data()));
0097     }
0098     else if (node->inherits("KisGeneratorLayer")) {
0099         return new FillLayer(dynamic_cast<KisGeneratorLayer*>(node.data()));
0100     }
0101     else if (node->inherits("KisShapeLayer")) {
0102         return new VectorLayer(dynamic_cast<KisShapeLayer*>(node.data()));
0103     }
0104     else if (node->inherits("KisFilterMask")) {
0105         return new FilterMask(image, dynamic_cast<KisFilterMask*>(node.data()));
0106     }
0107     else if (node->inherits("KisSelectionMask")) {
0108         return new SelectionMask(image, dynamic_cast<KisSelectionMask*>(node.data()));
0109     }
0110     else if (node->inherits("KisTransformMask")) {
0111         return new TransformMask(image, dynamic_cast<KisTransformMask*>(node.data()));
0112     }
0113     else {
0114         return new Node(image, node, parent);
0115     }
0116 }
0117 
0118 Node::~Node()
0119 {
0120     delete d;
0121 }
0122 
0123 bool Node::operator==(const Node &other) const
0124 {
0125     return (d->node == other.d->node
0126             && d->image == other.d->image);
0127 }
0128 
0129 bool Node::operator!=(const Node &other) const
0130 {
0131     return !(operator==(other));
0132 }
0133 
0134 Node *Node::clone() const
0135 {
0136     KisNodeSP clone = d->node->clone();
0137     Node *node = Node::createNode(0, clone);
0138     return node;
0139 }
0140 
0141 
0142 bool Node::alphaLocked() const
0143 {
0144     if (!d->node) return false;
0145     KisPaintLayerSP paintLayer = qobject_cast<KisPaintLayer*>(d->node.data());
0146     if (paintLayer) {
0147         return paintLayer->alphaLocked();
0148     }
0149     return false;
0150 }
0151 
0152 void Node::setAlphaLocked(bool value)
0153 {
0154     if (!d->node) return;
0155     KisPaintLayerSP paintLayer = qobject_cast<KisPaintLayer*>(d->node.data());
0156     if (paintLayer) {
0157         paintLayer->setAlphaLocked(value);
0158     }
0159 }
0160 
0161 
0162 QString Node::blendingMode() const
0163 {
0164     if (!d->node) return QString();
0165 
0166     return d->node->compositeOpId();
0167 }
0168 
0169 void Node::setBlendingMode(QString value)
0170 {
0171     if (!d->node) return;
0172 
0173     KUndo2Command *cmd = new KisNodeCompositeOpCommand(d->node,
0174                                                        value);
0175 
0176     KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
0177     d->image->waitForDone();
0178 }
0179 
0180 
0181 QList<Channel*> Node::channels() const
0182 {
0183     QList<Channel*> channels;
0184 
0185     if (!d->node) return channels;
0186     if (!d->node->inherits("KisLayer")) return channels;
0187 
0188     Q_FOREACH(KoChannelInfo *info, d->node->colorSpace()->channels()) {
0189         Channel *channel = new Channel(d->node, info);
0190         channels << channel;
0191     }
0192 
0193     return channels;
0194 }
0195 
0196 QList<Node*> Node::childNodes() const
0197 {
0198     QList<Node*> nodes;
0199     if (d->node) {
0200         KisNodeList nodeList;
0201         int childCount = d->node->childCount();
0202         for (int i = 0; i < childCount; ++i) {
0203             nodeList << d->node->at(i);
0204         }
0205         nodes = LibKisUtils::createNodeList(nodeList, d->image);
0206     }
0207     return nodes;
0208 }
0209 
0210 bool Node::addChildNode(Node *child, Node *above)
0211 {
0212     if (!d->node) return false;
0213 
0214     KUndo2Command *cmd = 0;
0215 
0216     if (above) {
0217         cmd = new KisImageLayerAddCommand(d->image, child->node(), d->node, above->node());
0218     } else {
0219         cmd = new KisImageLayerAddCommand(d->image, child->node(), d->node, d->node->childCount());
0220     }
0221 
0222     KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
0223     d->image->waitForDone();
0224 
0225     return true;
0226 }
0227 
0228 bool Node::removeChildNode(Node *child)
0229 {
0230     if (!d->node) return false;
0231     return child->remove();
0232 }
0233 
0234 void Node::setChildNodes(QList<Node*> nodes)
0235 {
0236     if (!d->node) return;
0237     KisNodeSP node = d->node->firstChild();
0238     while (node) {
0239         d->image->removeNode(node);
0240         node = node->nextSibling();
0241     }
0242     Q_FOREACH(Node *node, nodes) {
0243         d->image->addNode(node->node(), d->node);
0244     }
0245 }
0246 
0247 int Node::colorLabel() const
0248 {
0249     if (!d->node) return 0;
0250     return d->node->colorLabelIndex();
0251 }
0252 
0253 void Node::setColorLabel(int index)
0254 {
0255     if (!d->node) return;
0256     d->node->setColorLabelIndex(index);
0257 }
0258 
0259 QString Node::colorDepth() const
0260 {
0261     if (!d->node) return "";
0262     if (!d->node->projection()) return d->node->colorSpace()->colorDepthId().id();
0263     return d->node->projection()->colorSpace()->colorDepthId().id();
0264 }
0265 
0266 QString Node::colorModel() const
0267 {
0268     if (!d->node) return "";
0269     if (!d->node->projection()) return d->node->colorSpace()->colorModelId().id();
0270     return d->node->projection()->colorSpace()->colorModelId().id();
0271 }
0272 
0273 
0274 QString Node::colorProfile() const
0275 {
0276     if (!d->node) return "";
0277     if (!d->node->projection()) return d->node->colorSpace()->profile()->name();
0278     return d->node->projection()->colorSpace()->profile()->name();
0279 }
0280 
0281 bool Node::setColorProfile(const QString &colorProfile)
0282 {
0283     if (!d->node) return false;
0284     if (!d->node->inherits("KisLayer")) return false;
0285     KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
0286     const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(colorProfile);
0287     bool result = d->image->assignLayerProfile(layer, profile);
0288     d->image->waitForDone();
0289     return result;
0290 }
0291 
0292 bool Node::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
0293 {
0294     if (!d->node) return false;
0295     if (!d->node->inherits("KisLayer")) return false;
0296     const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(colorProfile);
0297     if (!profile) return false;
0298     const KoColorSpace *dstCs = KoColorSpaceRegistry::instance()->colorSpace(colorModel,
0299                                                                              colorDepth,
0300                                                                              profile);
0301     d->image->convertLayerColorSpace(d->node, dstCs, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
0302     d->image->waitForDone();
0303     return true;
0304 }
0305 
0306 bool Node::animated() const
0307 {
0308     if (!d->node) return false;
0309     return d->node->isAnimated();
0310 }
0311 
0312 void Node::enableAnimation() const
0313 {
0314     if (!d->node) return;
0315     d->node->enableAnimation();
0316 }
0317 
0318 void Node::setPinnedToTimeline(bool pinned) const
0319 {
0320     if (!d->node) return;
0321     d->node->setPinnedToTimeline(pinned);
0322 }
0323 
0324 bool Node::isPinnedToTimeline() const
0325 {
0326     if (!d->node) return false;
0327     return d->node->isPinnedToTimeline();
0328 }
0329 
0330 bool Node::collapsed() const
0331 {
0332     if (!d->node) return false;
0333     return d->node->collapsed();
0334 }
0335 
0336 void Node::setCollapsed(bool collapsed)
0337 {
0338     if (!d->node) return;
0339     d->node->setCollapsed(collapsed);
0340 }
0341 
0342 bool Node::inheritAlpha() const
0343 {
0344     if (!d->node) return false;
0345     if (!d->node->inherits("KisLayer")) return false;
0346     return qobject_cast<const KisLayer*>(d->node)->alphaChannelDisabled();
0347 }
0348 
0349 void Node::setInheritAlpha(bool value)
0350 {
0351     if (!d->node) return;
0352     if (!d->node->inherits("KisLayer")) return;
0353     const_cast<KisLayer*>(qobject_cast<const KisLayer*>(d->node))->disableAlphaChannel(value);
0354 }
0355 
0356 bool Node::locked() const
0357 {
0358     if (!d->node) return false;
0359     return d->node->userLocked();
0360 }
0361 
0362 void Node::setLocked(bool value)
0363 {
0364     if (!d->node) return;
0365     d->node->setUserLocked(value);
0366 }
0367 
0368 bool Node::hasExtents()
0369 {
0370     return !d->node->extent().isEmpty();
0371 }
0372 
0373 QString Node::name() const
0374 {
0375     if (!d->node) return QString();
0376     return d->node->name();
0377 }
0378 
0379 void Node::setName(QString name)
0380 {
0381     if (!d->node) return;
0382     d->node->setName(name);
0383 }
0384 
0385 
0386 int Node::opacity() const
0387 {
0388     if (!d->node) return 0;
0389     return d->node->opacity();
0390 }
0391 
0392 void Node::setOpacity(int value)
0393 {
0394     if (!d->node) return;
0395     if (value < 0) value = 0;
0396     if (value > 255) value = 255;
0397     d->node->setOpacity(value);
0398 }
0399 
0400 
0401 Node* Node::parentNode() const
0402 {
0403     if (!d->node) return 0;
0404     if (!d->node->parent()) return 0;
0405     return Node::createNode(d->image, d->node->parent());
0406 }
0407 
0408 QString Node::type() const
0409 {
0410     if (!d->node) return QString();
0411     if (qobject_cast<const KisPaintLayer*>(d->node)) {
0412         return "paintlayer";
0413     }
0414     else if (qobject_cast<const KisGroupLayer*>(d->node)) {
0415         return "grouplayer";
0416     }
0417     if (qobject_cast<const KisFileLayer*>(d->node)) {
0418         return "filelayer";
0419     }
0420     if (qobject_cast<const KisAdjustmentLayer*>(d->node)) {
0421         return "filterlayer";
0422     }
0423     if (qobject_cast<const KisGeneratorLayer*>(d->node)) {
0424         return "filllayer";
0425     }
0426     if (qobject_cast<const KisCloneLayer*>(d->node)) {
0427         return "clonelayer";
0428     }
0429     if (qobject_cast<const KisReferenceImagesLayer*>(d->node)) {
0430         return "referenceimageslayer";
0431     }
0432     if (qobject_cast<const KisShapeLayer*>(d->node)) {
0433         return "vectorlayer";
0434     }
0435     if (qobject_cast<const KisTransparencyMask*>(d->node)) {
0436         return "transparencymask";
0437     }
0438     if (qobject_cast<const KisFilterMask*>(d->node)) {
0439         return "filtermask";
0440     }
0441     if (qobject_cast<const KisTransformMask*>(d->node)) {
0442         return "transformmask";
0443     }
0444     if (qobject_cast<const KisSelectionMask*>(d->node)) {
0445         return "selectionmask";
0446     }
0447     if (qobject_cast<const KisColorizeMask*>(d->node)) {
0448         return "colorizemask";
0449     }
0450     return QString();
0451 }
0452 
0453 QIcon Node::icon() const
0454 {
0455     QIcon icon;
0456     if (d->node) {
0457         icon = d->node->icon();
0458     }
0459     return icon;
0460 }
0461 
0462 bool Node::visible() const
0463 {
0464     if (!d->node) return false;
0465     return d->node->visible();
0466 }
0467 
0468 bool Node::hasKeyframeAtTime(int frameNumber)
0469 {
0470     if (!d->node || !d->node->isAnimated()) return false;
0471 
0472     KisRasterKeyframeChannel *rkc = dynamic_cast<KisRasterKeyframeChannel*>(d->node->getKeyframeChannel(KisKeyframeChannel::Raster.id()));
0473     if (!rkc) return false;
0474 
0475     KisKeyframeSP currentKeyframe = rkc->keyframeAt(frameNumber);
0476 
0477     if (!currentKeyframe) {
0478         return false;
0479     }
0480 
0481     return true;
0482 }
0483 
0484 void Node::setVisible(bool visible)
0485 {
0486     if (!d->node) return;
0487     d->node->setVisible(visible);
0488 }
0489 
0490 
0491 QByteArray Node::pixelData(int x, int y, int w, int h) const
0492 {
0493     QByteArray ba;
0494 
0495     if (!d->node) return ba;
0496 
0497     KisPaintDeviceSP dev = d->node->paintDevice();
0498     if (!dev) return ba;
0499 
0500     ba.resize(w * h * dev->pixelSize());
0501     dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
0502     return ba;
0503 }
0504 
0505 QByteArray Node::pixelDataAtTime(int x, int y, int w, int h, int time) const
0506 {
0507     QByteArray ba;
0508 
0509     if (!d->node || !d->node->isAnimated()) return ba;
0510 
0511     //
0512     KisRasterKeyframeChannel *rkc = dynamic_cast<KisRasterKeyframeChannel*>(d->node->getKeyframeChannel(KisKeyframeChannel::Raster.id()));
0513     if (!rkc) return ba;
0514     KisRasterKeyframeSP frame = rkc->keyframeAt<KisRasterKeyframe>(time);
0515     if (!frame) return ba;
0516     KisPaintDeviceSP dev = new KisPaintDevice(*d->node->paintDevice(), KritaUtils::DeviceCopyMode::CopySnapshot);
0517     if (!dev) return ba;
0518 
0519     frame->writeFrameToDevice(dev);
0520 
0521     ba.resize(w * h * dev->pixelSize());
0522     dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
0523     return ba;
0524 }
0525 
0526 
0527 QByteArray Node::projectionPixelData(int x, int y, int w, int h) const
0528 {
0529     QByteArray ba;
0530 
0531     if (!d->node) return ba;
0532 
0533     KisPaintDeviceSP dev = d->node->projection();
0534     if (!dev) return ba;
0535 
0536     ba.resize(w * h * dev->pixelSize());
0537     dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
0538     return ba;
0539 }
0540 
0541 bool Node::setPixelData(QByteArray value, int x, int y, int w, int h)
0542 {
0543     if (!d->node) return false;
0544     KisPaintDeviceSP dev = d->node->paintDevice();
0545     if (!dev) return false;
0546     if (value.length() <  w * h * (int)dev->colorSpace()->pixelSize()) {
0547         qWarning() << "Node::setPixelData: not enough data to write to the paint device";
0548         return false;
0549     }
0550     dev->writeBytes((const quint8*)value.constData(), x, y, w, h);
0551     return true;
0552 }
0553 
0554 QRect Node::bounds() const
0555 {
0556     if (!d->node) return QRect();
0557     return d->node->exactBounds();
0558 }
0559 
0560 void Node::move(int x, int y)
0561 {
0562     if (!d->node) return;
0563     d->node->setX(x);
0564     d->node->setY(y);
0565 }
0566 
0567 QPoint Node::position() const
0568 {
0569     if (!d->node) return QPoint();
0570     return QPoint(d->node->x(), d->node->y());
0571 }
0572 
0573 bool Node::remove()
0574 {
0575     if (!d->node) return false;
0576     if (!d->node->parent()) return false;
0577 
0578     KUndo2Command *cmd = new KisImageLayerRemoveCommand(d->image, d->node);
0579 
0580     KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
0581     d->image->waitForDone();
0582 
0583     return true;
0584 }
0585 
0586 Node* Node::duplicate()
0587 {
0588     if (!d->node) return 0;
0589     return Node::createNode(d->image, d->node->clone());
0590 }
0591 
0592 bool Node::save(const QString &filename, double xRes, double yRes, const InfoObject &exportConfiguration, const QRect &exportRect)
0593 {
0594     if (!d->node) return false;
0595     if (filename.isEmpty()) return false;
0596 
0597     KisPaintDeviceSP projection = d->node->projection();
0598     QRect bounds = (exportRect.isEmpty())? d->node->exactBounds() : exportRect;
0599 
0600     QString mimeType = KisMimeDatabase::mimeTypeForFile(filename, false);
0601     QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
0602 
0603     KisImageSP dst = new KisImage(doc->createUndoStore(),
0604                                   bounds.right(),
0605                                   bounds.bottom(),
0606                                   projection->compositionSourceColorSpace(),
0607                                   d->node->name());
0608     dst->setResolution(xRes, yRes);
0609     doc->setFileBatchMode(Krita::instance()->batchmode());
0610     doc->setCurrentImage(dst);
0611     KisPaintLayer* paintLayer = new KisPaintLayer(dst, "paint device", d->node->opacity());
0612     paintLayer->paintDevice()->makeCloneFrom(projection, bounds);
0613     dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
0614     dst->cropImage(bounds);
0615     dst->initialRefreshGraph();
0616 
0617     bool r = doc->exportDocumentSync(filename, mimeType.toLatin1(), exportConfiguration.configuration());
0618     if (!r) {
0619         qWarning() << doc->errorMessage();
0620     }
0621     return r;
0622 }
0623 
0624 Node* Node::mergeDown()
0625 {
0626     if (!d->node) return 0;
0627     if (!qobject_cast<KisLayer*>(d->node.data())) return 0;
0628     if (!d->node->prevSibling()) return 0;
0629 
0630     d->image->mergeDown(qobject_cast<KisLayer*>(d->node.data()), KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
0631     d->image->waitForDone();
0632 
0633     return Node::createNode(d->image, d->node->prevSibling());
0634 }
0635 
0636 void Node::scaleNode(QPointF origin, int width, int height, QString strategy)
0637 {
0638     if (!d->node) return;
0639     if (!qobject_cast<KisLayer*>(d->node.data())) return;
0640     if (!d->node->parent()) return;
0641 
0642     KisFilterStrategy *actualStrategy = KisFilterStrategyRegistry::instance()->get(strategy);
0643     if (!actualStrategy) actualStrategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
0644 
0645     const QRect bounds(d->node->exactBounds());
0646 
0647     d->image->scaleNode(d->node,
0648                         origin,
0649                         qreal(width) / bounds.width(),
0650                         qreal(height) / bounds.height(),
0651                         actualStrategy, 0);
0652     d->image->waitForDone();
0653 }
0654 
0655 void Node::rotateNode(double radians)
0656 {
0657     if (!d->node) return;
0658     if (!qobject_cast<KisLayer*>(d->node.data())) return;
0659     if (!d->node->parent()) return;
0660 
0661     d->image->rotateNode(d->node, radians, 0);
0662     d->image->waitForDone();
0663 }
0664 
0665 void Node::cropNode(int x, int y, int w, int h)
0666 {
0667     if (!d->node) return;
0668     if (!qobject_cast<KisLayer*>(d->node.data())) return;
0669     if (!d->node->parent()) return;
0670 
0671     QRect rect = QRect(x, y, w, h);
0672     d->image->cropNode(d->node, rect);
0673     d->image->waitForDone();
0674 }
0675 
0676 void Node::shearNode(double angleX, double angleY)
0677 {
0678     if (!d->node) return;
0679     if (!qobject_cast<KisLayer*>(d->node.data())) return;
0680     if (!d->node->parent()) return;
0681 
0682     d->image->shearNode(d->node, angleX, angleY, 0);
0683     d->image->waitForDone();
0684 }
0685 
0686 QImage Node::thumbnail(int w, int h)
0687 {
0688     if (!d->node) return QImage();
0689     return d->node->createThumbnail(w, h);
0690 }
0691 
0692 QString Node::layerStyleToAsl()
0693 {
0694     if (!d->node) return QString();
0695 
0696     KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
0697 
0698     if (!layer) return QString();
0699 
0700     KisPSDLayerStyleSP layerStyle = layer->layerStyle();
0701 
0702     if (!layerStyle) return QString();
0703 
0704     KisAslLayerStyleSerializer serializer;
0705 
0706     serializer.setStyles(QVector<KisPSDLayerStyleSP>() << layerStyle);
0707 
0708     return serializer.formPsdXmlDocument().toString();
0709 }
0710 
0711 bool Node::setLayerStyleFromAsl(const QString &asl)
0712 {
0713     if (!d->node) return false;
0714 
0715     KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
0716 
0717     if (!layer) return false;
0718 
0719     QDomDocument aslDoc;
0720 
0721     if (!aslDoc.setContent(asl)) {
0722         qWarning() << "ASL string format is invalid!";
0723         return false;
0724     }
0725 
0726     KisAslLayerStyleSerializer serializer;
0727 
0728     serializer.registerPSDPattern(aslDoc);
0729     serializer.readFromPSDXML(aslDoc);
0730 
0731     if (serializer.styles().size() != 1) return false;
0732 
0733     KisPSDLayerStyleSP newStyle = serializer.styles().first();
0734     KUndo2Command *cmd = new KisSetLayerStyleCommand(layer, layer->layerStyle(), newStyle);
0735 
0736     KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
0737     d->image->waitForDone();
0738 
0739     return true;
0740 }
0741 
0742 int Node::index() const
0743 {
0744     if (!d->node) return -1;
0745     if (!d->node->parent()) return -1;
0746 
0747     return d->node->parent()->index(d->node);
0748 }
0749 
0750 QUuid Node::uniqueId() const
0751 {
0752     if (!d->node) return QUuid();
0753     return d->node->uuid();
0754 }
0755 
0756 KisPaintDeviceSP Node::paintDevice() const
0757 {
0758     return d->node->paintDevice();
0759 }
0760 
0761 KisImageSP Node::image() const
0762 {
0763     return d->image;
0764 }
0765 
0766 KisNodeSP Node::node() const
0767 {
0768     return d->node;
0769 }