1 // TortoiseMerge - a Diff/Patch program
3 // Copyright (C) 2006-2007 - TortoiseSVN
4 // Copyright (C) 2011 Sven Strickroth <email@cs-ware.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 void viewstate::AddLineFormView(CBaseView
*pView
, int nLine
, bool bAddEmptyLine
)
28 if (!pView
|| !pView
->m_pViewData
)
30 difflines
[nLine
] = pView
->m_pViewData
->GetLine(nLine
);
31 linestates
[nLine
] = pView
->m_pViewData
->GetState(nLine
);
32 linesEOL
[nLine
] = pView
->m_pViewData
->GetLineEnding(nLine
);
35 addedlines
.push_back(nLine
+ 1);
36 pView
->AddEmptyLine(nLine
);
40 CUndo
& CUndo::GetInstance()
42 static CUndo instance
;
55 void CUndo::AddState(const viewstate
& leftstate
, const viewstate
& rightstate
, const viewstate
& bottomstate
, POINT pt
)
57 m_viewstates
.push_back(bottomstate
);
58 m_viewstates
.push_back(rightstate
);
59 m_viewstates
.push_back(leftstate
);
60 m_caretpoints
.push_back(pt
);
63 bool CUndo::Undo(CBaseView
* pLeft
, CBaseView
* pRight
, CBaseView
* pBottom
)
68 if (!m_groups
.empty() && m_groups
.back() == m_caretpoints
.size())
71 std::list
<int>::size_type b
= m_groups
.back();
73 while (b
< m_caretpoints
.size())
74 UndoOne(pLeft
, pRight
, pBottom
);
77 UndoOne(pLeft
, pRight
, pBottom
);
79 CBaseView
* pActiveView
= pLeft
;
81 if (pRight
&& pRight
->HasCaret())
84 if (pBottom
&& pBottom
->HasCaret())
85 pActiveView
= pBottom
;
88 pActiveView
->ClearSelection();
89 pActiveView
->EnsureCaretVisible();
90 pActiveView
->UpdateCaret();
91 pActiveView
->SetModified(m_viewstates
.size() != m_originalstate
);
92 pActiveView
->RefreshViews();
95 if (m_viewstates
.size() < m_originalstate
)
96 // Can never get back to original state now
97 m_originalstate
= 1; // size() is always a multiple of 3
102 void CUndo::UndoOne(CBaseView
* pLeft
, CBaseView
* pRight
, CBaseView
* pBottom
)
104 viewstate state
= m_viewstates
.back();
106 m_viewstates
.pop_back();
107 state
= m_viewstates
.back();
109 m_viewstates
.pop_back();
110 state
= m_viewstates
.back();
111 Undo(state
, pBottom
);
112 m_viewstates
.pop_back();
113 if ((pLeft
)&&(pLeft
->HasCaret()))
115 pLeft
->SetCaretPosition(m_caretpoints
.back());
116 pLeft
->EnsureCaretVisible();
118 if ((pRight
)&&(pRight
->HasCaret()))
120 pRight
->SetCaretPosition(m_caretpoints
.back());
121 pRight
->EnsureCaretVisible();
123 if ((pBottom
)&&(pBottom
->HasCaret()))
125 pBottom
->SetCaretPosition(m_caretpoints
.back());
126 pBottom
->EnsureCaretVisible();
128 m_caretpoints
.pop_back();
131 void CUndo::Undo(const viewstate
& state
, CBaseView
* pView
)
136 for (std::list
<int>::const_iterator it
= state
.addedlines
.begin(); it
!= state
.addedlines
.end(); ++it
)
138 if (pView
->m_pViewData
)
139 pView
->m_pViewData
->RemoveData(*it
);
141 for (std::map
<int, DWORD
>::const_iterator it
= state
.linelines
.begin(); it
!= state
.linelines
.end(); ++it
)
143 if (pView
->m_pViewData
)
145 pView
->m_pViewData
->SetLineNumber(it
->first
, it
->second
);
148 for (std::map
<int, DWORD
>::const_iterator it
= state
.linestates
.begin(); it
!= state
.linestates
.end(); ++it
)
150 if (pView
->m_pViewData
)
152 pView
->m_pViewData
->SetState(it
->first
, (DiffStates
)it
->second
);
155 for (std::map
<int, EOL
>::const_iterator it
= state
.linesEOL
.begin(); it
!= state
.linesEOL
.end(); ++it
)
157 if (pView
->m_pViewData
)
159 pView
->m_pViewData
->SetLineEnding(it
->first
, (EOL
)it
->second
);
162 for (std::map
<int, CString
>::const_iterator it
= state
.difflines
.begin(); it
!= state
.difflines
.end(); ++it
)
164 if (pView
->m_pViewData
)
166 pView
->m_pViewData
->SetLine(it
->first
, it
->second
);
169 for (std::map
<int, viewdata
>::const_iterator it
= state
.removedlines
.begin(); it
!= state
.removedlines
.end(); ++it
)
171 if (pView
->m_pViewData
)
173 pView
->m_pViewData
->InsertData(it
->first
, it
->second
.sLine
, it
->second
.state
, it
->second
.linenumber
, it
->second
.ending
);
181 m_viewstates
.clear();
182 m_caretpoints
.clear();