Don't create the tooltips as topmost, and don't position them as topmost either but...
[TortoiseGit.git] / src / TortoiseMerge / Undo.cpp
blob088c70ff5b64b881ff27f0fea04e79c46a476783
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.
20 #include "stdafx.h"
21 #include "Undo.h"
23 #include "BaseView.h"
25 void viewstate::AddViewLineFromView(CBaseView *pView, int nViewLine, bool bAddEmptyLine)
27 // is undo good place for this ?
28 if (!pView || !pView->m_pViewData)
29 return;
30 replacedlines[nViewLine] = pView->m_pViewData->GetData(nViewLine);
31 if (bAddEmptyLine)
33 addedlines.push_back(nViewLine + 1);
34 pView->AddEmptyViewLine(nViewLine);
38 void viewstate::Clear()
40 difflines.clear();
41 linestates.clear();
42 linelines.clear();
43 linesEOL.clear();
44 markedlines.clear();
45 addedlines.clear();
47 removedlines.clear();
48 replacedlines.clear();
49 modifies = false;
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)
62 ++i;
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)
72 ++i;
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)
82 ++i;
83 --m_originalstateBottom;
88 CUndo& CUndo::GetInstance()
90 static CUndo instance;
91 return instance;
94 CUndo::CUndo()
96 Clear();
99 CUndo::~CUndo()
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)
111 if (!CanUndo())
112 return false;
114 if (m_groups.size() && m_groups.back() == m_caretpoints.size())
116 m_groups.pop_back();
117 std::list<int>::size_type b = m_groups.back();
118 m_groups.pop_back();
119 while (b < m_caretpoints.size())
120 UndoOne(pLeft, pRight, pBottom);
122 else
123 UndoOne(pLeft, pRight, pBottom);
125 CBaseView * pActiveView = NULL;
127 if (pBottom && pBottom->IsTarget())
129 pActiveView = pBottom;
131 else
132 if (pRight && pRight->IsTarget())
134 pActiveView = pRight;
136 else
137 //if (pLeft && pLeft->IsTarget())
139 pActiveView = pLeft;
143 if (pActiveView) {
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;
157 if (pLeft)
159 bool bModified = (m_originalstateLeft==(size_t)-1);
160 if (!bModified)
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)
168 bModified = true;
169 break;
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;
181 if (pRight)
183 bool bModified = (m_originalstateRight==(size_t)-1);
184 if (!bModified)
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;
199 if (pBottom)
201 bool bModified = (m_originalstateBottom==(size_t)-1);
202 if (!bModified)
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)
210 bModified = true;
211 break;
215 pBottom->SetModified(bModified);
216 pBottom->ClearStepModifiedMark();
218 pActiveView->RefreshViews();
221 return true;
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)
239 if (!pView)
240 return;
242 CViewData* viewData = pView->m_pViewData;
243 if (!viewData)
244 return;
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, it->second);
262 for (std::map<int, bool>::const_iterator it = state.markedlines.begin(); it != state.markedlines.end(); ++it)
264 viewData->SetMarked(it->first, 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();
286 void CUndo::Clear()
288 m_viewstates.clear();
289 m_caretpoints.clear();
290 m_groups.clear();
291 m_originalstateLeft = 0;
292 m_originalstateRight = 0;
293 m_originalstateBottom = 0;
294 m_groupCount = 0;