1// Aseprite
2// Copyright (C) 2001-2015 David Capello
3//
4// This program is distributed under the terms of
5// the End-User License Agreement for Aseprite.
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include "app/cmd/replace_image.h"
12
13#include "doc/cel.h"
14#include "doc/cels_range.h"
15#include "doc/image.h"
16#include "doc/image_io.h"
17#include "doc/image_ref.h"
18#include "doc/sprite.h"
19#include "doc/subobjects_io.h"
20#include "doc/tilesets.h"
21
22namespace app {
23namespace cmd {
24
25using namespace doc;
26
27ReplaceImage::ReplaceImage(Sprite* sprite, const ImageRef& oldImage, const ImageRef& newImage)
28 : WithSprite(sprite)
29 , m_oldImageId(oldImage->id())
30 , m_newImageId(newImage->id())
31 , m_newImage(newImage)
32{
33}
34
35void ReplaceImage::onExecute()
36{
37 // Save old image in m_copy. We cannot keep an ImageRef to this
38 // image, because there are other undo branches that could try to
39 // modify/re-add this same image ID
40 ImageRef oldImage = sprite()->getImageRef(m_oldImageId);
41 ASSERT(oldImage);
42 m_copy.reset(Image::createCopy(oldImage.get()));
43
44 replaceImage(m_oldImageId, m_newImage);
45 m_newImage.reset();
46}
47
48void ReplaceImage::onUndo()
49{
50 ImageRef newImage = sprite()->getImageRef(m_newImageId);
51 ASSERT(newImage);
52 ASSERT(!sprite()->getImageRef(m_oldImageId));
53 m_copy->setId(m_oldImageId);
54
55 replaceImage(m_newImageId, m_copy);
56 m_copy.reset(Image::createCopy(newImage.get()));
57}
58
59void ReplaceImage::onRedo()
60{
61 ImageRef oldImage = sprite()->getImageRef(m_oldImageId);
62 ASSERT(oldImage);
63 ASSERT(!sprite()->getImageRef(m_newImageId));
64 m_copy->setId(m_newImageId);
65
66 replaceImage(m_oldImageId, m_copy);
67 m_copy.reset(Image::createCopy(oldImage.get()));
68}
69
70void ReplaceImage::replaceImage(ObjectId oldId, const ImageRef& newImage)
71{
72 Sprite* spr = sprite();
73
74 for (Cel* cel : spr->uniqueCels()) {
75 if (cel->image()->id() == oldId)
76 cel->data()->incrementVersion();
77 }
78
79 if (spr->hasTilesets()) {
80 for (Tileset* tileset : *spr->tilesets()) {
81 for (tile_index i=0; i<tileset->size(); ++i) {
82 ImageRef image = tileset->get(i);
83 if (image && image->id() == oldId)
84 tileset->incrementVersion();
85 }
86 }
87 }
88
89 spr->replaceImage(oldId, newImage);
90}
91
92} // namespace cmd
93} // namespace app
94