Refactored
[TortoiseGit.git] / src / TortoiseMerge / Undo.cpp
blob098153c389fa2be70246310b2b5b5aa514c362e3
1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2006-2007, 2010-2011, 2013 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "Undo.h"
23 #include "BaseView.h"
25 void viewstate::AddViewLineFromView(CBaseView *pView, int nViewLine, bool bAddEmptyLine)
27 // is undo good place for this ?
28 if (!pView || !pView->m_pViewData)
29 return;
30 replacedlines[nViewLine] = pView->m_pViewData->GetData(nViewLine);
31 if (bAddEmptyLine)
33 addedlines.push_back(nViewLine + 1);
34 pView->AddEmptyViewLine(nViewLine);
38 void viewstate::Clear()
40 difflines.clear();
41 linestates.clear();
42 linelines.clear();
43 linesEOL.clear();
44 addedlines.clear();
46 removedlines.clear();
47 replacedlines.clear();
48 modifies = false;
51 void CUndo::MarkAsOriginalState(bool bLeft, bool bRight, bool bBottom)
53 // TODO reduce code dumplication
54 // find higest index of changing step
55 if (bLeft) // left is selected for mark
57 m_originalstateLeft = m_viewstates.size();
58 std::list<allviewstate>::reverse_iterator i = m_viewstates.rbegin();
59 while (i != m_viewstates.rend() && !i->left.modifies)
61 ++i;
62 --m_originalstateLeft;
65 if (bRight) // right is selected for mark
67 m_originalstateRight = m_viewstates.size();
68 std::list<allviewstate>::reverse_iterator i = m_viewstates.rbegin();
69 while (i != m_viewstates.rend() && !i->right.modifies)
71 ++i;
72 --m_originalstateRight;
75 if (bBottom) // bottom is selected for mark
77 m_originalstateBottom = m_viewstates.size();
78 std::list<allviewstate>::reverse_iterator i = m_viewstates.rbegin();
79 while (i != m_viewstates.rend() && !i->bottom.modifies)
81 ++i;
82 --m_originalstateBottom;
87 CUndo& CUndo::GetInstance()
89 static CUndo instance;
90 return instance;
93 CUndo::CUndo()
95 Clear();
98 CUndo::~CUndo()
102 void CUndo::AddState(const allviewstate& allstate, POINT pt)
104 m_viewstates.push_back(allstate);
105 m_caretpoints.push_back(pt);
108 bool CUndo::Undo(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)
110 if (!CanUndo())
111 return false;
113 if (m_groups.size() && m_groups.back() == m_caretpoints.size())
115 m_groups.pop_back();
116 std::list<int>::size_type b = m_groups.back();
117 m_groups.pop_back();
118 while (b < m_caretpoints.size())
119 UndoOne(pLeft, pRight, pBottom);
121 else
122 UndoOne(pLeft, pRight, pBottom);
124 CBaseView * pActiveView = NULL;
126 if (pBottom && pBottom->IsTarget())
128 pActiveView = pBottom;
130 else
131 if (pRight && pRight->IsTarget())
133 pActiveView = pRight;
135 else
136 //if (pLeft && pLeft->IsTarget())
138 pActiveView = pLeft;
142 if (pActiveView) {
143 pActiveView->ClearSelection();
144 pActiveView->BuildAllScreen2ViewVector();
145 pActiveView->RecalcAllVertScrollBars();
146 pActiveView->RecalcAllHorzScrollBars();
147 pActiveView->EnsureCaretVisible();
148 pActiveView->UpdateCaret();
150 // TODO reduce code dumplication
151 if (m_viewstates.size() < m_originalstateLeft)
153 // Left can never get back to original state now
154 m_originalstateLeft = (size_t)-1;
156 if (pLeft)
158 bool bModified = (m_originalstateLeft==(size_t)-1);
159 if (!bModified)
161 std::list<allviewstate>::iterator i = m_viewstates.begin();
162 std::advance(i, m_originalstateLeft);
163 for (; i!=m_viewstates.end(); ++i)
165 if (i->left.modifies)
167 bModified = true;
168 break;
172 pLeft->SetModified(bModified);
173 pLeft->ClearStepModifiedMark();
175 if (m_viewstates.size() < m_originalstateRight)
177 // Right can never get back to original state now
178 m_originalstateRight = (size_t)-1;
180 if (pRight)
182 bool bModified = (m_originalstateRight==(size_t)-1);
183 if (!bModified)
185 std::list<allviewstate>::iterator i = m_viewstates.begin();
186 std::advance(i, m_originalstateRight);
187 for (; i!=m_viewstates.end() && !i->right.modifies; ++i) ;
188 bModified = i!=m_viewstates.end();
190 pRight->SetModified(bModified);
191 pRight->ClearStepModifiedMark();
193 if (m_viewstates.size() < m_originalstateBottom)
195 // Bottom can never get back to original state now
196 m_originalstateBottom = (size_t)-1;
198 if (pBottom)
200 bool bModified = (m_originalstateBottom==(size_t)-1);
201 if (!bModified)
203 std::list<allviewstate>::iterator i = m_viewstates.begin();
204 std::advance(i, m_originalstateBottom);
205 for (; i!=m_viewstates.end(); ++i)
207 if (i->bottom.modifies)
209 bModified = true;
210 break;
214 pBottom->SetModified(bModified);
215 pBottom->ClearStepModifiedMark();
217 pActiveView->RefreshViews();
220 return true;
223 void CUndo::UndoOne(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)
225 allviewstate allstate = m_viewstates.back();
226 POINT pt = m_caretpoints.back();
228 Undo(allstate.left, pLeft, pt);
229 Undo(allstate.right, pRight, pt);
230 Undo(allstate.bottom, pBottom, pt);
232 m_viewstates.pop_back();
233 m_caretpoints.pop_back();
236 void CUndo::Undo(const viewstate& state, CBaseView * pView, const POINT& pt)
238 if (!pView)
239 return;
241 CViewData* viewData = pView->m_pViewData;
242 if (!viewData)
243 return;
245 for (std::list<int>::const_reverse_iterator it = state.addedlines.rbegin(); it != state.addedlines.rend(); ++it)
247 viewData->RemoveData(*it);
249 for (std::map<int, DWORD>::const_iterator it = state.linelines.begin(); it != state.linelines.end(); ++it)
251 viewData->SetLineNumber(it->first, it->second);
253 for (std::map<int, DWORD>::const_iterator it = state.linestates.begin(); it != state.linestates.end(); ++it)
255 viewData->SetState(it->first, (DiffStates)it->second);
257 for (std::map<int, EOL>::const_iterator it = state.linesEOL.begin(); it != state.linesEOL.end(); ++it)
259 viewData->SetLineEnding(it->first, (EOL)it->second);
261 for (std::map<int, CString>::const_iterator it = state.difflines.begin(); it != state.difflines.end(); ++it)
263 viewData->SetLine(it->first, it->second);
265 for (std::map<int, viewdata>::const_iterator it = state.removedlines.begin(); it != state.removedlines.end(); ++it)
267 viewData->InsertData(it->first, it->second);
269 for (std::map<int, viewdata>::const_iterator it = state.replacedlines.begin(); it != state.replacedlines.end(); ++it)
271 viewData->SetData(it->first, it->second);
274 if (pView->IsTarget())
276 pView->SetCaretViewPosition(pt);
277 pView->EnsureCaretVisible();
281 void CUndo::Clear()
283 m_viewstates.clear();
284 m_caretpoints.clear();
285 m_groups.clear();
286 m_originalstateLeft = 0;
287 m_originalstateRight = 0;
288 m_originalstateBottom = 0;
289 m_groupCount = 0;