74 selectionMasks.append(mask);
132 return qobject_cast<KisLayer*>(
node.
data());
388 KisBaseNode::PropertyList props = node->sectionModelProperties();
389 KisLayerPropertiesIcons::setNodeProperty(&props,
390 KisLayerPropertiesIcons::colorizeEditKeyStrokes,
393 addCommand(new KisNodePropertyListCommand(node, props));
436 if (
m_info->nodesCompositingVaries)
return;
440 m_info->image->disableDirtyRequests();
458 m_info->image->enableDirtyRequests();
475 m_info->dstLayer()->inherits(
"KisGroupLayer")) {
511 const QRect preparedRect = !interface->externalFrameActive() ?
527 :
m_nodes(info->allSrcNodes()) {}
601 if (
m_info->frames.size() > 0) {
602 m_info->dstNode->enableAnimation();
606 m_info->dstNode->setPinnedToTimeline(
m_info->pinnedToTimeline);
607 m_info->dstNode->setColorLabelIndex(
m_info->allSrcNodes().first()->colorLabelIndex());
625 QString mergedLayerName;
627 const QString mergedLayerSuffix = i18n(
"Merged");
628 mergedLayerName =
m_info->mergedNodes.first()->name();
630 if (
KisImageConfig(
true).renameMergedLayers() && !mergedLayerName.endsWith(mergedLayerSuffix)) {
631 mergedLayerName = QString(
"%1 %2")
632 .arg(mergedLayerName).arg(mergedLayerSuffix);
638 auto channelFlagsLazy = [](
KisNodeSP node) {
643 QString compositeOpId;
644 QBitArray channelFlags;
645 bool compositionVaries =
false;
646 bool isFirstCycle =
true;
651 channelFlags = channelFlagsLazy(node);
652 isFirstCycle =
false;
654 channelFlags != channelFlagsLazy(node)) {
655 compositionVaries =
true;
661 compositionVaries =
true;
670 if (!compositionVaries &&
m_info->frames.isEmpty()) {
681 if (!layers.isEmpty()) {
686 m_info->dstNode = layers.first()->tryCreateInternallyMergedLayerFromMutipleLayers(layers);
697 if (
m_info->frames.size() > 0) {
698 m_info->dstNode->enableAnimation();
702 if (!compositionVaries) {
703 if (!compositeOpId.isEmpty()) {
704 m_info->dstNode->setCompositeOpId(compositeOpId);
706 if (
m_info->dstLayer() && !channelFlags.isEmpty()) {
707 m_info->dstLayer()->setChannelFlags(channelFlags);
711 m_info->dstNode->setPinnedToTimeline(
m_info->pinnedToTimeline);
712 m_info->dstNode->setColorLabelIndex(
m_info->allSrcNodes().first()->colorLabelIndex());
714 m_info->rasterizedDstLayer->setOnionSkinEnabled(
m_info->enableOnionSkins);
717 m_info->nodesCompositingVaries = compositionVaries;
743 if (!
m_info->rasterizedDstLayer)
return;
763 QRect layerProjectionExtent =
m_info->currLayer->projection()->extent();
764 QRect prevLayerProjectionExtent =
m_info->prevLayer->projection()->extent();
765 int prevLayerArea = prevLayerProjectionExtent.width() * prevLayerProjectionExtent.height();
766 int layerArea = layerProjectionExtent.width() * layerProjectionExtent.height();
769 double norm = qMax(prevLayerArea, layerArea);
770 scores.append(prevLayerArea / norm);
771 scores.append(layerArea / norm);
774 srcs.append(
m_info->prevLayer->metaData());
775 srcs.append(
m_info->currLayer->metaData());
805 const QRect processRect =
813 quint8 *srcPtr = srcIt.
rawData();
814 quint8 *alpha8Ptr = dstIt.
rawData();
833 const QRect processRect =
842 quint8 *srcPtr = srcIt.
rawData();
843 quint8 *dstPtr = dstIt.
rawData();
884 : FlipFlopCommand(finalize, parent),
885 m_selectedBefore(selectedBefore),
886 m_selectedAfter(selectedAfter),
887 m_activeBefore(activeBefore),
888 m_activeAfter(activeAfter),
938 std::optional<ReplacementNode> replacementNode) {
940 const bool lastLayer = !replacementNode &&
scanForLastLayer(image, removedNodes);
943 const bool normalCompositeMode = node->compositeOpId() ==
COMPOSITE_OVER;
947 return !normalCompositeMode && !hasInheritAlpha;
953 RecipeSP updateRecipe(
new Recipe());
955 if (replacementNode) {
956 updateRecipe->nodesToAdd.push_back({replacementNode->node,
957 replacementNode->doRedoUpdates,
958 replacementNode->doUndoUpdates});
961 Q_FOREACH (
KisNodeSP node, removedNodes) {
962 updateRecipe->nodesToRemove.push_back({node, !isNodeWeird(node),
true});
967 if (replacementNode) {
969 replacementNode->node,
970 replacementNode->parent,
971 replacementNode->putAfter,
980 if (replacementNode->relinkClones) {
983 Q_FOREACH (
KisNodeSP node, removedNodes) {
985 if (originalSource) {
992 if (finalSource && !clones.isEmpty()) {
998 while (!removedNodes.isEmpty()) {
999 KisNodeList::iterator it = removedNodes.begin();
1001 while (it != removedNodes.end()) {
1006 it = removedNodes.erase(it);
1027 if (node == src)
continue;
1040 bool removeLayers =
false;
1041 Q_FOREACH(
KisNodeSP nodeToRemove, nodesToRemove) {
1042 if (qobject_cast<KisLayer*>(nodeToRemove.
data())) {
1043 removeLayers =
true;
1047 if (!removeLayers)
return false;
1049 bool lastLayer =
true;
1052 if (!nodesToRemove.contains(node) &&
1053 qobject_cast<KisLayer*>(node.
data()) &&
1073 if (
m_nodes.isEmpty())
return;
1144 QSet<KisNodeSP> nodesToHide;
1145 QSet<KisNodeSP> extraNodesToRemove;
1147 for (
auto it = nodesToRemove.begin(); it != nodesToRemove.end(); ++it) {
1152 nodesToHide.insert(root);
1154 bool rootNeedsCarefulRemoval =
false;
1157 [root, &nodesToHide, &rootNeedsCarefulRemoval] (
KisNodeSP node) {
1159 while (node != root) {
1160 nodesToHide.insert(node);
1161 node = node->parent();
1162 KIS_SAFE_ASSERT_RECOVER_BREAK(node);
1164 nodesToHide.insert(root);
1165 rootNeedsCarefulRemoval =
true;
1169 if (rootNeedsCarefulRemoval) {
1171 [&extraNodesToRemove] (
KisNodeSP node) {
1172 extraNodesToRemove.insert(node);
1177 nodesToRemove +=
KisNodeList(extraNodesToRemove.begin(), extraNodesToRemove.end());
1178 KritaUtils::filterContainer<KisNodeList>(nodesToRemove,
1180 return !nodesToHide.contains(node);
1182 _nodesToHide =
KisNodeList(nodesToHide.begin(), nodesToHide.end());
1187 : m_info(info), m_putAfter(putAfter), m_relinkClones(relinkClones) {}
1191 putAfter = nodesToDelete.last();
1210 bool foundDeletedAncestor =
false;
1211 KisNodeSP topmostAncestorToDelete =
nullptr;
1215 if (nodesToDelete.contains(node)
1216 && !nodesToDelete.contains(node->
parent())) {
1217 foundDeletedAncestor =
true;
1218 topmostAncestorToDelete = node;
1227 if (foundDeletedAncestor) {
1228 parent = topmostAncestorToDelete->
parent();
1229 putAfter = topmostAncestorToDelete;
1232 parent = putAfter->
parent();
1238 KisNodeList nodesToDelete = m_info->allSrcNodes();
1241 findPerfectParent(nodesToDelete, m_putAfter, parent);
1250 addCommand(new KisImageLayerAddCommand(m_info->image,
1268 KisNodeList safeNodesToDelete = m_info->allSrcNodes();
1273 Q_FOREACH(
KisNodeSP node, safeNodesToHide) {
1277 safeReplaceMultipleNodes(safeNodesToDelete, m_info->image,
1278 std::make_optional<ReplacementNode>(
1283 m_info->selectionMasks,
1298 bool m_relinkClones {
false};
1301 SwitchFrameCommand::SharedStorage::~SharedStorage() {
1305 : FlipFlopCommand(finalize),
1308 m_storage(storage) {}
1314 const int currentTime = interface->currentTime();
1320 interface->image()->disableUIUpdates();
1326 const int currentTime = interface->currentTime();
1331 interface->restoreCurrentTime(&
m_storage->value);
1355 Q_FOREACH(
KisNodeSP srcNode, srcNodes) {
1358 if (!keyframe.isNull() && keyframe->colorLabel() != 0) {
1359 dstKeyframe->setColorLabel(keyframe->colorLabel());
1365 dstKeyframe->setColorLabel(0);
1392 if (initialKeyframe == -1) {
1399 frames.insert(currentSpan.
start());
1403 frames.insert(lastKeyframe);
1412 if (!rootNode->
visible())
return QSet<int>();
1429 if (frames.isEmpty()) {
1430 (*jobs)[0].insert(node);
1432 foreach (
int frame, frames) {
1433 (*jobs)[frame].insert(node);
1458 while (prevLayer && prevLayer->
isFakeNode()) {
1462 if (!prevLayer)
return;
1497 if (info->frames.size() > 0) {
1502 const int currentTimeOnStart = info->image->animationInterface()->currentTime();
1504 foreach (
int frame, info->frames) {
1525 const bool skipMergingSourceLayer = !layer->
isAnimated() &&
1526 frame != currentTimeOnStart;
1543 }
else if (layer->
visible()) {
1557 }
else if (prevLayer->
visible()) {
1582 nodeParents << parent;
1583 parent = parent->parent();
1586 foreach(
KisNodeSP perspectiveParent, parents) {
1587 if (nodeParents.contains(perspectiveParent)) {
1597 bool result =
false;
1608 return node == cloneSource;
1626 KisNodeList::iterator it = nodes.begin();
1628 while (it != nodes.end()) {
1629 if ((!allowMasks && !qobject_cast<KisLayer*>(it->data())) ||
1632 it = nodes.erase(it);
1641 KisNodeList::iterator it = std::find(inputNodes.begin(), inputNodes.end(), root);
1643 if (it != inputNodes.end()) {
1645 inputNodes.erase(it);
1648 if (inputNodes.isEmpty()) {
1678 while (localRoot->
parent()) {
1679 localRoot = localRoot->
parent();
1701 while (localRoot->
parent()) {
1702 localRoot = localRoot->
parent();
1722 bool haveExternalNodes =
false;
1725 haveExternalNodes =
true;
1730 if (!haveExternalNodes) {
1733 sortedNodes = filteredNodes;
1744 const QString prefix = i18n(
"Copy of");
1745 QString newName = node->
name();
1746 if (!newName.startsWith(prefix)) {
1747 newName = QString(
"%1 %2").arg(prefix).arg(newName);
1756 if ((!excludeRoot || root->
parent()) && root->
check(props)) {
1775 int putAfterIndex = -1;
1779 visibleNodes << node;
1786 *invisibleNodes << node;
1788 if (node == *putAfter) {
1789 putAfterIndex = visibleNodes.size() - 1;
1794 if (!visibleNodes.isEmpty() && putAfterIndex >= 0) {
1795 putAfterIndex = qBound(0, putAfterIndex, visibleNodes.size() - 1);
1796 *putAfter = visibleNodes[putAfterIndex];
1799 return visibleNodes;
1804 KisNodeList::iterator it = nodes.begin();
1806 while (it != nodes.end()) {
1807 if ((*it)->userLocked()) {
1808 it = nodes.erase(it);
1847 m_info->ephemeralCommandsStore->addCommand(cmd);
1869 m_info->ephemeralCommandsStore->undoAll();
1904 bool cleanupNodes =
true,
const QString layerName = QString(),
1905 MergeFlags flags =
None)
1908 putAfter = mergedNodes.first();
1914 std::swap(mergedNodes, tempNodes);
1918 if (mergedNodes.size() <= 1 &&
1919 (!flattenSingleLayer && mergedNodes.size() == 1))
return;
1930 if (mergedNodes.isEmpty())
return;
1936 putAfter = putAfter->
parent();
1946 if (!putAfter->
parent()) {
1956 if (!invisibleNodes.isEmpty() && cleanupNodes) {
1968 putAfter = mergedNodes.first();
1978 if (mergedNodes.size() > 1 || invisibleNodes.isEmpty()) {
2003 if (!info->frames.isEmpty()) {
2004 foreach (
int frame, info->frames) {
2063 mergedNodes << image->
root();
2067 false, i18nc(
"New layer created from all the visible layers",
"Visible"),
2082 parentLayer = qobject_cast<KisLayer*>(parent.data());
2084 parent = parent->parent();
2085 }
while(!parentLayer && parent);
2091 if (!mask)
continue;
2101 m_info->dstNode = mergedMask;
2126 for (
auto it = mergedNodes.begin(); it != mergedNodes.end(); ) {
2129 it = mergedNodes.erase(it);
2131 selectionMasks.append(mask);
2136 if (mergedNodes.isEmpty())
return false;
2138 KisLayerSP parentLayer = qobject_cast<KisLayer*>(selectionMasks.first()->parent().data());
2167 mergedNodes << layer;
2183 mergedNodes << image->
root();
2192 : FlipFlopCommand(finalize, parent),
2229 return node->
uuid() == uuid;
2239 if (name.isEmpty() || (!partialMatch && child->
name() == name) || (partialMatch && child->
name().contains(name, Qt::CaseInsensitive))) {
2255 return node->
name() == name;
2273 if (delayedUpdate) {
2296 if (croppedUpdate) {
2307 return layer->
image();
2343 if (!preparedArea.contains(realNodeRect)) {
2345 QRegion dirtyRegion = realNodeRect;
2346 dirtyRegion -= preparedArea;
2348 auto rc = dirtyRegion.begin();
2349 while (rc != dirtyRegion.end()) {
2372 if (!node)
return node;
2383 bool hasNonNormalLayers =
false;
2384 bool hasTransparentLayer =
false;
2388 [&numLayers, &hasNonNormalLayers, &hasTransparentLayer, image] (
KisNodeSP node) {
2389 if (!node->inherits(
"KisLayer")) return;
2393 if (node->exactBounds().isEmpty()) return;
2396 if (!hasTransparentLayer &&
2397 node->exactBounds() != image->bounds()) {
2399 hasTransparentLayer = true;
2402 if (!hasNonNormalLayers &&
2405 hasNonNormalLayers = true;
2409 return numLayers == 1 || (!hasNonNormalLayers && !hasTransparentLayer);
2424 if (info->frames.count() > 0) {
2425 Q_FOREACH(
const int& frame, info->frames) {
2442 if (!info->hasTargetNode())
2450 if (info->frames().count() > 0) {
2451 Q_FOREACH(
const int& frame, info->frames()) {
2466 [node = info->targetNode()] (std::future<bool> completed) {
2467 return completed.get() ? node : KisNodeSP();
2487 return keyframe->frameID();
2532 if (!rasterChannel) {
2550 Q_FOREACH(
const int& frame, times ) {
2552 frameIDs << raster->frameID();
2577 QSet<int> uniqueTimes;
2579 Q_FOREACH(
const int&
id, frameIDs) {
2581 if (times.count() > 0) {
2582 uniqueTimes.insert(*times.begin());
2592 return selectedTimes;
2597 if (filterActiveFrameID) {
2601 selectedFrameIDs.remove(currentActiveFrameID);
2607 return uniqueFrameTimes;
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
const quint8 OPACITY_OPAQUE_U8
const QString COMPOSITE_OVER
const QString COMPOSITE_BEHIND
KUndo2Command(KUndo2Command *parent=0)
QSharedPointer< Recipe > RecipeSP
KisPaintDeviceSP coloringProjection() const
virtual void forceUpdateHiddenAreaOnOriginal()=0
virtual QRect bounds() const =0
The KisDelayedUpdateNodeInterface class is an interface for nodes that delay their real updates with ...
virtual void forceUpdateTimedNode()=0
forceUpdateTimedNode forces the node to regenerate its project. The update might be asynchronous,...
virtual bool hasPendingTimedUpdates() const =0
The command for adding a layer.
The command for layer moves inside the layer stack.
void emitNotification(KisImageSignalType type)
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
KisGroupLayerSP rootLayer() const
const KoColorSpace * colorSpace() const
KisImageAnimationInterface * animationInterface() const
QString nextLayerName(const QString &baseName="") const
QVector< QRect > enableUIUpdates() override
KisNodeSP isolationRootNode() const
KisImageSignalRouter * signalRouter()
QRect bounds() const override
KisKeyframeChannel stores and manages KisKeyframes. Maps units of time to virtual keyframe values....
QSet< int > allKeyframeTimes() const
Get a set of all integer times that map to a keyframe.
int firstKeyframeTime() const
KisKeyframeSP keyframeAt(int time) const
Get a keyframe at specified time. Used primarily when the value of a given keyframe is needed.
void addKeyframe(int time, KUndo2Command *parentUndoCmd=nullptr)
Add a new keyframe to the channel at the specified time.
virtual KisTimeSpan affectedFrames(int time) const
Get the set of frames affected by any changes to the value or content of the active keyframe at the g...
KisKeyframeSP activeKeyframeAt(int time) const
int activeKeyframeTime(int time) const
Get the time of the active keyframe. Useful for snapping any time to that of the most recent keyframe...
int lastKeyframeTime() const
static const KoID colorizeEditKeyStrokes
static QVariant nodeProperty(KisNodeSP node, const KoID &id, const QVariant &defaultValue)
static void setNodeProperty(KisBaseNode::PropertyList *props, const KoID &id, const QVariant &value)
static const KoID inheritAlpha
static const KoID onionSkins
static const KoID passThrough
KisNodeList m_selectedAfter
KisNodeList m_selectedBefore
KeepNodesSelectedCommand(const KisNodeList &selectedBefore, const KisNodeList &selectedAfter, KisNodeSP activeBefore, KisNodeSP activeAfter, KisImageSP image, bool finalize, KUndo2Command *parent=0)
static void updateNodes(const KisNodeList &nodes)
KisSimpleUpdateCommand(KisNodeList nodes, bool finalize, KUndo2Command *parent=0)
virtual void addCommandImpl(KUndo2Command *cmd)=0
virtual ~RemoveNodeHelper()
void safeReplaceMultipleNodes(KisNodeList removedNodes, KisImageSP image, std::optional< ReplacementNode > replacementNode)
void safeRemoveMultipleNodes(KisNodeList nodes, KisImageSP image)
bool checkIsSourceForClone(KisNodeSP src, const KisNodeList &nodes)
static bool scanForLastLayer(KisImageWSP image, KisNodeList nodesToRemove)
The command for setting the composite op.
The command for changing the property list of a layer.
void writeFrameToDevice(int frameId, KisPaintDeviceSP targetDevice)
void uploadFrame(int srcFrameId, int dstFrameId, KisPaintDeviceSP srcDevice)
KisRasterKeyframeChannel * keyframeChannel() const
void setDefaultPixel(const KoColor &defPixel)
virtual const KoColorSpace * compositionSourceColorSpace() const
KisPaintDeviceFramesInterface * framesInterface()
QRect exactBounds() const
const KoColorSpace * colorSpace() const
KoColor defaultPixel() const
KisDefaultBoundsBaseSP defaultBounds() const
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
std::future< bool > && successfullyCompletedFuture()
The KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
QSet< int > timesForFrameID(int frameID) const
QSet< int > clonesOf(int time)
The KisRasterKeyframe class is a concrete subclass of KisKeyframe that wraps a physical raster image ...
The KisScalarKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisSca...
virtual KisTimeSpan identicalFrames(int time) const override
Get a span of times for which the channel gives identical results compared to frame at a given time....
ALWAYS_INLINE quint8 * rawData()
static KisTimeSpan infinite(int start)
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
#define KIS_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_NOOP(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
QList< KisNodeSP > KisNodeList
KisSharedPtr< KisNode > KisNodeSP
KUndo2MagicString kundo2_i18n(const char *text)
@ ChangeProjectionColorCommand
QRect realNodeChangeRect(KisNodeSP rootNode, QRect currentRect=QRect())
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea, const QRect &extraUpdateRect)
void flattenImage(KisImageSP image, KisNodeSP activeNode, MergeFlags flags)
bool checkIsCloneOf(KisNodeSP node, const KisNodeList &nodes)
KisNodeSP findIsolationRoot(KisNodeSP node)
QSet< int > fetchLayerFrames(KisNodeSP node)
QSet< int > fetchUniqueFrameTimes(KisNodeSP node, QSet< int > selectedTimes, bool filterActiveFrameID)
bool hasDelayedNodeWithUpdates(KisNodeSP root)
void updateFrameJobs(FrameJobs *jobs, KisNodeSP node)
QSet< int > filterTimesForOnlyRasterKeyedTimes(KisNodeSP node, const QSet< int > ×)
void updateFrameJobsRecursive(FrameJobs *jobs, KisNodeSP rootNode)
KisNodeSP recursiveFindNode(KisNodeSP node, std::function< bool(KisNodeSP)> func)
void splitAlphaToMask(KisImageSP image, KisNodeSP node, const QString &maskName)
void changeImageDefaultProjectionColor(KisImageSP image, const KoColor &color)
KisTimeSpan fetchLayerActiveRasterFrameSpan(KisNodeSP node, const int time)
KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks)
QMap< int, QSet< KisNodeSP > > FrameJobs
int fetchLayerActiveRasterFrameID(KisNodeSP node)
QSharedPointer< SplitAlphaToMaskInfo > SplitAlphaToMaskInfoSP
QSharedPointer< MergeDownInfo > MergeDownInfoSP
void sortMergeableNodes(KisNodeSP root, KisNodeList &inputNodes, KisNodeList &outputNodes)
QRect recursiveTightNodeVisibleBounds(KisNodeSP rootNode)
KisImageSP findImageByHierarchy(KisNodeSP node)
QSet< int > fetchLayerUniqueRasterTimesMatchingIDs(KisNodeSP node, QSet< int > &frameIDs)
KisNodeSP findNodeByName(KisNodeSP root, const QString &name)
KisNodeList filterInvisibleNodes(const KisNodeList &nodes, KisNodeList *invisibleNodes, KisNodeSP *putAfter)
void flattenLayer(KisImageSP image, KisLayerSP layer, MergeFlags flags)
QSet< int > fetchLayerRasterIDsAtTimes(KisNodeSP node, const QSet< int > ×)
KisNodeSP findRoot(KisNodeSP node)
QList< KisNodeSP > findNodesByName(KisNodeSP root, const QString &name, bool recursive, bool partialMatch)
QSharedPointer< ConvertToPaintLayerInfo > ConvertToPaintLayerInfoSP
KisNodeList findNodesWithProps(KisNodeSP root, const KoProperties &props, bool excludeRoot)
void addCopyOfNameTag(KisNodeSP node)
KisNodeSP findNodeByUuid(KisNodeSP root, const QUuid &uuid)
void newLayerFromVisible(KisImageSP image, KisNodeSP putAfter, MergeFlags flags)
void filterUnlockedNodes(KisNodeList &nodes)
void mergeMultipleLayersImpl(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, bool flattenSingleLayer, const KUndo2MagicString &actionName, bool cleanupNodes=true, const QString layerName=QString(), MergeFlags flags=None)
bool canChangeImageProfileInvisibly(KisImageSP image)
void recursiveApplyNodes(NodePointer node, Functor func)
int fetchLayerActiveRasterFrameTime(KisNodeSP node)
void splitNonRemovableNodes(KisNodeList &nodesToRemove, KisNodeList &_nodesToHide)
KisNodeList sortAndFilterAnyMergeableNodesSafe(const KisNodeList &nodes, KisImageSP image)
void filterMergeableNodes(KisNodeList &nodes, bool allowMasks)
void forceAllHiddenOriginalsUpdate(KisNodeSP root)
QSet< int > fetchLayerIdenticalRasterFrameTimes(KisNodeSP node, const int &frameTime)
bool checkIsChildOf(KisNodeSP node, const KisNodeList &parents)
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea)
void mergeMultipleLayers(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags)
void mergeDown(KisImageSP image, KisLayerSP layer, const KisMetaData::MergeStrategy *strategy, MergeFlags flags)
bool tryMergeSelectionMasks(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter)
std::future< KisNodeSP > convertToPaintLayer(KisImageSP image, KisNodeSP src)
QSet< int > fetchLayerRasterFrameTimesMatchingID(KisNodeSP node, const int frameID)
void forceAllDelayedNodesUpdate(KisNodeSP root)
QSharedPointer< MergeDownInfoBase > MergeDownInfoBaseSP
QSet< int > fetchLayerFramesRecursive(KisNodeSP rootNode)
void fetchSelectionMasks(KisNodeList mergedNodes, QVector< KisSelectionMaskSP > &selectionMasks)
KisNodeList sortMergeableInternalNodes(KisNodeList nodes)
QSharedPointer< MergeMultipleInfo > MergeMultipleInfoSP
void mergeMultipleNodes(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags)
auto then(std::future< T > &&future, Function &&func) -> std::future< decltype(func(std::move(future)))>
std::future< void > make_ready_future()
QMap< QString, KisKeyframeChannel * > keyframeChannels
virtual KisPaintDeviceSP projection() const =0
const QString & compositeOpId() const
bool isEditable(bool checkVisibility=true) const
bool isPinnedToTimeline() const
KisKeyframeChannel * getKeyframeChannel(const QString &id, bool create)
virtual QRect exactBounds() const
virtual KisPaintDeviceSP original() const =0
void setName(const QString &name)
virtual QRect extent() const
virtual KisPaintDeviceSP paintDevice() const =0
virtual PropertyList sectionModelProperties() const
void setCompositeOpId(const QString &compositeOpId)
virtual bool isFakeNode() const
bool check(const KoProperties &properties) const
virtual bool visible(bool recursive=false) const
virtual bool supportsKeyframeChannel(const QString &id)
KisLayerSP reincarnateAsPaintLayer() const
The AggregateCommand struct is a command with delayed initialization. On first redo() populateChildCo...
void addCommand(KUndo2Command *cmd)
MergeDownInfoBaseSP m_info
ActivateSelectionMask(MergeDownInfoBaseSP info)
void populateChildCommands() override
void populateChildCommands() override
MergeDownInfoBaseSP m_mergeInfo
AddNewFrame(KisNodeSP node, int frame, KisNodeSP source)
KisNodeList m_sampledNodes
AddNewFrame(KisNodeSP node, int frame)
AddNewFrame(KisNodeSP node, int frame, KisNodeList sampleNodes)
void applyKeyframeColorLabel(KisKeyframeSP dstKeyframe, KisNodeList srcNodes)
AddNewFrame(MergeDownInfoBaseSP info, int frame)
void populateChildCommands() override
MergeDownInfoBaseSP m_info
static void findPerfectParent(KisNodeList nodesToDelete, KisNodeSP &putAfter, KisNodeSP &parent)
CleanUpNodes(MergeDownInfoBaseSP info, KisNodeSP putAfter, bool relinkClones=false)
void addCommandImpl(KUndo2Command *cmd) override
KisNodeSP insertionPutAfter() const
KisPaintDeviceSP m_sourcePaintDevice
KisNodeSP m_insertionParent
ConvertToPaintLayerInfo(KisImageSP image, KisNodeSP node)
KisNodeSP m_insertionPutAfter
KisNodeSP insertionParent() const
KisPaintLayerSP sourcePaintLayer()
SwitchFrameCommand::SharedStorageSP storage
KisPaintLayerSP targetPaintLayer()
KisNodeList sourceNodes()
KisPaintDeviceSP paintDevice()
MergeMultipleInfoSP m_info
CreateMergedLayerMultiple(MergeMultipleInfoSP info, const QString name=QString())
void populateChildCommands() override
void populateChildCommands() override
CreateMergedLayer(MergeDownInfoSP info)
void populateChildCommands() override
MergeDownInfoBaseSP m_info
DisableColorizeKeyStrokes(MergeDownInfoBaseSP info)
void populateChildCommands() override
DisableOnionSkins(MergeDownInfoBaseSP info)
MergeDownInfoBaseSP m_info
DisablePassThroughForHeadsOnly(MergeDownInfoBaseSP info, bool skipIfDstIsGroup=false)
void populateChildCommands() override
MergeDownInfoBaseSP m_info
EphemeralCommandsWrapper(MergeMultipleInfoSP info, QVector< KUndo2Command * > commands, bool cleanupNodes)
MergeMultipleInfoSP m_info
QVector< KUndo2Command * > m_commands
void populateChildCommands()
FillSelectionMasks(MergeDownInfoBaseSP info)
MergeDownInfoBaseSP m_info
InitSplitAlphaSelectionMask(SplitAlphaToMaskInfoSP info)
SplitAlphaToMaskInfoSP m_info
void populateChildCommands() override
void populateChildCommands() override
InsertNode(MergeDownInfoBaseSP info, KisNodeSP putAfter)
MergeDownInfoBaseSP m_info
virtual void addCommandImpl(KUndo2Command *cmd)
KeepMergedNodesSelected(MergeDownInfoSP info, bool finalizing)
MergeDownInfoSP m_singleInfo
void populateChildCommands() override
MergeMultipleInfoSP m_multipleInfo
KeepMergedNodesSelected(MergeMultipleInfoSP info, KisNodeSP putAfter, bool finalizing)
MergeDownInfoBase(KisImageSP _image)
SwitchFrameCommand::SharedStorageSP storage
virtual ~MergeDownInfoBase()
QVector< KisSelectionMaskSP > selectionMasks
virtual KisNodeList allSrcNodes()=0
KisPaintLayerSP rasterizedDstLayer
MergeDownInfo(KisImageSP _image, KisLayerSP _prevLayer, KisLayerSP _currLayer, MergeFlags flags)
KisNodeList allSrcNodes() override
MergeLayersMultiple(MergeMultipleInfoSP info)
MergeMultipleInfoSP m_info
void populateChildCommands() override
bool m_skipMergingSourceLayer
MergeLayers(MergeDownInfoSP info, bool skipMergingSourceLayer)
void populateChildCommands() override
MergeMultipleInfo(KisImageSP _image, KisNodeList _mergedNodes, MergeFlags flags)
KisNodeList allSrcNodes() override
bool nodesCompositingVaries
QScopedPointer< KisSurrogateUndoStore > ephemeralCommandsStore
void populateChildCommands() override
MergeSelectionMasks(MergeDownInfoBaseSP info, KisNodeSP putAfter)
MergeDownInfoBaseSP m_info
MergeDownInfoBaseSP m_info
RefreshDelayedUpdateLayers(MergeDownInfoBaseSP info)
RefreshDelayedUpdateLayers(KisNodeList nodes)
RefreshHiddenAreas(KisImageSP image, KisNodeSP node)
RefreshHiddenAreas(MergeDownInfoBaseSP info, refresh_entire_image_t)
RefreshHiddenAreas(MergeDownInfoBaseSP info)
static constexpr refresh_entire_image_t refresh_entire_image
void populateChildCommands() override
SelectGlobalSelectionMask(KisImageSP image)
~SelectGlobalSelectionMask()
virtual void addCommandImpl(KUndo2Command *cmd)
SimpleAddNode(KisImageSP image, KisNodeSP toAdd, KisNodeSP parent=0, KisNodeSP putAfter=0)
void populateChildCommands() override
SimpleRemoveLayers(const KisNodeList &nodes, KisImageSP image)
void addCommandImpl(KUndo2Command *cmd) override
void populateChildCommands() override
SplitAlphaToMaskInfoSP m_info
KisPaintDeviceSP m_cached
SplitAlphaCommand(SplitAlphaToMaskInfoSP info)
SwitchFrameCommand::SharedStorageSP storage
SplitAlphaToMaskInfo(KisImageSP _image, KisNodeSP _node, const QString &maskName)
KisPaintDeviceSP getMaskDevice()
KisTransparencyMaskSP mask
The SwitchFrameCommand struct Switches to frame with undo/redo support.
~SwitchFrameCommand() override
SharedStorageSP m_storage
UndoEphemeralCommands(MergeMultipleInfoSP info)
void populateChildCommands()
MergeMultipleInfoSP m_info
void populateChildCommands() override
UploadProjectionToFrameCommand(KisNodeSP src, KisNodeSP target, int frame)
void disableAlphaChannel(bool disable)
virtual KisSelectionMaskSP selectionMask() const
bool alphaChannelDisabled() const
KisPSDLayerStyleSP layerStyle
const QList< KisCloneLayerWSP > registeredClones() const
void initSelection(KisSelectionSP copyFrom, KisLayerSP parentLayer)
initSelection initializes the selection for the mask from the given selection's projection.
KisPaintDeviceSP paintDevice() const override
KisNodeSP prevSibling() const
KisNodeSP firstChild() const
QList< KisNodeSP > childNodes(const QStringList &nodeTypes, const KoProperties &properties) const
virtual KisAbstractProjectionPlaneSP projectionPlane() const
KisProjectionLeafSP projectionLeaf
quint32 childCount() const
KisNodeSP lastChild() const
KisNodeSP nextSibling() const
KisNodeGraphListener * graphListener
virtual bool allowAsChild(KisNodeSP) const =0
void setOnionSkinEnabled(bool state)
bool onionSkinEnabled() const
void setAlphaLocked(bool lock)
void applySelection(KisPixelSelectionSP selection, SelectionAction action)
void setSelection(KisSelectionSP selection)
Set the selection of this adjustment layer to a copy of selection.
KisPixelSelectionSP pixelSelection