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 58 of file kis_node_property_list_command.cpp.

59 : KisNodeCommand(kundo2_i18n("Property Changes"), node),
60 m_newPropertyList(newPropertyList),
67{
68}
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 138 of file kis_node_property_list_command.cpp.

139{
140 const KisNodePropertyListCommand *other =
141 dynamic_cast<const KisNodePropertyListCommand*>(command);
142
143 return other && other->m_node == m_node &&
144 changedProperties(m_oldPropertyList, other->m_newPropertyList).isEmpty();
145}
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 127 of file kis_node_property_list_command.cpp.

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

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 154 of file kis_node_property_list_command.cpp.

157{
162 if (oldPropertyList == newPropertyList) {
163 return;
164 }
165
166 bool oldPassThroughValue = false;
167 bool newPassThroughValue = false;
168
169 bool oldVisibilityValue = false;
170 bool newVisibilityValue = false;
171
172 Q_FOREACH (const KisBaseNode::Property &prop, oldPropertyList) {
174 oldPassThroughValue = prop.state.toBool();
175 }
176 if (prop.id == KisLayerPropertiesIcons::visible.id()) {
177 oldVisibilityValue = prop.state.toBool();
178 }
179 }
180
181 Q_FOREACH (const KisBaseNode::Property &prop, newPropertyList) {
183 newPassThroughValue = prop.state.toBool();
184 }
185 if (prop.id == KisLayerPropertiesIcons::visible.id()) {
186 newVisibilityValue = prop.state.toBool();
187 }
188 }
189
190 if (oldPassThroughValue && !newPassThroughValue) {
191 KisLayerSP layer(qobject_cast<KisLayer*>(m_node.data()));
192 KisImageSP image = layer->image().toStrongRef();
193 if (image) {
194 image->refreshGraphAsync(layer);
195 }
196 } else if ((m_node->parent() && !oldPassThroughValue && newPassThroughValue) ||
197 (oldPassThroughValue && newPassThroughValue &&
198 !oldVisibilityValue && newVisibilityValue)) {
199
200 KisLayerSP layer(qobject_cast<KisLayer*>(m_node->parent().data()));
201 KisImageSP image = layer->image().toStrongRef();
202 if (image) {
203 image->refreshGraphAsync(layer);
204 }
205 } else if (checkOnionSkinChanged(oldPropertyList, newPropertyList)) {
206 m_node->setDirtyDontResetAnimationCache(totalUpdateExtent);
207 } else {
208 m_node->setDirty(totalUpdateExtent); // TODO check if visibility was actually changed or not
209 }
210}
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 98 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 103 of file kis_node_property_list_command.cpp.

104{
105 const KisNodePropertyListCommand *other =
106 dynamic_cast<const KisNodePropertyListCommand*>(command);
107
108 if (other && other->m_node == m_node &&
109 (changedProperties(m_oldPropertyList, m_newPropertyList).isEmpty() ||
110 changedProperties(m_oldPropertyList, m_newPropertyList) ==
111 changedProperties(other->m_oldPropertyList, other->m_newPropertyList))) {
112
113 const QSet<QString> changedInTheMeantime =
114 changedProperties(m_newPropertyList, other->m_oldPropertyList);
115
116 KIS_SAFE_ASSERT_RECOVER_NOOP(changedInTheMeantime.isEmpty() ||
117 (changedInTheMeantime.size() == 1 &&
118 *changedInTheMeantime.begin() == KisLayerPropertiesIcons::colorOverlay.id()));
119
121 return true;
122 }
123
124 return false;
125}
#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 212 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 70 of file kis_node_property_list_command.cpp.

71{
73 const QSet<QString> changed = changedProperties(propsBefore, m_newPropertyList);
74 if (changed.isEmpty()) return;
75
76 const QRect oldExtent = m_node->projectionPlane()->tightUserVisibleBounds();
78
79 if (!propsWithNoUpdates().contains(changed)) {
80 doUpdate(propsBefore, m_node->sectionModelProperties(), oldExtent | m_node->projectionPlane()->tightUserVisibleBounds());
81 }
82}
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 226 of file kis_node_property_list_command.cpp.

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

References KisUndoAdapter::addCommand(), KisLayerPropertiesIcons::colorizeNeedsUpdate, KisImage::endStroke(), KoID::id(), KisNodePropertyListCommand(), KisLayerPropertiesIcons::openFileLayerFile, 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 84 of file kis_node_property_list_command.cpp.

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

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: