aseprite/src/app/undo_transaction.cpp
David Capello 81ffb0c5bd Refactor: Create doc::Context and move some logic from app::Document to doc::Document
The objective of these changes is to create a more testable doc/logic API.

Included changes:
- Added doc::Context, doc::Documents (the old app::Documents),
  and doc::Sprites (and observers for each)
- Added raster::Sprite::createBasicSprite()
- Added doc::ColorMode (equal to raster::PixelFormat)
- Added some methods to doc::Document: context(), sprites(), sprite()
  (to replace app::Document::getSprite()), width/height(), colorMode(),
  name(), and close()
- Moved app::DocumentObserver/Event to doc::DocumentObserver/Event
- Replaced app::ContextObserver with doc::DocumentsObserver and a couple
  of signals.
- Renamed app::Context::getActiveDocument() with
  doc::Context::activeDocument()
- Renamed app::Context::getActiveLocation() with
  app::Context::activeLocation()
- Removed app::ContextObserverList
- Removed app::DocumentId (now we can use doc::ObjectId)
- Removed app::Context::getSettings()
2014-07-29 00:53:24 -03:00

140 lines
3.6 KiB
C++

/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/undo_transaction.h"
#include "app/context_access.h"
#include "app/document.h"
#include "app/document_undo.h"
#include "app/undoers/close_group.h"
#include "app/undoers/open_group.h"
#include "raster/sprite.h"
#include "undo/undo_history.h"
namespace app {
UndoTransaction::UndoTransaction(Context* context, const char* label, undo::Modification modification)
: m_context(context)
, m_label(label)
, m_modification(modification)
{
ASSERT(label != NULL);
DocumentLocation location = m_context->activeLocation();
m_document = location.document();
m_sprite = location.sprite();
m_undo = m_document->getUndo();
m_closed = false;
m_committed = false;
m_enabledFlag = m_undo->isEnabled();
if (isEnabled()) {
SpritePosition position(m_sprite->layerToIndex(location.layer()),
location.frame());
m_undo->pushUndoer(new undoers::OpenGroup(getObjects(),
m_label,
m_modification,
m_sprite,
position));
}
}
UndoTransaction::~UndoTransaction()
{
try {
if (isEnabled()) {
// If it isn't committed, we have to rollback all changes.
if (!m_committed && !m_closed)
rollback();
ASSERT(m_closed);
}
}
catch (...) {
// Just avoid throwing an exception in the dtor (just in case
// rollback() failed).
// TODO logging error
}
}
void UndoTransaction::closeUndoGroup()
{
ASSERT(!m_closed);
if (isEnabled()) {
DocumentLocation location = m_context->activeLocation();
SpritePosition position(m_sprite->layerToIndex(location.layer()),
location.frame());
// Close the undo information.
m_undo->pushUndoer(new undoers::CloseGroup(getObjects(),
m_label,
m_modification,
m_sprite,
position));
m_closed = true;
}
}
void UndoTransaction::commit()
{
ASSERT(!m_closed);
ASSERT(!m_committed);
if (isEnabled()) {
closeUndoGroup();
m_committed = true;
}
}
void UndoTransaction::rollback()
{
ASSERT(!m_closed);
ASSERT(!m_committed);
if (isEnabled()) {
closeUndoGroup();
// Undo the group of operations.
m_undo->doUndo();
// Clear the redo (sorry to the user, here we lost the old redo
// information).
m_undo->clearRedo();
}
}
void UndoTransaction::pushUndoer(undo::Undoer* undoer)
{
m_undo->pushUndoer(undoer);
}
undo::ObjectsContainer* UndoTransaction::getObjects() const
{
return m_undo->getObjects();
}
} // namespace app