74 selectionMasks.append(mask);
131 return qobject_cast<KisLayer*>(
node.
data());
387 KisBaseNode::PropertyList props = node->sectionModelProperties();
388 KisLayerPropertiesIcons::setNodeProperty(&props,
389 KisLayerPropertiesIcons::colorizeEditKeyStrokes,
392 addCommand(new KisNodePropertyListCommand(node, props));
435 if (
m_info->nodesCompositingVaries)
return;
439 m_info->image->disableDirtyRequests();
457 m_info->image->enableDirtyRequests();
474 m_info->dstLayer()->inherits(
"KisGroupLayer")) {
510 const QRect preparedRect = !interface->externalFrameActive() ?
526 :
m_nodes(info->allSrcNodes()) {}
600 if (
m_info->frames.size() > 0) {
601 m_info->dstNode->enableAnimation();
605 m_info->dstNode->setPinnedToTimeline(
m_info->pinnedToTimeline);
606 m_info->dstNode->setColorLabelIndex(
m_info->allSrcNodes().first()->colorLabelIndex());
624 QString mergedLayerName;
626 const QString mergedLayerSuffix = i18n(
"Merged");
627 mergedLayerName =
m_info->mergedNodes.first()->name();
629 if (
KisImageConfig(
true).renameMergedLayers() && !mergedLayerName.endsWith(mergedLayerSuffix)) {
630 mergedLayerName = QString(
"%1 %2")
631 .arg(mergedLayerName).arg(mergedLayerSuffix);
638 m_info->dstNode = dstPaintLayer;
640 if (
m_info->frames.size() > 0) {
641 m_info->dstNode->enableAnimation();
646 auto channelFlagsLazy = [](
KisNodeSP node) {
651 QString compositeOpId;
652 QBitArray channelFlags;
653 bool compositionVaries =
false;
654 bool isFirstCycle =
true;
659 channelFlags = channelFlagsLazy(node);
660 isFirstCycle =
false;
662 channelFlags != channelFlagsLazy(node)) {
663 compositionVaries =
true;
669 compositionVaries =
true;
674 if (!compositionVaries) {
675 if (!compositeOpId.isEmpty()) {
676 m_info->dstNode->setCompositeOpId(compositeOpId);
678 if (
m_info->dstLayer() && !channelFlags.isEmpty()) {
679 m_info->dstLayer()->setChannelFlags(channelFlags);
683 m_info->nodesCompositingVaries = compositionVaries;
685 m_info->dstNode->setPinnedToTimeline(
m_info->pinnedToTimeline);
686 m_info->dstNode->setColorLabelIndex(
m_info->allSrcNodes().first()->colorLabelIndex());
732 QRect layerProjectionExtent =
m_info->currLayer->projection()->extent();
733 QRect prevLayerProjectionExtent =
m_info->prevLayer->projection()->extent();
734 int prevLayerArea = prevLayerProjectionExtent.width() * prevLayerProjectionExtent.height();
735 int layerArea = layerProjectionExtent.width() * layerProjectionExtent.height();
738 double norm = qMax(prevLayerArea, layerArea);
739 scores.append(prevLayerArea / norm);
740 scores.append(layerArea / norm);
743 srcs.append(
m_info->prevLayer->metaData());
744 srcs.append(
m_info->currLayer->metaData());
774 const QRect processRect =
782 quint8 *srcPtr = srcIt.
rawData();
783 quint8 *alpha8Ptr = dstIt.
rawData();
802 const QRect processRect =
811 quint8 *srcPtr = srcIt.
rawData();
812 quint8 *dstPtr = dstIt.
rawData();
853 : FlipFlopCommand(finalize, parent),
854 m_selectedBefore(selectedBefore),
855 m_selectedAfter(selectedAfter),
856 m_activeBefore(activeBefore),
857 m_activeAfter(activeAfter),
907 std::optional<ReplacementNode> replacementNode) {
909 const bool lastLayer = !replacementNode &&
scanForLastLayer(image, removedNodes);
912 const bool normalCompositeMode = node->compositeOpId() ==
COMPOSITE_OVER;
916 return !normalCompositeMode && !hasInheritAlpha;
922 RecipeSP updateRecipe(
new Recipe());
924 if (replacementNode) {
925 updateRecipe->nodesToAdd.push_back({replacementNode->node,
926 replacementNode->doRedoUpdates,
927 replacementNode->doUndoUpdates});
930 Q_FOREACH (
KisNodeSP node, removedNodes) {
931 updateRecipe->nodesToRemove.push_back({node, !isNodeWeird(node),
true});
936 if (replacementNode) {
938 replacementNode->node,
939 replacementNode->parent,
940 replacementNode->putAfter,
949 if (replacementNode->relinkClones) {
952 Q_FOREACH (
KisNodeSP node, removedNodes) {
954 if (originalSource) {
961 if (finalSource && !clones.isEmpty()) {
967 while (!removedNodes.isEmpty()) {
968 KisNodeList::iterator it = removedNodes.begin();
970 while (it != removedNodes.end()) {
975 it = removedNodes.erase(it);
996 if (node == src)
continue;
1009 bool removeLayers =
false;
1010 Q_FOREACH(
KisNodeSP nodeToRemove, nodesToRemove) {
1011 if (qobject_cast<KisLayer*>(nodeToRemove.
data())) {
1012 removeLayers =
true;
1016 if (!removeLayers)
return false;
1018 bool lastLayer =
true;
1021 if (!nodesToRemove.contains(node) &&
1022 qobject_cast<KisLayer*>(node.
data()) &&
1042 if (
m_nodes.isEmpty())
return;
1113 QSet<KisNodeSP> nodesToHide;
1114 QSet<KisNodeSP> extraNodesToRemove;
1116 for (
auto it = nodesToRemove.begin(); it != nodesToRemove.end(); ++it) {
1121 nodesToHide.insert(root);
1123 bool rootNeedsCarefulRemoval =
false;
1126 [root, &nodesToHide, &rootNeedsCarefulRemoval] (
KisNodeSP node) {
1128 while (node != root) {
1129 nodesToHide.insert(node);
1130 node = node->parent();
1131 KIS_SAFE_ASSERT_RECOVER_BREAK(node);
1133 nodesToHide.insert(root);
1134 rootNeedsCarefulRemoval =
true;
1138 if (rootNeedsCarefulRemoval) {
1140 [&extraNodesToRemove] (
KisNodeSP node) {
1141 extraNodesToRemove.insert(node);
1146 nodesToRemove +=
KisNodeList(extraNodesToRemove.begin(), extraNodesToRemove.end());
1147 KritaUtils::filterContainer<KisNodeList>(nodesToRemove,
1149 return !nodesToHide.contains(node);
1151 _nodesToHide =
KisNodeList(nodesToHide.begin(), nodesToHide.end());
1156 : m_info(info), m_putAfter(putAfter), m_relinkClones(relinkClones) {}
1160 putAfter = nodesToDelete.last();
1179 bool foundDeletedAncestor =
false;
1180 KisNodeSP topmostAncestorToDelete =
nullptr;
1184 if (nodesToDelete.contains(node)
1185 && !nodesToDelete.contains(node->
parent())) {
1186 foundDeletedAncestor =
true;
1187 topmostAncestorToDelete = node;
1196 if (foundDeletedAncestor) {
1197 parent = topmostAncestorToDelete->
parent();
1198 putAfter = topmostAncestorToDelete;
1201 parent = putAfter->
parent();
1207 KisNodeList nodesToDelete = m_info->allSrcNodes();
1210 findPerfectParent(nodesToDelete, m_putAfter, parent);
1219 addCommand(new KisImageLayerAddCommand(m_info->image,
1237 KisNodeList safeNodesToDelete = m_info->allSrcNodes();
1242 Q_FOREACH(
KisNodeSP node, safeNodesToHide) {
1246 safeReplaceMultipleNodes(safeNodesToDelete, m_info->image,
1247 std::make_optional<ReplacementNode>(
1252 m_info->selectionMasks,
1267 bool m_relinkClones {
false};
1270 SwitchFrameCommand::SharedStorage::~SharedStorage() {
1274 : FlipFlopCommand(finalize),
1277 m_storage(storage) {}
1283 const int currentTime = interface->currentTime();
1289 interface->image()->disableUIUpdates();
1295 const int currentTime = interface->currentTime();
1300 interface->restoreCurrentTime(&
m_storage->value);
1324 Q_FOREACH(
KisNodeSP srcNode, srcNodes) {
1327 if (!keyframe.isNull() && keyframe->colorLabel() != 0) {
1328 dstKeyframe->setColorLabel(keyframe->colorLabel());
1334 dstKeyframe->setColorLabel(0);
1361 if (initialKeyframe == -1) {
1368 frames.insert(currentSpan.
start());
1372 frames.insert(lastKeyframe);
1381 if (!rootNode->
visible())
return QSet<int>();
1398 if (frames.isEmpty()) {
1399 (*jobs)[0].insert(node);
1401 foreach (
int frame, frames) {
1402 (*jobs)[frame].insert(node);
1427 while (prevLayer && prevLayer->
isFakeNode()) {
1431 if (!prevLayer)
return;
1466 if (info->frames.size() > 0) {
1471 const int currentTimeOnStart = info->image->animationInterface()->currentTime();
1473 foreach (
int frame, info->frames) {
1494 const bool skipMergingSourceLayer = !layer->
isAnimated() &&
1495 frame != currentTimeOnStart;
1512 }
else if (layer->
visible()) {
1526 }
else if (prevLayer->
visible()) {
1551 nodeParents << parent;
1552 parent = parent->parent();
1555 foreach(
KisNodeSP perspectiveParent, parents) {
1556 if (nodeParents.contains(perspectiveParent)) {
1566 bool result =
false;
1577 return node == cloneSource;
1595 KisNodeList::iterator it = nodes.begin();
1597 while (it != nodes.end()) {
1598 if ((!allowMasks && !qobject_cast<KisLayer*>(it->data())) ||
1601 it = nodes.erase(it);
1610 KisNodeList::iterator it = std::find(inputNodes.begin(), inputNodes.end(), root);
1612 if (it != inputNodes.end()) {
1614 inputNodes.erase(it);
1617 if (inputNodes.isEmpty()) {
1647 while (localRoot->
parent()) {
1648 localRoot = localRoot->
parent();
1670 while (localRoot->
parent()) {
1671 localRoot = localRoot->
parent();
1691 bool haveExternalNodes =
false;
1694 haveExternalNodes =
true;
1699 if (!haveExternalNodes) {
1702 sortedNodes = filteredNodes;
1713 const QString prefix = i18n(
"Copy of");
1714 QString newName = node->
name();
1715 if (!newName.startsWith(prefix)) {
1716 newName = QString(
"%1 %2").arg(prefix).arg(newName);
1725 if ((!excludeRoot || root->
parent()) && root->
check(props)) {
1744 int putAfterIndex = -1;
1748 visibleNodes << node;
1755 *invisibleNodes << node;
1757 if (node == *putAfter) {
1758 putAfterIndex = visibleNodes.size() - 1;
1763 if (!visibleNodes.isEmpty() && putAfterIndex >= 0) {
1764 putAfterIndex = qBound(0, putAfterIndex, visibleNodes.size() - 1);
1765 *putAfter = visibleNodes[putAfterIndex];
1768 return visibleNodes;
1773 KisNodeList::iterator it = nodes.begin();
1775 while (it != nodes.end()) {
1776 if ((*it)->userLocked()) {
1777 it = nodes.erase(it);
1816 m_info->ephemeralCommandsStore->addCommand(cmd);
1838 m_info->ephemeralCommandsStore->undoAll();
1873 bool cleanupNodes =
true,
const QString layerName = QString(),
1874 MergeFlags flags =
None)
1877 putAfter = mergedNodes.first();
1883 std::swap(mergedNodes, tempNodes);
1887 if (mergedNodes.size() <= 1 &&
1888 (!flattenSingleLayer && mergedNodes.size() == 1))
return;
1899 if (mergedNodes.isEmpty())
return;
1905 putAfter = putAfter->
parent();
1915 if (!putAfter->
parent()) {
1925 if (!invisibleNodes.isEmpty() && cleanupNodes) {
1937 putAfter = mergedNodes.first();
1947 if (mergedNodes.size() > 1 || invisibleNodes.isEmpty()) {
1972 if (!info->frames.isEmpty()) {
1973 foreach (
int frame, info->frames) {
2032 mergedNodes << image->
root();
2036 false, i18nc(
"New layer created from all the visible layers",
"Visible"),
2051 parentLayer = qobject_cast<KisLayer*>(parent.data());
2053 parent = parent->parent();
2054 }
while(!parentLayer && parent);
2060 if (!mask)
continue;
2070 m_info->dstNode = mergedMask;
2095 for (
auto it = mergedNodes.begin(); it != mergedNodes.end(); ) {
2098 it = mergedNodes.erase(it);
2100 selectionMasks.append(mask);
2105 if (mergedNodes.isEmpty())
return false;
2107 KisLayerSP parentLayer = qobject_cast<KisLayer*>(selectionMasks.first()->parent().data());
2136 mergedNodes << layer;
2152 mergedNodes << image->
root();
2161 : FlipFlopCommand(finalize, parent),
2198 return node->
uuid() == uuid;
2208 if (name.isEmpty() || (!partialMatch && child->
name() == name) || (partialMatch && child->
name().contains(name, Qt::CaseInsensitive))) {
2224 return node->
name() == name;
2234 if (delayedUpdate) {
2257 if (croppedUpdate) {
2268 return layer->
image();
2304 if (!preparedArea.contains(realNodeRect)) {
2306 QRegion dirtyRegion = realNodeRect;
2307 dirtyRegion -= preparedArea;
2309 auto rc = dirtyRegion.begin();
2310 while (rc != dirtyRegion.end()) {
2333 if (!node)
return node;
2344 bool hasNonNormalLayers =
false;
2345 bool hasTransparentLayer =
false;
2349 [&numLayers, &hasNonNormalLayers, &hasTransparentLayer, image] (
KisNodeSP node) {
2350 if (!node->inherits(
"KisLayer")) return;
2354 if (node->exactBounds().isEmpty()) return;
2357 if (!hasTransparentLayer &&
2358 node->exactBounds() != image->bounds()) {
2360 hasTransparentLayer = true;
2363 if (!hasNonNormalLayers &&
2366 hasNonNormalLayers = true;
2370 return numLayers == 1 || (!hasNonNormalLayers && !hasTransparentLayer);
2385 if (info->frames.count() > 0) {
2386 Q_FOREACH(
const int& frame, info->frames) {
2403 if (!info->hasTargetNode())
2411 if (info->frames().count() > 0) {
2412 Q_FOREACH(
const int& frame, info->frames()) {
2427 [node = info->targetNode()] (std::future<bool> completed) {
2428 return completed.get() ? node : KisNodeSP();
2448 return keyframe->frameID();
2493 if (!rasterChannel) {
2511 Q_FOREACH(
const int& frame, times ) {
2513 frameIDs << raster->frameID();
2538 QSet<int> uniqueTimes;
2540 Q_FOREACH(
const int&
id, frameIDs) {
2542 if (times.count() > 0) {
2543 uniqueTimes.insert(*times.begin());
2553 return selectedTimes;
2558 if (filterActiveFrameID) {
2562 selectedFrameIDs.remove(currentActiveFrameID);
2568 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
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)
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
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