1 // TortoiseMerge - a Diff/Patch program
\r
3 // Copyright (C) 2006-2007 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
23 #include "BaseView.h"
\r
25 void viewstate::AddLineFormView(CBaseView *pView, int nLine, bool bAddEmptyLine)
\r
27 if (!pView || !pView->m_pViewData)
\r
29 difflines[nLine] = pView->m_pViewData->GetLine(nLine);
\r
30 linestates[nLine] = pView->m_pViewData->GetState(nLine);
\r
33 addedlines.push_back(nLine + 1);
\r
34 pView->AddEmptyLine(nLine);
\r
38 CUndo& CUndo::GetInstance()
\r
40 static CUndo instance;
\r
46 m_originalstate = 0;
\r
53 void CUndo::AddState(const viewstate& leftstate, const viewstate& rightstate, const viewstate& bottomstate, POINT pt)
\r
55 m_viewstates.push_back(bottomstate);
\r
56 m_viewstates.push_back(rightstate);
\r
57 m_viewstates.push_back(leftstate);
\r
58 m_caretpoints.push_back(pt);
\r
61 bool CUndo::Undo(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)
\r
66 if (m_groups.size() && m_groups.back() == m_caretpoints.size())
\r
68 m_groups.pop_back();
\r
69 std::list<int>::size_type b = m_groups.back();
\r
70 m_groups.pop_back();
\r
71 while (b < m_caretpoints.size())
\r
72 UndoOne(pLeft, pRight, pBottom);
\r
75 UndoOne(pLeft, pRight, pBottom);
\r
77 CBaseView * pActiveView = pLeft;
\r
79 if (pRight && pRight->HasCaret())
\r
80 pActiveView = pRight;
\r
82 if (pBottom && pBottom->HasCaret())
\r
83 pActiveView = pBottom;
\r
86 pActiveView->ClearSelection();
\r
87 pActiveView->EnsureCaretVisible();
\r
88 pActiveView->UpdateCaret();
\r
89 pActiveView->SetModified(m_viewstates.size() != m_originalstate);
\r
90 pActiveView->RefreshViews();
\r
93 if (m_viewstates.size() < m_originalstate)
\r
94 // Can never get back to original state now
\r
95 m_originalstate = 1; // size() is always a multiple of 3
\r
100 void CUndo::UndoOne(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)
\r
102 viewstate state = m_viewstates.back();
\r
103 Undo(state, pLeft);
\r
104 m_viewstates.pop_back();
\r
105 state = m_viewstates.back();
\r
106 Undo(state, pRight);
\r
107 m_viewstates.pop_back();
\r
108 state = m_viewstates.back();
\r
109 Undo(state, pBottom);
\r
110 m_viewstates.pop_back();
\r
111 if ((pLeft)&&(pLeft->HasCaret()))
\r
113 pLeft->SetCaretPosition(m_caretpoints.back());
\r
114 pLeft->EnsureCaretVisible();
\r
116 if ((pRight)&&(pRight->HasCaret()))
\r
118 pRight->SetCaretPosition(m_caretpoints.back());
\r
119 pRight->EnsureCaretVisible();
\r
121 if ((pBottom)&&(pBottom->HasCaret()))
\r
123 pBottom->SetCaretPosition(m_caretpoints.back());
\r
124 pBottom->EnsureCaretVisible();
\r
126 m_caretpoints.pop_back();
\r
129 void CUndo::Undo(const viewstate& state, CBaseView * pView)
\r
134 for (std::list<int>::const_iterator it = state.addedlines.begin(); it != state.addedlines.end(); ++it)
\r
136 if (pView->m_pViewData)
\r
137 pView->m_pViewData->RemoveData(*it);
\r
139 for (std::map<int, DWORD>::const_iterator it = state.linelines.begin(); it != state.linelines.end(); ++it)
\r
141 if (pView->m_pViewData)
\r
143 pView->m_pViewData->SetLineNumber(it->first, it->second);
\r
146 for (std::map<int, DWORD>::const_iterator it = state.linestates.begin(); it != state.linestates.end(); ++it)
\r
148 if (pView->m_pViewData)
\r
150 pView->m_pViewData->SetState(it->first, (DiffStates)it->second);
\r
153 for (std::map<int, CString>::const_iterator it = state.difflines.begin(); it != state.difflines.end(); ++it)
\r
155 if (pView->m_pViewData)
\r
157 pView->m_pViewData->SetLine(it->first, it->second);
\r
160 for (std::map<int, viewdata>::const_iterator it = state.removedlines.begin(); it != state.removedlines.end(); ++it)
\r
162 if (pView->m_pViewData)
\r
164 pView->m_pViewData->InsertData(it->first, it->second.sLine, it->second.state, it->second.linenumber, it->second.ending);
\r
170 void CUndo::Clear()
\r
172 m_viewstates.clear();
\r
173 m_caretpoints.clear();
\r
175 m_originalstate = 0;
\r