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 }