Fixed issue #1507: Submodule Diff Dialog should show dirty state only on working...
[TortoiseGit.git] / src / TortoiseMerge / LeftView.cpp
blobfdb7955bab7d8755495b7cf2f51fdec840d74d87
1 // TortoiseMerge - a Diff/Patch program
3 // Copyright (C) 2006-2009,2011 - 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.
19 #include "StdAfx.h"
20 #include "Resource.h"
21 #include "AppUtils.h"
22 #include ".\leftview.h"
24 IMPLEMENT_DYNCREATE(CLeftView, CBaseView)
26 CLeftView::CLeftView(void)
28 m_pwndLeft = this;
29 m_nStatusBarID = ID_INDICATOR_LEFTVIEW;
32 CLeftView::~CLeftView(void)
36 bool CLeftView::OnContextMenu(CPoint point, int /*nLine*/, DiffStates state)
38 if (!m_pwndRight->IsWindowVisible())
39 return false;
41 CMenu popup;
42 if (popup.CreatePopupMenu())
44 #define ID_USEBLOCK 1
45 #define ID_USEFILE 2
46 #define ID_USETHEIRANDYOURBLOCK 3
47 #define ID_USEYOURANDTHEIRBLOCK 4
48 #define ID_USEBOTHTHISFIRST 5
49 #define ID_USEBOTHTHISLAST 6
51 UINT uFlags = MF_ENABLED;
52 if ((m_nSelBlockStart == -1)||(m_nSelBlockEnd == -1))
53 uFlags |= MF_DISABLED | MF_GRAYED;
54 CString temp;
56 bool bImportantBlock = true;
57 switch (state)
59 case DIFFSTATE_UNKNOWN:
60 bImportantBlock = false;
61 break;
63 temp.LoadString(IDS_VIEWCONTEXTMENU_USETHISBLOCK);
64 popup.AppendMenu(MF_STRING | uFlags | (bImportantBlock ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_USEBLOCK, temp);
66 temp.LoadString(IDS_VIEWCONTEXTMENU_USETHISFILE);
67 popup.AppendMenu(MF_STRING | MF_ENABLED, ID_USEFILE, temp);
69 if (m_pwndBottom->IsWindowVisible())
71 temp.LoadString(IDS_VIEWCONTEXTMENU_USEYOURANDTHEIRBLOCK);
72 popup.AppendMenu(MF_STRING | uFlags | (bImportantBlock ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_USEYOURANDTHEIRBLOCK, temp);
73 temp.LoadString(IDS_VIEWCONTEXTMENU_USETHEIRANDYOURBLOCK);
74 popup.AppendMenu(MF_STRING | uFlags | (bImportantBlock ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_USETHEIRANDYOURBLOCK, temp);
76 else
78 temp.LoadString(IDS_VIEWCONTEXTMENU_USEBOTHTHISFIRST);
79 popup.AppendMenu(MF_STRING | uFlags | (bImportantBlock ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_USEBOTHTHISFIRST, temp);
80 temp.LoadString(IDS_VIEWCONTEXTMENU_USEBOTHTHISLAST);
81 popup.AppendMenu(MF_STRING | uFlags | (bImportantBlock ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_USEBOTHTHISLAST, temp);
84 popup.AppendMenu(MF_SEPARATOR, NULL);
86 temp.LoadString(IDS_EDIT_COPY);
87 popup.AppendMenu(MF_STRING | (HasTextSelection() ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_EDIT_COPY, temp);
88 if (!m_bCaretHidden)
90 temp.LoadString(IDS_EDIT_CUT);
91 popup.AppendMenu(MF_STRING | (HasTextSelection() ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_EDIT_CUT, temp);
92 temp.LoadString(IDS_EDIT_PASTE);
93 popup.AppendMenu(MF_STRING | (CAppUtils::HasClipboardFormat(CF_UNICODETEXT)||CAppUtils::HasClipboardFormat(CF_TEXT) ? MF_ENABLED : MF_DISABLED|MF_GRAYED), ID_EDIT_PASTE, temp);
96 // if the context menu is invoked through the keyboard, we have to use
97 // a calculated position on where to anchor the menu on
98 if ((point.x == -1) && (point.y == -1))
100 CRect rect;
101 GetWindowRect(&rect);
102 point = rect.CenterPoint();
104 int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);
105 viewstate leftstate;
106 viewstate bottomstate;
107 viewstate rightstate;
108 switch (cmd)
110 case ID_EDIT_COPY:
111 OnEditCopy();
112 return true;
113 case ID_EDIT_CUT:
114 OnEditCopy();
115 RemoveSelectedText();
116 return false;
117 case ID_EDIT_PASTE:
118 PasteText();
119 return false;
120 case ID_USEFILE:
122 if (m_pwndBottom->IsWindowVisible())
124 for (int i=0; i<GetLineCount(); i++)
126 bottomstate.difflines[i] = m_pwndBottom->m_pViewData->GetLine(i);
127 m_pwndBottom->m_pViewData->SetLine(i, m_pViewData->GetLine(i));
128 bottomstate.linestates[i] = m_pwndBottom->m_pViewData->GetState(i);
129 m_pwndBottom->m_pViewData->SetState(i, m_pViewData->GetState(i));
130 m_pwndBottom->m_pViewData->SetLineEnding(i, m_pViewData->GetLineEnding(i));
131 if (m_pwndBottom->IsLineConflicted(i))
133 if (m_pViewData->GetState(i) == DIFFSTATE_CONFLICTEMPTY)
134 m_pwndBottom->m_pViewData->SetState(i, DIFFSTATE_CONFLICTRESOLVEDEMPTY);
135 else
136 m_pwndBottom->m_pViewData->SetState(i, DIFFSTATE_CONFLICTRESOLVED);
139 m_pwndBottom->SetModified();
141 else
143 for (int i=0; i<GetLineCount(); i++)
145 rightstate.difflines[i] = m_pwndRight->m_pViewData->GetLine(i);
146 m_pwndRight->m_pViewData->SetLine(i, m_pViewData->GetLine(i));
147 m_pwndRight->m_pViewData->SetLineEnding(i, m_pViewData->GetLineEnding(i));
148 DiffStates state2 = m_pViewData->GetState(i);
149 switch (state2)
151 case DIFFSTATE_CONFLICTEMPTY:
152 case DIFFSTATE_UNKNOWN:
153 case DIFFSTATE_EMPTY:
154 rightstate.linestates[i] = m_pwndRight->m_pViewData->GetState(i);
155 m_pwndRight->m_pViewData->SetState(i, state2);
156 break;
157 case DIFFSTATE_YOURSADDED:
158 case DIFFSTATE_IDENTICALADDED:
159 case DIFFSTATE_NORMAL:
160 case DIFFSTATE_THEIRSADDED:
161 case DIFFSTATE_ADDED:
162 case DIFFSTATE_CONFLICTADDED:
163 case DIFFSTATE_CONFLICTED:
164 case DIFFSTATE_CONFLICTED_IGNORED:
165 case DIFFSTATE_IDENTICALREMOVED:
166 case DIFFSTATE_REMOVED:
167 case DIFFSTATE_THEIRSREMOVED:
168 case DIFFSTATE_YOURSREMOVED:
169 rightstate.linestates[i] = m_pwndRight->m_pViewData->GetState(i);
170 m_pwndRight->m_pViewData->SetState(i, DIFFSTATE_NORMAL);
171 leftstate.linestates[i] = m_pViewData->GetState(i);
172 m_pViewData->SetState(i, DIFFSTATE_NORMAL);
173 break;
174 default:
175 break;
178 m_pwndRight->SetModified();
179 if (m_pwndLocator)
180 m_pwndLocator->DocumentUpdated();
183 break;
184 case ID_USEBLOCK:
186 if ((m_nSelBlockStart == -1)||(m_nSelBlockEnd == -1))
187 break;
188 if (m_pwndBottom->IsWindowVisible())
190 for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
192 bottomstate.difflines[i] = m_pwndBottom->m_pViewData->GetLine(i);
193 m_pwndBottom->m_pViewData->SetLine(i, m_pViewData->GetLine(i));
194 bottomstate.linestates[i] = m_pwndBottom->m_pViewData->GetState(i);
195 m_pwndBottom->m_pViewData->SetState(i, m_pViewData->GetState(i));
196 m_pwndBottom->m_pViewData->SetLineEnding(i, lineendings);
197 if (m_pwndBottom->IsLineConflicted(i))
199 if (m_pViewData->GetState(i) == DIFFSTATE_CONFLICTEMPTY)
200 m_pwndBottom->m_pViewData->SetState(i, DIFFSTATE_CONFLICTRESOLVEDEMPTY);
201 else
202 m_pwndBottom->m_pViewData->SetState(i, DIFFSTATE_CONFLICTRESOLVED);
205 m_pwndBottom->SetModified();
207 else
209 for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
211 rightstate.difflines[i] = m_pwndRight->m_pViewData->GetLine(i);
212 m_pwndRight->m_pViewData->SetLine(i, m_pViewData->GetLine(i));
213 m_pwndRight->m_pViewData->SetLineEnding(i, lineendings);
214 DiffStates state2 = m_pViewData->GetState(i);
215 switch (state2)
217 case DIFFSTATE_ADDED:
218 case DIFFSTATE_CONFLICTADDED:
219 case DIFFSTATE_CONFLICTED:
220 case DIFFSTATE_CONFLICTED_IGNORED:
221 case DIFFSTATE_CONFLICTEMPTY:
222 case DIFFSTATE_IDENTICALADDED:
223 case DIFFSTATE_NORMAL:
224 case DIFFSTATE_THEIRSADDED:
225 case DIFFSTATE_UNKNOWN:
226 case DIFFSTATE_YOURSADDED:
227 case DIFFSTATE_EMPTY:
228 rightstate.linestates[i] = m_pwndRight->m_pViewData->GetState(i);
229 m_pwndRight->m_pViewData->SetState(i, state2);
230 break;
231 case DIFFSTATE_IDENTICALREMOVED:
232 case DIFFSTATE_REMOVED:
233 case DIFFSTATE_THEIRSREMOVED:
234 case DIFFSTATE_YOURSREMOVED:
235 rightstate.linestates[i] = m_pwndRight->m_pViewData->GetState(i);
236 m_pwndRight->m_pViewData->SetState(i, DIFFSTATE_ADDED);
237 break;
238 default:
239 break;
242 m_pwndRight->SetModified();
245 break;
246 case ID_USEYOURANDTHEIRBLOCK:
248 UseYourAndTheirBlock(rightstate, bottomstate, leftstate);
250 break;
251 case ID_USETHEIRANDYOURBLOCK:
253 UseTheirAndYourBlock(rightstate, bottomstate, leftstate);
255 break;
256 case ID_USEBOTHTHISLAST:
258 UseBothRightFirst(rightstate, leftstate);
260 break;
261 case ID_USEBOTHTHISFIRST:
263 UseBothLeftFirst(rightstate, leftstate);
265 break;
266 default:
267 return false;
268 } // switch (cmd)
269 CUndo::GetInstance().AddState(leftstate, rightstate, bottomstate, m_ptCaretPos);
270 } // if (popup.CreatePopupMenu())
271 return false;