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.
25 void viewstate::AddViewLineFromView(CBaseView
*pView
, int nViewLine
, bool bAddEmptyLine
)
27 // is undo good place for this ?
28 if (!pView
|| !pView
->m_pViewData
)
30 replacedlines
[nViewLine
] = pView
->m_pViewData
->GetData(nViewLine
);
33 addedlines
.push_back(nViewLine
+ 1);
34 pView
->AddEmptyViewLine(nViewLine
);
38 void viewstate::Clear()
48 replacedlines
.clear();
52 void CUndo::MarkAsOriginalState(bool bLeft
, bool bRight
, bool bBottom
)
54 // TODO reduce code dumplication
55 // find higest index of changing step
56 if (bLeft
) // left is selected for mark
58 m_originalstateLeft
= m_viewstates
.size();
59 std::list
<allviewstate
>::reverse_iterator i
= m_viewstates
.rbegin();
60 while (i
!= m_viewstates
.rend() && !i
->left
.modifies
)
63 --m_originalstateLeft
;
66 if (bRight
) // right is selected for mark
68 m_originalstateRight
= m_viewstates
.size();
69 std::list
<allviewstate
>::reverse_iterator i
= m_viewstates
.rbegin();
70 while (i
!= m_viewstates
.rend() && !i
->right
.modifies
)
73 --m_originalstateRight
;
76 if (bBottom
) // bottom is selected for mark
78 m_originalstateBottom
= m_viewstates
.size();
79 std::list
<allviewstate
>::reverse_iterator i
= m_viewstates
.rbegin();
80 while (i
!= m_viewstates
.rend() && !i
->bottom
.modifies
)
83 --m_originalstateBottom
;
88 CUndo
& CUndo::GetInstance()
90 static CUndo instance
;
103 void CUndo::AddState(const allviewstate
& allstate
, POINT pt
)
105 m_viewstates
.push_back(allstate
);
106 m_caretpoints
.push_back(pt
);
109 bool CUndo::Undo(CBaseView
* pLeft
, CBaseView
* pRight
, CBaseView
* pBottom
)
114 if (m_groups
.size() && m_groups
.back() == m_caretpoints
.size())
117 std::list
<int>::size_type b
= m_groups
.back();
119 while (b
< m_caretpoints
.size())
120 UndoOne(pLeft
, pRight
, pBottom
);
123 UndoOne(pLeft
, pRight
, pBottom
);
125 CBaseView
* pActiveView
= NULL
;
127 if (pBottom
&& pBottom
->IsTarget())
129 pActiveView
= pBottom
;
132 if (pRight
&& pRight
->IsTarget())
134 pActiveView
= pRight
;
137 //if (pLeft && pLeft->IsTarget())
144 pActiveView
->ClearSelection();
145 pActiveView
->BuildAllScreen2ViewVector();
146 pActiveView
->RecalcAllVertScrollBars();
147 pActiveView
->RecalcAllHorzScrollBars();
148 pActiveView
->EnsureCaretVisible();
149 pActiveView
->UpdateCaret();
151 // TODO reduce code dumplication
152 if (m_viewstates
.size() < m_originalstateLeft
)
154 // Left can never get back to original state now
155 m_originalstateLeft
= (size_t)-1;
159 bool bModified
= (m_originalstateLeft
==(size_t)-1);
162 std::list
<allviewstate
>::iterator i
= m_viewstates
.begin();
163 std::advance(i
, m_originalstateLeft
);
164 for (; i
!=m_viewstates
.end(); ++i
)
166 if (i
->left
.modifies
)
173 pLeft
->SetModified(bModified
);
174 pLeft
->ClearStepModifiedMark();
176 if (m_viewstates
.size() < m_originalstateRight
)
178 // Right can never get back to original state now
179 m_originalstateRight
= (size_t)-1;
183 bool bModified
= (m_originalstateRight
==(size_t)-1);
186 std::list
<allviewstate
>::iterator i
= m_viewstates
.begin();
187 std::advance(i
, m_originalstateRight
);
188 for (; i
!=m_viewstates
.end() && !i
->right
.modifies
; ++i
) ;
189 bModified
= i
!=m_viewstates
.end();
191 pRight
->SetModified(bModified
);
192 pRight
->ClearStepModifiedMark();
194 if (m_viewstates
.size() < m_originalstateBottom
)
196 // Bottom can never get back to original state now
197 m_originalstateBottom
= (size_t)-1;
201 bool bModified
= (m_originalstateBottom
==(size_t)-1);
204 std::list
<allviewstate
>::iterator i
= m_viewstates
.begin();
205 std::advance(i
, m_originalstateBottom
);
206 for (; i
!=m_viewstates
.end(); ++i
)
208 if (i
->bottom
.modifies
)
215 pBottom
->SetModified(bModified
);
216 pBottom
->ClearStepModifiedMark();
218 pActiveView
->RefreshViews();
224 void CUndo::UndoOne(CBaseView
* pLeft
, CBaseView
* pRight
, CBaseView
* pBottom
)
226 allviewstate allstate
= m_viewstates
.back();
227 POINT pt
= m_caretpoints
.back();
229 Undo(allstate
.left
, pLeft
, pt
);
230 Undo(allstate
.right
, pRight
, pt
);
231 Undo(allstate
.bottom
, pBottom
, pt
);
233 m_viewstates
.pop_back();
234 m_caretpoints
.pop_back();
237 void CUndo::Undo(const viewstate
& state
, CBaseView
* pView
, const POINT
& pt
)
242 CViewData
* viewData
= pView
->m_pViewData
;
246 for (std::list
<int>::const_reverse_iterator it
= state
.addedlines
.rbegin(); it
!= state
.addedlines
.rend(); ++it
)
248 viewData
->RemoveData(*it
);
250 for (std::map
<int, DWORD
>::const_iterator it
= state
.linelines
.begin(); it
!= state
.linelines
.end(); ++it
)
252 viewData
->SetLineNumber(it
->first
, it
->second
);
254 for (std::map
<int, DWORD
>::const_iterator it
= state
.linestates
.begin(); it
!= state
.linestates
.end(); ++it
)
256 viewData
->SetState(it
->first
, (DiffStates
)it
->second
);
258 for (std::map
<int, EOL
>::const_iterator it
= state
.linesEOL
.begin(); it
!= state
.linesEOL
.end(); ++it
)
260 viewData
->SetLineEnding(it
->first
, (EOL
)it
->second
);
262 for (std::map
<int, bool>::const_iterator it
= state
.markedlines
.begin(); it
!= state
.markedlines
.end(); ++it
)
264 viewData
->SetMarked(it
->first
, (EOL
)it
->second
);
266 for (std::map
<int, CString
>::const_iterator it
= state
.difflines
.begin(); it
!= state
.difflines
.end(); ++it
)
268 viewData
->SetLine(it
->first
, it
->second
);
270 for (std::map
<int, viewdata
>::const_iterator it
= state
.removedlines
.begin(); it
!= state
.removedlines
.end(); ++it
)
272 viewData
->InsertData(it
->first
, it
->second
);
274 for (std::map
<int, viewdata
>::const_iterator it
= state
.replacedlines
.begin(); it
!= state
.replacedlines
.end(); ++it
)
276 viewData
->SetData(it
->first
, it
->second
);
279 if (pView
->IsTarget())
281 pView
->SetCaretViewPosition(pt
);
282 pView
->EnsureCaretVisible();
288 m_viewstates
.clear();
289 m_caretpoints
.clear();
291 m_originalstateLeft
= 0;
292 m_originalstateRight
= 0;
293 m_originalstateBottom
= 0;