1 // Aseprite 2 // Copyright (C) 2001-2018 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_transaction.h" 12 13 #include "app/context.h" 14 #include "app/site.h" 15 16 #ifdef ENABLE_UI 17 #include "app/app.h" 18 #include "app/ui/timeline/timeline.h" 19 #endif 20 21 namespace app { 22 CmdTransaction(const std::string & label,bool changeSavedState,int * savedCounter)23CmdTransaction::CmdTransaction(const std::string& label, 24 bool changeSavedState, 25 int* savedCounter) 26 : m_ranges(nullptr) 27 , m_label(label) 28 , m_changeSavedState(changeSavedState) 29 , m_savedCounter(savedCounter) 30 { 31 } 32 setNewDocRange(const DocRange & range)33void CmdTransaction::setNewDocRange(const DocRange& range) 34 { 35 #ifdef ENABLE_UI 36 if (m_ranges) 37 range.write(m_ranges->m_after); 38 #endif 39 } 40 commit()41void CmdTransaction::commit() 42 { 43 m_spritePositionAfter = calcSpritePosition(); 44 45 // We cannot capture m_ranges->m_after from the Timeline here 46 // because the document range in the Timeline is updated after the 47 // commit/command (on Timeline::onAfterCommandExecution). 48 // 49 // So m_ranges->m_after is captured explicitly in 50 // setNewDocRange(). 51 } 52 documentRangeBeforeExecute() const53std::istream* CmdTransaction::documentRangeBeforeExecute() const 54 { 55 if (m_ranges && m_ranges->m_before.tellp() > 0) { 56 m_ranges->m_before.seekg(0); 57 return &m_ranges->m_before; 58 } 59 else 60 return nullptr; 61 } 62 documentRangeAfterExecute() const63std::istream* CmdTransaction::documentRangeAfterExecute() const 64 { 65 if (m_ranges && m_ranges->m_after.tellp() > 0) { 66 m_ranges->m_after.seekg(0); 67 return &m_ranges->m_after; 68 } 69 else 70 return nullptr; 71 } 72 onExecute()73void CmdTransaction::onExecute() 74 { 75 CmdSequence::onExecute(); 76 77 // The execution of CmdTransaction is called by Transaction at the 78 // very beginning, just to save the current sprite position. 79 m_spritePositionBefore = calcSpritePosition(); 80 #ifdef ENABLE_UI 81 if (isDocRangeEnabled()) { 82 m_ranges.reset(new Ranges); 83 calcDocRange().write(m_ranges->m_before); 84 } 85 #endif 86 87 if (m_changeSavedState) 88 ++(*m_savedCounter); 89 } 90 onUndo()91void CmdTransaction::onUndo() 92 { 93 CmdSequence::onUndo(); 94 95 if (m_changeSavedState) 96 --(*m_savedCounter); 97 } 98 onRedo()99void CmdTransaction::onRedo() 100 { 101 CmdSequence::onRedo(); 102 103 if (m_changeSavedState) 104 ++(*m_savedCounter); 105 } 106 onLabel() const107std::string CmdTransaction::onLabel() const 108 { 109 return m_label; 110 } 111 onMemSize() const112size_t CmdTransaction::onMemSize() const 113 { 114 size_t size = CmdSequence::onMemSize(); 115 if (m_ranges) { 116 size += (m_ranges->m_before.tellp() + 117 m_ranges->m_after.tellp()); 118 } 119 return size; 120 } 121 calcSpritePosition() const122SpritePosition CmdTransaction::calcSpritePosition() const 123 { 124 Site site = context()->activeSite(); 125 return SpritePosition(site.layer(), site.frame()); 126 } 127 isDocRangeEnabled() const128bool CmdTransaction::isDocRangeEnabled() const 129 { 130 #ifdef ENABLE_UI 131 if (App::instance()) { 132 Timeline* timeline = App::instance()->timeline(); 133 if (timeline && timeline->range().enabled()) 134 return true; 135 } 136 #endif 137 return false; 138 } 139 calcDocRange() const140DocRange CmdTransaction::calcDocRange() const 141 { 142 #ifdef ENABLE_UI 143 // TODO We cannot use Context::activeSite() because it losts 144 // important information about the DocRange() (type and 145 // flags). 146 if (App::instance()) { 147 Timeline* timeline = App::instance()->timeline(); 148 if (timeline) 149 return timeline->range(); 150 } 151 #endif 152 return DocRange(); 153 } 154 155 } // namespace app 156