Krita Source Code Documentation
Loading...
Searching...
No Matches
KisNodePropertyListCommand Class Reference

The command for changing the property list of a layer. More...

#include <kis_node_property_list_command.h>

+ Inheritance diagram for KisNodePropertyListCommand:

Public Types

typedef KisBaseNode::PropertyList PropertyList
 

Public Member Functions

bool canAnnihilateWith (const KUndo2Command *other) const override
 
bool canMergeWith (const KUndo2Command *command) const override
 
int id () const override
 
 KisNodePropertyListCommand (KisNodeSP node, KisBaseNode::PropertyList newPropertyList)
 
bool mergeWith (const KUndo2Command *command) override
 
void redo () override
 
void undo () override
 
- Public Member Functions inherited from KisNodeCommand
 KisNodeCommand (const KUndo2MagicString &name, KisNodeSP node)
 
 ~KisNodeCommand () override
 
- Public Member Functions inherited from KUndo2Command
QString actionText () const
 
const KUndo2Commandchild (int index) const
 
int childCount () const
 
virtual QTime endTime () const
 
KUndo2CommandExtraDataextraData () const
 
bool hasParent () const
 
virtual bool isMerged () const
 
 KUndo2Command (const KUndo2MagicString &text, KUndo2Command *parent=0)
 
 KUndo2Command (KUndo2Command *parent=0)
 
virtual QVector< KUndo2Command * > mergeCommandsVector () const
 
virtual void redoMergedCommands ()
 
void setEndTime ()
 
virtual void setEndTime (const QTime &time)
 
void setExtraData (KUndo2CommandExtraData *data)
 
void setText (const KUndo2MagicString &text)
 
void setTime ()
 
virtual void setTime (const QTime &time)
 
virtual void setTimedID (int timedID)
 
KUndo2MagicString text () const
 
virtual QTime time () const
 
virtual int timedId () const
 
virtual bool timedMergeWith (KUndo2Command *other)
 
virtual void undoMergedCommands ()
 
virtual ~KUndo2Command ()
 
- Public Member Functions inherited from KisAsynchronouslyMergeableCommandInterface
virtual ~KisAsynchronouslyMergeableCommandInterface ()
 

Static Public Member Functions

static void setNodePropertiesAutoUndo (KisNodeSP node, KisImageSP image, PropertyList proplist)
 

Private Member Functions

void doUpdate (const KisBaseNode::PropertyList &oldPropertyList, const KisBaseNode::PropertyList &newPropertyList, const QRect &totalUpdateExtent)
 

Static Private Member Functions

static const QSet< QString > & propsWithNoUpdates ()
 

Private Attributes

KisBaseNode::PropertyList m_newPropertyList
 
KisBaseNode::PropertyList m_oldPropertyList
 

Additional Inherited Members

- Protected Attributes inherited from KisNodeCommand
KisNodeSP m_node
 

Detailed Description

The command for changing the property list of a layer.

Definition at line 16 of file kis_node_property_list_command.h.

Member Typedef Documentation

◆ PropertyList

Constructor & Destructor Documentation

◆ KisNodePropertyListCommand()

KisNodePropertyListCommand::KisNodePropertyListCommand ( KisNodeSP node,
KisBaseNode::PropertyList newPropertyList )

Constructor

Parameters
nodethe layer to add
newPropertyListthe property list to which the node to be added

TODO instead of "Property Changes" check which property has been changed and display either lock/unlock, visible/hidden or "Property Changes" (this require new strings)

Definition at line 60 of file kis_node_property_list_command.cpp.

61 : KisNodeCommand(kundo2_i18n("Property Changes"), node),
62 m_newPropertyList(newPropertyList),
69{
70}
KisNodeCommand(const KUndo2MagicString &name, KisNodeSP node)
KisBaseNode::PropertyList m_newPropertyList
KisBaseNode::PropertyList m_oldPropertyList
KUndo2MagicString kundo2_i18n(const char *text)
virtual PropertyList sectionModelProperties() const

Member Function Documentation

◆ canAnnihilateWith()

bool KisNodePropertyListCommand::canAnnihilateWith ( const KUndo2Command * other) const
overridevirtual

Attempts to merge this command with command and checks if the two commands compensate each other. If the function returns true, both commands are removed from the stack.

If this function returns true, calling this command's redo() followed by other redo() must have no effect.

The function itself shouldn't do any changes to the command, because after returning true, the command will be deleted as a "noop"

KUndo2QStack will only try to merge two commands if they have the same id, and the id is not -1.

The default implementation returns false.

See also
id() KUndo2QStack::push()

Reimplemented from KUndo2Command.

Definition at line 140 of file kis_node_property_list_command.cpp.

141{
142 const KisNodePropertyListCommand *other =
143 dynamic_cast<const KisNodePropertyListCommand*>(command);
144
145 return other && other->m_node == m_node &&
146 changedProperties(m_oldPropertyList, other->m_newPropertyList).isEmpty();
147}
The command for changing the property list of a layer.

References m_newPropertyList, KisNodeCommand::m_node, and m_oldPropertyList.

◆ canMergeWith()

bool KisNodePropertyListCommand::canMergeWith ( const KUndo2Command * command) const
overridevirtual
Returns
true if command can be merged with (*this) command using KUndo2Command::mergeWith() call.

WARNING: if canMergeWith() returned true, then mergeWith() must also return true. Otherwise KisSavedMacroCommand will be able to enter inconsistent state and assert.

Implements KisAsynchronouslyMergeableCommandInterface.

Definition at line 129 of file kis_node_property_list_command.cpp.

130{
131 const KisNodePropertyListCommand *other =
132 dynamic_cast<const KisNodePropertyListCommand*>(command);
133
134 return other && other->m_node == m_node &&
135 (changedProperties(m_oldPropertyList, m_newPropertyList).isEmpty() ||
136 changedProperties(m_oldPropertyList, m_newPropertyList) ==
137 changedProperties(other->m_oldPropertyList, other->m_newPropertyList));
138}

References m_newPropertyList, KisNodeCommand::m_node, and m_oldPropertyList.

◆ doUpdate()

void KisNodePropertyListCommand::doUpdate ( const KisBaseNode::PropertyList & oldPropertyList,
const KisBaseNode::PropertyList & newPropertyList,
const QRect & totalUpdateExtent )
private

Sometimes the node might refuse to change the property, e.g. needs-update for colorize mask. In this case we should avoid issuing the update and set-modified call.

Definition at line 156 of file kis_node_property_list_command.cpp.

159{
164 if (oldPropertyList == newPropertyList) {
165 return;
166 }
167
168 bool oldPassThroughValue = false;
169 bool newPassThroughValue = false;
170
171 bool oldVisibilityValue = false;
172 bool newVisibilityValue = false;
173
174 Q_FOREACH (const KisBaseNode::Property &prop, oldPropertyList) {
176 oldPassThroughValue = prop.state.toBool();
177 }
178 if (prop.id == KisLayerPropertiesIcons::visible.id()) {
179 oldVisibilityValue = prop.state.toBool();
180 }
181 }
182
183 Q_FOREACH (const KisBaseNode::Property &prop, newPropertyList) {
185 newPassThroughValue = prop.state.toBool();
186 }
187 if (prop.id == KisLayerPropertiesIcons::visible.id()) {
188 newVisibilityValue = prop.state.toBool();
189 }
190 }
191
192 if (oldPassThroughValue && !newPassThroughValue) {
193 KisLayerSP layer(qobject_cast<KisLayer*>(m_node.data()));
194 KisImageSP image = layer->image().toStrongRef();
195 if (image) {
196 image->refreshGraphAsync(layer);
197 }
198 } else if ((m_node->parent() && !oldPassThroughValue && newPassThroughValue) ||
199 (oldPassThroughValue && newPassThroughValue &&
200 !oldVisibilityValue && newVisibilityValue)) {
201
202 KisLayerSP layer(qobject_cast<KisLayer*>(m_node->parent().data()));
203 KisImageSP image = layer->image().toStrongRef();
204 if (image) {
205 image->refreshGraphAsync(layer);
206 }
207 } else if (checkOnionSkinChanged(oldPropertyList, newPropertyList)) {
208 m_node->setDirtyDontResetAnimationCache(totalUpdateExtent);
209 } else {
210 m_node->setDirty(totalUpdateExtent); // TODO check if visibility was actually changed or not
211 }
212}
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
QString id() const
Definition KoID.cpp:63
bool checkOnionSkinChanged(const KisBaseNode::PropertyList &oldPropertyList, const KisBaseNode::PropertyList &newPropertyList)
void setDirtyDontResetAnimationCache()
Definition kis_node.cpp:599
KisNodeWSP parent
Definition kis_node.cpp:86
virtual void setDirty()
Definition kis_node.cpp:577

References checkOnionSkinChanged(), KisSharedPtr< T >::data(), KisWeakSharedPtr< T >::data(), KoID::id(), KisBaseNode::Property::id, KisBaseNode::image, KisNodeCommand::m_node, KisNode::parent, KisLayerPropertiesIcons::passThrough, KisImage::refreshGraphAsync(), KisNode::setDirty(), KisNode::setDirtyDontResetAnimationCache(), KisBaseNode::Property::state, KisWeakSharedPtr< T >::toStrongRef(), and KisLayerPropertiesIcons::visible.

◆ id()

int KisNodePropertyListCommand::id ( ) const
overridevirtual

Returns the ID of this command.

A command ID is used in command compression. It must be an integer unique to this command's class, or -1 if the command doesn't support compression.

If the command supports compression this function must be overridden in the derived class to return the correct ID. The base implementation returns -1.

KUndo2QStack::push() will only try to merge two commands if they have the same ID, and the ID is not -1.

See also
mergeWith(), KUndo2QStack::push()

Reimplemented from KUndo2Command.

Definition at line 100 of file kis_node_property_list_command.cpp.

References KisCommandUtils::NodePropertyListCommandId.

◆ mergeWith()

bool KisNodePropertyListCommand::mergeWith ( const KUndo2Command * command)
overridevirtual

Attempts to merge this command with command. Returns true on success; otherwise returns false.

If this function returns true, calling this command's redo() must have the same effect as redoing both this command and command. Similarly, calling this command's undo() must have the same effect as undoing command and this command.

KUndo2QStack will only try to merge two commands if they have the same id, and the id is not -1.

The default implementation returns false.

See also
id() KUndo2QStack::push()

Reimplemented from KUndo2Command.

Definition at line 105 of file kis_node_property_list_command.cpp.

106{
107 const KisNodePropertyListCommand *other =
108 dynamic_cast<const KisNodePropertyListCommand*>(command);
109
110 if (other && other->m_node == m_node &&
111 (changedProperties(m_oldPropertyList, m_newPropertyList).isEmpty() ||
112 changedProperties(m_oldPropertyList, m_newPropertyList) ==
113 changedProperties(other->m_oldPropertyList, other->m_newPropertyList))) {
114
115 const QSet<QString> changedInTheMeantime =
116 changedProperties(m_newPropertyList, other->m_oldPropertyList);
117
118 KIS_SAFE_ASSERT_RECOVER_NOOP(changedInTheMeantime.isEmpty() ||
119 (changedInTheMeantime.size() == 1 &&
120 *changedInTheMeantime.begin() == KisLayerPropertiesIcons::colorOverlay.id()));
121
123 return true;
124 }
125
126 return false;
127}
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KisLayerPropertiesIcons::colorOverlay, KoID::id(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_newPropertyList, KisNodeCommand::m_node, and m_oldPropertyList.

◆ propsWithNoUpdates()

const QSet< QString > & KisNodePropertyListCommand::propsWithNoUpdates ( )
staticprivate

Definition at line 214 of file kis_node_property_list_command.cpp.

References KisLayerPropertiesIcons::alphaLocked, KisLayerPropertiesIcons::colorizeNeedsUpdate, KisLayerPropertiesIcons::colorLabelIndex, KoID::id(), KisLayerPropertiesIcons::layerError, KisLayerPropertiesIcons::locked, KisLayerPropertiesIcons::openFileLayerFile, and KisLayerPropertiesIcons::selectionActive.

◆ redo()

void KisNodePropertyListCommand::redo ( )
overridevirtual

Applies a change to the document. This function must be implemented in the derived class. Calling KUndo2QStack::push(), KUndo2QStack::undo() or KUndo2QStack::redo() from this function leads to undefined behavior.

The default implementation calls redo() on all child commands.

See also
undo()

Reimplemented from KUndo2Command.

Definition at line 72 of file kis_node_property_list_command.cpp.

73{
75 const QSet<QString> changed = changedProperties(propsBefore, m_newPropertyList);
76 if (changed.isEmpty()) return;
77
78 const QRect oldExtent = m_node->projectionPlane()->tightUserVisibleBounds();
80
81 if (!propsWithNoUpdates().contains(changed)) {
82 doUpdate(propsBefore, m_node->sectionModelProperties(), oldExtent | m_node->projectionPlane()->tightUserVisibleBounds());
83 }
84}
void doUpdate(const KisBaseNode::PropertyList &oldPropertyList, const KisBaseNode::PropertyList &newPropertyList, const QRect &totalUpdateExtent)
static const QSet< QString > & propsWithNoUpdates()
virtual void setSectionModelProperties(const PropertyList &properties)
virtual KisAbstractProjectionPlaneSP projectionPlane() const
Definition kis_node.cpp:240

References doUpdate(), m_newPropertyList, KisNodeCommand::m_node, KisNode::projectionPlane(), propsWithNoUpdates(), KisBaseNode::sectionModelProperties(), and KisBaseNode::setSectionModelProperties().

◆ setNodePropertiesAutoUndo()

void KisNodePropertyListCommand::setNodePropertiesAutoUndo ( KisNodeSP node,
KisImageSP image,
PropertyList proplist )
static

HACK ALERT!

Here we start a fake legacy stroke, so that all the LoD planes would be invalidated. Ideally, we should refactor this method and avoid resetting LoD planes when node visibility changes, Instead there should be two commands executes: LoD agnostic one (which sets the properties themselves), and two LoD-specific update commands: one for lodN and another one for lod0.

Definition at line 228 of file kis_node_property_list_command.cpp.

229{
230 const QSet<QString> properties = changedProperties(node->sectionModelProperties(), proplist);
231
232 const bool undo = !properties.isEmpty() &&
233 (properties.size() != 1 ||
235
236 std::unique_ptr<KUndo2Command> cmd(new KisNodePropertyListCommand(node, proplist));
237
238 if (undo) {
239 image->undoAdapter()->addCommand(cmd.release());
240 }
241 else {
253 struct SimpleLodResettingStroke : public KisSimpleStrokeStrategy {
254 SimpleLodResettingStroke(KUndo2Command *cmd)
255 : KisSimpleStrokeStrategy(QLatin1String("SimpleLodResettingStroke")),
256 m_cmd(cmd)
257 {
258 setClearsRedoOnStart(false);
259 this->enableJob(JOB_INIT, true);
260 }
261
262 void initStrokeCallback() override {
263 m_cmd->redo();
264 // NOTE: we don't Q_EMIT imageModified signal here because this
265 // branch is only taken for the stasis changes, that do not
266 // change actual image representation.
267 }
268
269 private:
270 QScopedPointer<KUndo2Command> m_cmd;
271 };
272
273 KisStrokeId strokeId = image->startStroke(new SimpleLodResettingStroke(cmd.release()));
274 image->endStroke(strokeId);
275 }
276
277}
KisUndoAdapter * undoAdapter() const
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void endStroke(KisStrokeId id) override
static bool isStatelessProperty(const QString &id)
KisNodePropertyListCommand(KisNodeSP node, KisBaseNode::PropertyList newPropertyList)
virtual void addCommand(KUndo2Command *cmd)=0

References KisUndoAdapter::addCommand(), KisImage::endStroke(), KisLayerPropertiesIcons::isStatelessProperty(), KisNodePropertyListCommand(), KisBaseNode::sectionModelProperties(), KisImage::startStroke(), undo(), and KisImage::undoAdapter().

◆ undo()

void KisNodePropertyListCommand::undo ( )
overridevirtual

Reverts a change to the document. After undo() is called, the state of the document should be the same as before redo() was called. This function must be implemented in the derived class. Calling KUndo2QStack::push(), KUndo2QStack::undo() or KUndo2QStack::redo() from this function leads to undefined behavior.

The default implementation calls undo() on all child commands in reverse order.

See also
redo()

Reimplemented from KUndo2Command.

Definition at line 86 of file kis_node_property_list_command.cpp.

87{
89 const QSet<QString> changed = changedProperties(propsBefore, m_oldPropertyList);
90 if (changed.isEmpty()) return;
91
92 const QRect oldExtent = m_node->projectionPlane()->tightUserVisibleBounds();
94
95 if (!propsWithNoUpdates().contains(changed)) {
96 doUpdate(propsBefore, m_node->sectionModelProperties(), oldExtent | m_node->projectionPlane()->tightUserVisibleBounds());
97 }
98}

References doUpdate(), KisNodeCommand::m_node, m_oldPropertyList, KisNode::projectionPlane(), propsWithNoUpdates(), KisBaseNode::sectionModelProperties(), and KisBaseNode::setSectionModelProperties().

Member Data Documentation

◆ m_newPropertyList

KisBaseNode::PropertyList KisNodePropertyListCommand::m_newPropertyList
private

Definition at line 43 of file kis_node_property_list_command.h.

◆ m_oldPropertyList

KisBaseNode::PropertyList KisNodePropertyListCommand::m_oldPropertyList
private

Definition at line 44 of file kis_node_property_list_command.h.


The documentation for this class was generated from the following files: