Fix Export with resize + non-linear undo history (fix #1749)

This commit is contained in:
David Capello 2018-06-14 17:27:22 -03:00
parent 15d517c42f
commit a4d1833a9c
4 changed files with 32 additions and 17 deletions

View File

@ -16,6 +16,8 @@
#include "app/commands/params.h"
#include "app/console.h"
#include "app/context_access.h"
#include "app/document.h"
#include "app/document_undo.h"
#include "app/file/file.h"
#include "app/file/gif_format.h"
#include "app/file_selector.h"
@ -39,6 +41,7 @@
#include "doc/sprite.h"
#include "fmt/format.h"
#include "ui/ui.h"
#include "undo/undo_state.h"
namespace app {
@ -289,6 +292,10 @@ public:
protected:
void onExecute(Context* context) override;
private:
void moveToUndoState(Document* doc,
const undo::UndoState* state);
};
SaveFileCopyAsCommand::SaveFileCopyAsCommand()
@ -365,7 +372,7 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
}
// Apply scale
bool undoResize = false;
const undo::UndoState* undoState = nullptr;
if (xscale != 1.0 || yscale != 1.0) {
Command* resizeCmd = Commands::instance()->byId(CommandId::SpriteSize());
ASSERT(resizeCmd);
@ -378,6 +385,7 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
if (newHeight < 1) newHeight = 1;
if (width != newWidth || height != newHeight) {
doc->setInhibitBackup(true);
undoState = doc->undoHistory()->currentState();
Params params;
params.set("use-ui", "false");
@ -385,7 +393,6 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
params.set("height", base::convert_to<std::string>(newHeight).c_str());
params.set("resize-method", "nearest-neighbor"); // TODO add algorithm in the UI?
context->executeCommand(resizeCmd, params);
undoResize = true;
}
}
}
@ -422,15 +429,27 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
}
// Undo resize
if (undoResize) {
Command* undoCmd = Commands::instance()->byId(CommandId::Undo());
if (undoCmd)
context->executeCommand(undoCmd);
if (undoState &&
undoState != doc->undoHistory()->currentState()) {
moveToUndoState(doc, undoState);
doc->setInhibitBackup(false);
}
}
void SaveFileCopyAsCommand::moveToUndoState(Document* doc,
const undo::UndoState* state)
{
try {
DocumentWriter writer(doc, 100);
doc->undoHistory()->moveToState(state);
doc->generateMaskBoundaries();
doc->notifyGeneralUpdate();
}
catch (const std::exception& ex) {
Console::showException(ex);
}
}
Command* CommandFactory::createSaveFileCommand()
{
return new SaveFileCommand;

View File

@ -159,11 +159,7 @@ private:
view()->updateView();
}
void onAfterUndo(DocumentUndo* history) override {
selectState(history->currentState());
}
void onAfterRedo(DocumentUndo* history) override {
void onCurrentUndoStateChange(DocumentUndo* history) override {
selectState(history->currentState());
}

View File

@ -106,7 +106,7 @@ void DocumentUndo::undo()
m_totalUndoSize -= cmd->memSize();
{
m_undoHistory.undo();
notify_observers(&DocumentUndoObserver::onAfterUndo, this);
notify_observers(&DocumentUndoObserver::onCurrentUndoStateChange, this);
}
m_totalUndoSize += cmd->memSize();
if (m_totalUndoSize != oldSize)
@ -122,7 +122,7 @@ void DocumentUndo::redo()
m_totalUndoSize -= cmd->memSize();
{
m_undoHistory.redo();
notify_observers(&DocumentUndoObserver::onAfterRedo, this);
notify_observers(&DocumentUndoObserver::onCurrentUndoStateChange, this);
}
m_totalUndoSize += cmd->memSize();
if (m_totalUndoSize != oldSize)
@ -217,6 +217,7 @@ Cmd* DocumentUndo::lastExecutedCmd() const
void DocumentUndo::moveToState(const undo::UndoState* state)
{
m_undoHistory.moveTo(state);
notify_observers(&DocumentUndoObserver::onCurrentUndoStateChange, this);
// Recalculate the total undo size
size_t oldSize = m_totalUndoSize;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2015-2017 David Capello
// Copyright (C) 2015-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -22,8 +22,7 @@ class DocumentUndo;
virtual void onAddUndoState(DocumentUndo* history) = 0;
virtual void onDeleteUndoState(DocumentUndo* history,
undo::UndoState* state) = 0;
virtual void onAfterUndo(DocumentUndo* history) = 0;
virtual void onAfterRedo(DocumentUndo* history) = 0;
virtual void onCurrentUndoStateChange(DocumentUndo* history) = 0;
virtual void onClearRedo(DocumentUndo* history) = 0;
virtual void onTotalUndoSizeChange(DocumentUndo* history) = 0;
};