OSDN Git Service

merge original branch.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseMerge / Undo.cpp
1 // TortoiseMerge - a Diff/Patch program\r
2 \r
3 // Copyright (C) 2006-2007 - TortoiseSVN\r
4 \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
9 \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
14 \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
18 //\r
19 \r
20 #include "StdAfx.h"\r
21 #include "Undo.h"\r
22 \r
23 #include "BaseView.h"\r
24 \r
25 void viewstate::AddLineFormView(CBaseView *pView, int nLine, bool bAddEmptyLine)\r
26 {\r
27         if (!pView || !pView->m_pViewData)\r
28                 return;\r
29         difflines[nLine] = pView->m_pViewData->GetLine(nLine);\r
30         linestates[nLine] = pView->m_pViewData->GetState(nLine);\r
31         if (bAddEmptyLine)\r
32         {\r
33                 addedlines.push_back(nLine + 1);\r
34                 pView->AddEmptyLine(nLine);\r
35         }\r
36 }\r
37 \r
38 CUndo& CUndo::GetInstance()\r
39 {\r
40         static CUndo instance;\r
41         return instance;\r
42 }\r
43 \r
44 CUndo::CUndo()\r
45 {\r
46         m_originalstate = 0;\r
47 }\r
48 \r
49 CUndo::~CUndo()\r
50 {\r
51 }\r
52 \r
53 void CUndo::AddState(const viewstate& leftstate, const viewstate& rightstate, const viewstate& bottomstate, POINT pt)\r
54 {\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
59 }\r
60 \r
61 bool CUndo::Undo(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)\r
62 {\r
63         if (!CanUndo())\r
64                 return false;\r
65 \r
66         if (m_groups.size() && m_groups.back() == m_caretpoints.size())\r
67         {\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
73         }\r
74         else\r
75                 UndoOne(pLeft, pRight, pBottom);\r
76 \r
77         CBaseView * pActiveView = pLeft;\r
78 \r
79         if (pRight && pRight->HasCaret())\r
80                 pActiveView = pRight;\r
81 \r
82         if (pBottom && pBottom->HasCaret())\r
83                 pActiveView = pBottom;\r
84 \r
85         if (pActiveView) {\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
91         }\r
92 \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
96 \r
97         return true;\r
98 }\r
99 \r
100 void CUndo::UndoOne(CBaseView * pLeft, CBaseView * pRight, CBaseView * pBottom)\r
101 {\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
112         {\r
113                 pLeft->SetCaretPosition(m_caretpoints.back());\r
114                 pLeft->EnsureCaretVisible();\r
115         }\r
116         if ((pRight)&&(pRight->HasCaret()))\r
117         {\r
118                 pRight->SetCaretPosition(m_caretpoints.back());\r
119                 pRight->EnsureCaretVisible();\r
120         }\r
121         if ((pBottom)&&(pBottom->HasCaret()))\r
122         {\r
123                 pBottom->SetCaretPosition(m_caretpoints.back());\r
124                 pBottom->EnsureCaretVisible();\r
125         }\r
126         m_caretpoints.pop_back();\r
127 }\r
128 \r
129 void CUndo::Undo(const viewstate& state, CBaseView * pView)\r
130 {\r
131         if (!pView)\r
132                 return;\r
133 \r
134         for (std::list<int>::const_iterator it = state.addedlines.begin(); it != state.addedlines.end(); ++it)\r
135         {\r
136                 if (pView->m_pViewData)\r
137                         pView->m_pViewData->RemoveData(*it);\r
138         }\r
139         for (std::map<int, DWORD>::const_iterator it = state.linelines.begin(); it != state.linelines.end(); ++it)\r
140         {\r
141                 if (pView->m_pViewData)\r
142                 {\r
143                         pView->m_pViewData->SetLineNumber(it->first, it->second);\r
144                 }\r
145         }\r
146         for (std::map<int, DWORD>::const_iterator it = state.linestates.begin(); it != state.linestates.end(); ++it)\r
147         {\r
148                 if (pView->m_pViewData)\r
149                 {\r
150                         pView->m_pViewData->SetState(it->first, (DiffStates)it->second);\r
151                 }\r
152         }\r
153         for (std::map<int, CString>::const_iterator it = state.difflines.begin(); it != state.difflines.end(); ++it)\r
154         {\r
155                 if (pView->m_pViewData)\r
156                 {\r
157                         pView->m_pViewData->SetLine(it->first, it->second);\r
158                 }\r
159         }\r
160         for (std::map<int, viewdata>::const_iterator it = state.removedlines.begin(); it != state.removedlines.end(); ++it)\r
161         {\r
162                 if (pView->m_pViewData)\r
163                 {\r
164                         pView->m_pViewData->InsertData(it->first, it->second.sLine, it->second.state, it->second.linenumber, it->second.ending);\r
165                 }\r
166         }\r
167 }\r
168 \r
169 \r
170 void CUndo::Clear()\r
171 {\r
172         m_viewstates.clear();\r
173         m_caretpoints.clear();\r
174         m_groups.clear();\r
175         m_originalstate = 0;\r
176 }\r