Fixed issue #1507: Submodule Diff Dialog should show dirty state only on working...
[TortoiseGit.git] / src / TortoiseMerge / Undo.cpp
blobd1acc95f75e288dbf6aeadf18e183686f7dea6e0
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.
21 #include "StdAfx.h"
22 #include "Undo.h"
24 #include "BaseView.h"
26 void viewstate::AddLineFormView(CBaseView *pView, int nLine, bool bAddEmptyLine)
28 if (!pView || !pView->m_pViewData)
29 return;
30 difflines[nLine] = pView->m_pViewData->GetLine(nLine);
31 linestates[nLine] = pView->m_pViewData->GetState(nLine);
32 linesEOL[nLine] = pView->m_pViewData->GetLineEnding(nLine);
33 if (bAddEmptyLine)
35 addedlines.push_back(nLine + 1);
36 pView->AddEmptyLine(nLine);
40 CUndo& CUndo::GetInstance()
42 static CUndo instance;
43 return instance;
46 CUndo::CUndo()
48 m_originalstate = 0;
51 CUndo::~CUndo()
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)
65 if (!CanUndo())
66 return false;
68 if (!m_groups.empty() && m_groups.back() == m_caretpoints.size())
70 m_groups.pop_back();
71 std::list<int>::size_type b = m_groups.back();
72 m_groups.pop_back();
73 while (b < m_caretpoints.size())
74 UndoOne(pLeft, pRight, pBottom);
76 else
77 UndoOne(pLeft, pRight, pBottom);
79 CBaseView * pActiveView = pLeft;
81 if (pRight && pRight->HasCaret())
82 pActiveView = pRight;
84 if (pBottom && pBottom->HasCaret())
85 pActiveView = pBottom;
87 if (pActiveView) {
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
99 return true;
102 void CUndo::UndoOne(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)
104 viewstate state = m_viewstates.back();
105 Undo(state, pLeft);
106 m_viewstates.pop_back();
107 state = m_viewstates.back();
108 Undo(state, pRight);
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)
133 if (!pView)
134 return;
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);
179 void CUndo::Clear()
181 m_viewstates.clear();
182 m_caretpoints.clear();
183 m_groups.clear();
184 m_originalstate = 0;