1 // TortoiseMerge - a Diff/Patch program
3 // Copyright (C) 2006-2007 - 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::AddLineFormView(CBaseView
*pView
, int nLine
, bool bAddEmptyLine
)
27 if (!pView
|| !pView
->m_pViewData
)
29 difflines
[nLine
] = pView
->m_pViewData
->GetLine(nLine
);
30 linestates
[nLine
] = pView
->m_pViewData
->GetState(nLine
);
33 addedlines
.push_back(nLine
+ 1);
34 pView
->AddEmptyLine(nLine
);
38 CUndo
& CUndo::GetInstance()
40 static CUndo instance
;
53 void CUndo::AddState(const viewstate
& leftstate
, const viewstate
& rightstate
, const viewstate
& bottomstate
, POINT pt
)
55 m_viewstates
.push_back(bottomstate
);
56 m_viewstates
.push_back(rightstate
);
57 m_viewstates
.push_back(leftstate
);
58 m_caretpoints
.push_back(pt
);
61 bool CUndo::Undo(CBaseView
* pLeft
, CBaseView
* pRight
, CBaseView
* pBottom
)
66 if (m_groups
.size() && m_groups
.back() == m_caretpoints
.size())
69 std::list
<int>::size_type b
= m_groups
.back();
71 while (b
< m_caretpoints
.size())
72 UndoOne(pLeft
, pRight
, pBottom
);
75 UndoOne(pLeft
, pRight
, pBottom
);
77 CBaseView
* pActiveView
= pLeft
;
79 if (pRight
&& pRight
->HasCaret())
82 if (pBottom
&& pBottom
->HasCaret())
83 pActiveView
= pBottom
;
86 pActiveView
->ClearSelection();
87 pActiveView
->EnsureCaretVisible();
88 pActiveView
->UpdateCaret();
89 pActiveView
->SetModified(m_viewstates
.size() != m_originalstate
);
90 pActiveView
->RefreshViews();
93 if (m_viewstates
.size() < m_originalstate
)
94 // Can never get back to original state now
95 m_originalstate
= 1; // size() is always a multiple of 3
100 void CUndo::UndoOne(CBaseView
* pLeft
, CBaseView
* pRight
, CBaseView
* pBottom
)
102 viewstate state
= m_viewstates
.back();
104 m_viewstates
.pop_back();
105 state
= m_viewstates
.back();
107 m_viewstates
.pop_back();
108 state
= m_viewstates
.back();
109 Undo(state
, pBottom
);
110 m_viewstates
.pop_back();
111 if ((pLeft
)&&(pLeft
->HasCaret()))
113 pLeft
->SetCaretPosition(m_caretpoints
.back());
114 pLeft
->EnsureCaretVisible();
116 if ((pRight
)&&(pRight
->HasCaret()))
118 pRight
->SetCaretPosition(m_caretpoints
.back());
119 pRight
->EnsureCaretVisible();
121 if ((pBottom
)&&(pBottom
->HasCaret()))
123 pBottom
->SetCaretPosition(m_caretpoints
.back());
124 pBottom
->EnsureCaretVisible();
126 m_caretpoints
.pop_back();
129 void CUndo::Undo(const viewstate
& state
, CBaseView
* pView
)
134 for (std::list
<int>::const_iterator it
= state
.addedlines
.begin(); it
!= state
.addedlines
.end(); ++it
)
136 if (pView
->m_pViewData
)
137 pView
->m_pViewData
->RemoveData(*it
);
139 for (std::map
<int, DWORD
>::const_iterator it
= state
.linelines
.begin(); it
!= state
.linelines
.end(); ++it
)
141 if (pView
->m_pViewData
)
143 pView
->m_pViewData
->SetLineNumber(it
->first
, it
->second
);
146 for (std::map
<int, DWORD
>::const_iterator it
= state
.linestates
.begin(); it
!= state
.linestates
.end(); ++it
)
148 if (pView
->m_pViewData
)
150 pView
->m_pViewData
->SetState(it
->first
, (DiffStates
)it
->second
);
153 for (std::map
<int, CString
>::const_iterator it
= state
.difflines
.begin(); it
!= state
.difflines
.end(); ++it
)
155 if (pView
->m_pViewData
)
157 pView
->m_pViewData
->SetLine(it
->first
, it
->second
);
160 for (std::map
<int, viewdata
>::const_iterator it
= state
.removedlines
.begin(); it
!= state
.removedlines
.end(); ++it
)
162 if (pView
->m_pViewData
)
164 pView
->m_pViewData
->InsertData(it
->first
, it
->second
.sLine
, it
->second
.state
, it
->second
.linenumber
, it
->second
.ending
);
172 m_viewstates
.clear();
173 m_caretpoints
.clear();