Commit 23184897 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Merge branch 'kazakov/compressible-visibility-new-master'

parents 6ece3f60 0c5a02e9
......@@ -339,6 +339,29 @@ bool KUndo2Command::timedMergeWith(KUndo2Command *other)
return false;
return true;
}
/*!
Attempts to merge this command with \a 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
\p other redo() must have no effect.
The function itself shouln'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.
\sa id() KUndo2QStack::push()
*/
bool KUndo2Command::annihilateWith(const KUndo2Command *other)
{
Q_UNUSED(other)
return false;
}
void KUndo2Command::setTime()
{
m_timeOfCreation = QTime::currentTime();
......@@ -823,7 +846,27 @@ void KUndo2QStack::push(KUndo2Command *cmd)
}
m_index = m_command_list.size();
}
if (try_merge && cur->mergeWith(cmd)) {
if (try_merge && !macro && cur->annihilateWith(cmd)) {
delete cmd;
if (!macro) {
// this condition must be ruled out by try_merge check
// otherwise we would have to do cleanup for the clean state
Q_ASSERT(m_clean_index != m_index);
delete m_command_list.takeLast();
m_index--;
emit indexChanged(m_index);
emit canUndoChanged(canUndo());
emit undoTextChanged(undoText());
emit canRedoChanged(canRedo());
emit redoTextChanged(redoText());
} else {
delete m_macro_stack.takeLast();
}
} else if (try_merge && cur->mergeWith(cmd)) {
delete cmd;
if (!macro) {
emit indexChanged(m_index);
......
......@@ -104,6 +104,8 @@ public:
virtual bool mergeWith(const KUndo2Command *other);
virtual bool timedMergeWith(KUndo2Command *other);
virtual bool annihilateWith(const KUndo2Command *other);
int childCount() const;
const KUndo2Command *child(int index) const;
......
......@@ -117,6 +117,15 @@ bool KisNodePropertyListCommand::canMergeWith(const KUndo2Command *command) cons
changedProperties(other->m_oldPropertyList, other->m_newPropertyList));
}
bool KisNodePropertyListCommand::annihilateWith(const KUndo2Command *command)
{
const KisNodePropertyListCommand *other =
dynamic_cast<const KisNodePropertyListCommand*>(command);
return other && other->m_node == m_node &&
changedProperties(m_oldPropertyList, other->m_newPropertyList).isEmpty();
}
bool checkOnionSkinChanged(const KisBaseNode::PropertyList &oldPropertyList,
const KisBaseNode::PropertyList &newPropertyList)
{
......@@ -184,15 +193,7 @@ void KisNodePropertyListCommand::doUpdate(const KisBaseNode::PropertyList &oldPr
void KisNodePropertyListCommand::setNodePropertiesAutoUndo(KisNodeSP node, KisImageSP image, PropertyList proplist)
{
QSet<QString> changedProps = changedProperties(node->sectionModelProperties(),
proplist);
changedProps.remove(KisLayerPropertiesIcons::visible.id());
changedProps.remove(KisLayerPropertiesIcons::locked.id());
changedProps.remove(KisLayerPropertiesIcons::selectionActive.id());
changedProps.remove(KisLayerPropertiesIcons::alphaLocked.id());
changedProps.remove(KisLayerPropertiesIcons::colorizeNeedsUpdate.id());
const bool undo = !changedProps.isEmpty();
const bool undo = !changedProperties(node->sectionModelProperties(), proplist).isEmpty();
QScopedPointer<KUndo2Command> cmd(new KisNodePropertyListCommand(node, proplist));
......@@ -214,10 +215,9 @@ void KisNodePropertyListCommand::setNodePropertiesAutoUndo(KisNodeSP node, KisIm
*/
struct SimpleLodResettingStroke : public KisSimpleStrokeStrategy {
SimpleLodResettingStroke(KUndo2Command *cmd, KisImageSP image)
SimpleLodResettingStroke(KUndo2Command *cmd)
: KisSimpleStrokeStrategy(QLatin1String("SimpleLodResettingStroke")),
m_cmd(cmd),
m_image(image)
m_cmd(cmd)
{
setClearsRedoOnStart(false);
this->enableJob(JOB_INIT, true);
......@@ -225,15 +225,13 @@ void KisNodePropertyListCommand::setNodePropertiesAutoUndo(KisNodeSP node, KisIm
void initStrokeCallback() override {
m_cmd->redo();
m_image->setModifiedWithoutUndo();
}
private:
QScopedPointer<KUndo2Command> m_cmd;
KisImageSP m_image;
};
KisStrokeId strokeId = image->startStroke(new SimpleLodResettingStroke(cmd.take(), image));
KisStrokeId strokeId = image->startStroke(new SimpleLodResettingStroke(cmd.take()));
image->endStroke(strokeId);
}
......
......@@ -30,6 +30,7 @@ public:
int id() const override;
bool mergeWith(const KUndo2Command *command) override;
bool canMergeWith(const KUndo2Command *command) const override;
bool annihilateWith(const KUndo2Command *other) override;
typedef KisBaseNode::PropertyList PropertyList;
static void setNodePropertiesAutoUndo(KisNodeSP node, KisImageSP image, PropertyList proplist);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment