1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2008-2012 - TortoiseGit
4 // Copyright (C) 2004-2012 - TortoiseSVN
5 // Copyright (C) 2012 - Sven Strickroth <email@cs-ware.de>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software Foundation,
19 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "TortoiseMerge.h"
24 #include "SysProgressDlg.h"
26 #include "MessageBox.h"
28 #include "PathUtils.h"
31 #include "RightView.h"
32 #include "BottomView.h"
33 #include "DiffColors.h"
35 #include "SelectFileFilter.h"
36 #include "FormatMessageWrapper.h"
37 #include "TaskbarUUID.h"
44 const UINT TaskBarButtonCreated
= RegisterWindowMessage(L
"TaskbarButtonCreated");
46 IMPLEMENT_DYNCREATE(CMainFrame
, CFrameWndEx
)
48 BEGIN_MESSAGE_MAP(CMainFrame
, CFrameWndEx
)
50 ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN7
, ID_VIEW_APPLOOK_OFF_2007_AQUA
, &CMainFrame::OnApplicationLook
)
51 ON_UPDATE_COMMAND_UI_RANGE(IDC_STYLEBUTTON
, ID_VIEW_APPLOOK_OFF_2007_AQUA
, &CMainFrame::OnUpdateApplicationLook
)
52 // Global help commands
53 ON_COMMAND(ID_HELP_FINDER
, CFrameWndEx::OnHelpFinder
)
54 ON_COMMAND(ID_HELP
, CFrameWndEx::OnHelp
)
55 ON_COMMAND(ID_CONTEXT_HELP
, CFrameWndEx::OnContextHelp
)
56 ON_COMMAND(ID_DEFAULT_HELP
, CFrameWndEx::OnHelpFinder
)
57 ON_COMMAND(ID_FILE_OPEN
, OnFileOpen
)
58 ON_COMMAND(ID_VIEW_WHITESPACES
, OnViewWhitespaces
)
60 ON_COMMAND(ID_FILE_SAVE
, OnFileSave
)
61 ON_COMMAND(ID_FILE_SAVE_AS
, OnFileSaveAs
)
62 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE
, OnUpdateFileSave
)
63 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS
, OnUpdateFileSaveAs
)
64 ON_COMMAND(ID_VIEW_ONEWAYDIFF
, OnViewOnewaydiff
)
65 ON_UPDATE_COMMAND_UI(ID_VIEW_ONEWAYDIFF
, OnUpdateViewOnewaydiff
)
66 ON_UPDATE_COMMAND_UI(ID_VIEW_WHITESPACES
, OnUpdateViewWhitespaces
)
67 ON_COMMAND(ID_VIEW_OPTIONS
, OnViewOptions
)
70 ON_COMMAND(ID_FILE_RELOAD
, OnFileReload
)
71 ON_COMMAND(ID_VIEW_LINEDOWN
, OnViewLinedown
)
72 ON_COMMAND(ID_VIEW_LINEUP
, OnViewLineup
)
73 ON_COMMAND(ID_VIEW_MOVEDBLOCKS
, OnViewMovedBlocks
)
74 ON_UPDATE_COMMAND_UI(ID_VIEW_MOVEDBLOCKS
, OnUpdateViewMovedBlocks
)
75 ON_UPDATE_COMMAND_UI(ID_EDIT_MARKASRESOLVED
, OnUpdateMergeMarkasresolved
)
76 ON_COMMAND(ID_EDIT_MARKASRESOLVED
, OnMergeMarkasresolved
)
77 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTCONFLICT
, OnUpdateMergeNextconflict
)
78 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSCONFLICT
, OnUpdateMergePreviousconflict
)
81 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY
, OnUpdateEditCopy
)
82 ON_COMMAND(ID_VIEW_SWITCHLEFT
, OnViewSwitchleft
)
83 ON_UPDATE_COMMAND_UI(ID_VIEW_SWITCHLEFT
, OnUpdateViewSwitchleft
)
84 ON_COMMAND(ID_VIEW_LINELEFT
, &CMainFrame::OnViewLineleft
)
85 ON_COMMAND(ID_VIEW_LINERIGHT
, &CMainFrame::OnViewLineright
)
86 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILELIST
, &CMainFrame::OnUpdateViewShowfilelist
)
87 ON_COMMAND(ID_VIEW_SHOWFILELIST
, &CMainFrame::OnViewShowfilelist
)
88 ON_COMMAND(ID_EDIT_USETHEIRBLOCK
, &CMainFrame::OnEditUseTheirs
)
89 ON_COMMAND(ID_EDIT_USEMYBLOCK
, &CMainFrame::OnEditUseMine
)
90 ON_COMMAND(ID_EDIT_USETHEIRTHENMYBLOCK
, &CMainFrame::OnEditUseTheirsThenMine
)
91 ON_COMMAND(ID_EDIT_USEMINETHENTHEIRBLOCK
, &CMainFrame::OnEditUseMineThenTheirs
)
92 ON_COMMAND(ID_EDIT_UNDO
, &CMainFrame::OnEditUndo
)
93 ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO
, &CMainFrame::OnUpdateEditUndo
)
94 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMINETHENTHEIRBLOCK
, &CMainFrame::OnUpdateEditUseminethentheirblock
)
95 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMYBLOCK
, &CMainFrame::OnUpdateEditUsemyblock
)
96 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRBLOCK
, &CMainFrame::OnUpdateEditUsetheirblock
)
97 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRTHENMYBLOCK
, &CMainFrame::OnUpdateEditUsetheirthenmyblock
)
98 ON_COMMAND(ID_VIEW_INLINEDIFFWORD
, &CMainFrame::OnViewInlinediffword
)
99 ON_UPDATE_COMMAND_UI(ID_VIEW_INLINEDIFFWORD
, &CMainFrame::OnUpdateViewInlinediffword
)
100 ON_COMMAND(ID_VIEW_INLINEDIFF
, &CMainFrame::OnViewInlinediff
)
101 ON_UPDATE_COMMAND_UI(ID_VIEW_INLINEDIFF
, &CMainFrame::OnUpdateViewInlinediff
)
102 ON_UPDATE_COMMAND_UI(ID_EDIT_CREATEUNIFIEDDIFFFILE
, &CMainFrame::OnUpdateEditCreateunifieddifffile
)
103 ON_COMMAND(ID_EDIT_CREATEUNIFIEDDIFFFILE
, &CMainFrame::OnEditCreateunifieddifffile
)
104 ON_UPDATE_COMMAND_UI(ID_VIEW_LINEDIFFBAR
, &CMainFrame::OnUpdateViewLinediffbar
)
105 ON_COMMAND(ID_VIEW_LINEDIFFBAR
, &CMainFrame::OnViewLinediffbar
)
106 ON_UPDATE_COMMAND_UI(ID_VIEW_LOCATORBAR
, &CMainFrame::OnUpdateViewLocatorbar
)
107 ON_COMMAND(ID_VIEW_LOCATORBAR
, &CMainFrame::OnViewLocatorbar
)
108 ON_COMMAND(ID_EDIT_USELEFTBLOCK
, &CMainFrame::OnEditUseleftblock
)
109 ON_UPDATE_COMMAND_UI(ID_USEBLOCKS
, &CMainFrame::OnUpdateUseBlock
)
110 ON_UPDATE_COMMAND_UI(ID_EDIT_USELEFTBLOCK
, &CMainFrame::OnUpdateEditUseleftblock
)
111 ON_COMMAND(ID_EDIT_USELEFTFILE
, &CMainFrame::OnEditUseleftfile
)
112 ON_UPDATE_COMMAND_UI(ID_EDIT_USELEFTFILE
, &CMainFrame::OnUpdateEditUseleftfile
)
113 ON_COMMAND(ID_EDIT_USEBLOCKFROMLEFTBEFORERIGHT
, &CMainFrame::OnEditUseblockfromleftbeforeright
)
114 ON_UPDATE_COMMAND_UI(ID_EDIT_USEBLOCKFROMLEFTBEFORERIGHT
, &CMainFrame::OnUpdateEditUseblockfromleftbeforeright
)
115 ON_COMMAND(ID_EDIT_USEBLOCKFROMRIGHTBEFORELEFT
, &CMainFrame::OnEditUseblockfromrightbeforeleft
)
116 ON_UPDATE_COMMAND_UI(ID_EDIT_USEBLOCKFROMRIGHTBEFORELEFT
, &CMainFrame::OnUpdateEditUseblockfromrightbeforeleft
)
117 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTDIFFERENCE
, &CMainFrame::OnUpdateNavigateNextdifference
)
118 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSDIFFERENCE
, &CMainFrame::OnUpdateNavigatePreviousdifference
)
119 ON_COMMAND(ID_VIEW_COLLAPSED
, &CMainFrame::OnViewCollapsed
)
120 ON_UPDATE_COMMAND_UI(ID_VIEW_COLLAPSED
, &CMainFrame::OnUpdateViewCollapsed
)
121 ON_COMMAND(ID_VIEW_COMPAREWHITESPACES
, &CMainFrame::OnViewComparewhitespaces
)
122 ON_UPDATE_COMMAND_UI(ID_VIEW_COMPAREWHITESPACES
, &CMainFrame::OnUpdateViewComparewhitespaces
)
123 ON_COMMAND(ID_VIEW_IGNOREWHITESPACECHANGES
, &CMainFrame::OnViewIgnorewhitespacechanges
)
124 ON_UPDATE_COMMAND_UI(ID_VIEW_IGNOREWHITESPACECHANGES
, &CMainFrame::OnUpdateViewIgnorewhitespacechanges
)
125 ON_COMMAND(ID_VIEW_IGNOREALLWHITESPACECHANGES
, &CMainFrame::OnViewIgnoreallwhitespacechanges
)
126 ON_UPDATE_COMMAND_UI(ID_VIEW_IGNOREALLWHITESPACECHANGES
, &CMainFrame::OnUpdateViewIgnoreallwhitespacechanges
)
127 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTINLINEDIFF
, &CMainFrame::OnUpdateNavigateNextinlinediff
)
128 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVINLINEDIFF
, &CMainFrame::OnUpdateNavigatePrevinlinediff
)
129 ON_COMMAND(ID_VIEW_WRAPLONGLINES
, &CMainFrame::OnViewWraplonglines
)
130 ON_UPDATE_COMMAND_UI(ID_VIEW_WRAPLONGLINES
, &CMainFrame::OnUpdateViewWraplonglines
)
131 ON_REGISTERED_MESSAGE( TaskBarButtonCreated
, CMainFrame::OnTaskbarButtonCreated
)
132 ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE
, &CMainFrame::OnUpdateEditPaste
)
135 static UINT indicators
[] =
137 ID_SEPARATOR
, // status line indicator
138 ID_INDICATOR_LEFTVIEW
,
139 ID_INDICATOR_RIGHTVIEW
,
140 ID_INDICATOR_BOTTOMVIEW
,
146 // CMainFrame construction/destruction
148 CMainFrame::CMainFrame()
149 : m_bInitSplitter(FALSE
)
150 , m_bReversedPatch(FALSE
)
151 , m_bHasConflicts(false)
152 , m_bInlineWordDiff(true)
154 , m_bLocatorBar(true)
155 , m_nMoveMovesToIgnore(0)
156 , m_pwndLeftView(NULL
)
157 , m_pwndRightView(NULL
)
158 , m_pwndBottomView(NULL
)
161 , m_bCheckReload(false)
162 , m_bSaveRequired(false)
164 , resolveMsgWParam(0)
165 , resolveMsgLParam(0)
166 , m_regWrapLines(L
"Software\\TortoiseGitMerge\\WrapLines", 0)
167 , m_regViewModedBlocks(L
"Software\\TortoiseGitMerge\\ViewMovedBlocks", 0)
168 , m_regOneWay(L
"Software\\TortoiseGitMerge\\OnePane")
169 , m_regCollapsed(L
"Software\\TortoiseGitMerge\\Collapsed", 0)
170 , m_regInlineDiff(L
"Software\\TortoiseGitMerge\\DisplayBinDiff", TRUE
)
172 m_bOneWay
= (0 != ((DWORD
)m_regOneWay
));
173 theApp
.m_nAppLook
= theApp
.GetInt(_T("ApplicationLook"), ID_VIEW_APPLOOK_VS_2005
);
174 m_bCollapsed
= !!(DWORD
)m_regCollapsed
;
175 m_bViewMovedBlocks
= !!(DWORD
)m_regViewModedBlocks
;
176 m_bWrapLines
= !!(DWORD
)m_regWrapLines
;
177 m_bInlineDiff
= !!m_regInlineDiff
;
178 CMFCVisualManagerWindows::m_b3DTabsXPTheme
= TRUE
;
181 CMainFrame::~CMainFrame()
185 LRESULT
CMainFrame::OnTaskbarButtonCreated(WPARAM
/*wParam*/, LPARAM
/*lParam*/)
187 SetUUIDOverlayIcon(m_hWnd
);
192 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct
)
194 if (CFrameWndEx::OnCreate(lpCreateStruct
) == -1)
197 OnApplicationLook(theApp
.m_nAppLook
);
199 m_wndRibbonBar
.Create (this);
200 m_wndRibbonBar
.LoadFromResource(IDR_RIBBON
);
202 // enable the dialog launch button on the view panel
203 CMFCRibbonCategory
* pMainCat
= m_wndRibbonBar
.GetCategory(1);
206 CMFCRibbonPanel
* pPanel
= pMainCat
->GetPanel(3);
208 pPanel
->EnableLaunchButton(ID_VIEW_OPTIONS
);
211 if (!m_wndStatusBar
.Create(this) ||
212 !m_wndStatusBar
.SetIndicators(indicators
,
213 _countof(indicators
)))
215 TRACE0("Failed to create status bar\n");
216 return -1; // fail to create
219 if (!m_wndLocatorBar
.Create(this, IDD_DIFFLOCATOR
,
220 CBRS_ALIGN_LEFT
| CBRS_SIZE_FIXED
, ID_VIEW_LOCATORBAR
))
222 TRACE0("Failed to create dialogbar\n");
223 return -1; // fail to create
225 if (!m_wndLineDiffBar
.Create(this, IDD_LINEDIFF
,
226 CBRS_ALIGN_BOTTOM
| CBRS_SIZE_FIXED
, ID_VIEW_LINEDIFFBAR
))
228 TRACE0("Failed to create dialogbar\n");
229 return -1; // fail to create
231 m_wndLocatorBar
.m_pMainFrm
= this;
232 m_wndLineDiffBar
.m_pMainFrm
= this;
234 EnableDocking(CBRS_ALIGN_ANY
);
235 DockPane(&m_wndLocatorBar
);
236 DockPane(&m_wndLineDiffBar
);
237 ShowPane(&m_wndLocatorBar
, true, false, true);
238 ShowPane(&m_wndLineDiffBar
, true, false, true);
240 m_wndLocatorBar
.EnableGripper(FALSE
);
241 m_wndLineDiffBar
.EnableGripper(FALSE
);
246 BOOL
CMainFrame::PreCreateWindow(CREATESTRUCT
& cs
)
248 if( !CFrameWndEx::PreCreateWindow(cs
) )
253 void CMainFrame::OnApplicationLook(UINT id
)
257 theApp
.m_nAppLook
= id
;
259 switch (theApp
.m_nAppLook
)
261 case ID_VIEW_APPLOOK_WIN_2000
:
262 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager
));
263 m_wndRibbonBar
.SetWindows7Look(FALSE
);
266 case ID_VIEW_APPLOOK_OFF_XP
:
267 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP
));
268 m_wndRibbonBar
.SetWindows7Look(FALSE
);
271 case ID_VIEW_APPLOOK_WIN_XP
:
272 CMFCVisualManagerWindows::m_b3DTabsXPTheme
= TRUE
;
273 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows
));
274 m_wndRibbonBar
.SetWindows7Look(FALSE
);
277 case ID_VIEW_APPLOOK_OFF_2003
:
278 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003
));
279 CDockingManager::SetDockingMode(DT_SMART
);
280 m_wndRibbonBar
.SetWindows7Look(FALSE
);
283 case ID_VIEW_APPLOOK_VS_2005
:
284 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005
));
285 CDockingManager::SetDockingMode(DT_SMART
);
286 m_wndRibbonBar
.SetWindows7Look(FALSE
);
289 case ID_VIEW_APPLOOK_VS_2008
:
290 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2008
));
291 CDockingManager::SetDockingMode(DT_SMART
);
292 m_wndRibbonBar
.SetWindows7Look(FALSE
);
295 case ID_VIEW_APPLOOK_WIN7
:
296 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows7
));
297 CDockingManager::SetDockingMode(DT_SMART
);
298 m_wndRibbonBar
.SetWindows7Look(TRUE
);
302 switch (theApp
.m_nAppLook
)
304 case ID_VIEW_APPLOOK_OFF_2007_BLUE
:
305 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue
);
308 case ID_VIEW_APPLOOK_OFF_2007_BLACK
:
309 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack
);
312 case ID_VIEW_APPLOOK_OFF_2007_SILVER
:
313 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver
);
316 case ID_VIEW_APPLOOK_OFF_2007_AQUA
:
317 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua
);
321 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007
));
322 CDockingManager::SetDockingMode(DT_SMART
);
323 m_wndRibbonBar
.SetWindows7Look(FALSE
);
326 RedrawWindow(NULL
, NULL
, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_FRAME
| RDW_ERASE
);
328 theApp
.WriteInt(_T("ApplicationLook"), theApp
.m_nAppLook
);
331 void CMainFrame::OnUpdateApplicationLook(CCmdUI
* pCmdUI
)
334 pCmdUI
->SetRadio(theApp
.m_nAppLook
== pCmdUI
->m_nID
);
338 // CMainFrame diagnostics
341 void CMainFrame::AssertValid() const
343 CFrameWndEx::AssertValid();
346 void CMainFrame::Dump(CDumpContext
& dc
) const
348 CFrameWndEx::Dump(dc
);
354 // CMainFrame message handlers
357 BOOL
CMainFrame::OnCreateClient(LPCREATESTRUCT
/*lpcs*/, CCreateContext
* pContext
)
363 // split into three panes:
372 // create a splitter with 2 rows, 1 column
373 if (!m_wndSplitter
.CreateStatic(this, 2, 1))
375 TRACE0("Failed to CreateStaticSplitter\n");
379 // add the second splitter pane - which is a nested splitter with 2 columns
380 if (!m_wndSplitter2
.CreateStatic(
381 &m_wndSplitter
, // our parent window is the first splitter
382 1, 2, // the new splitter is 1 row, 2 columns
383 WS_CHILD
| WS_VISIBLE
| WS_BORDER
, // style, WS_BORDER is needed
384 m_wndSplitter
.IdFromRowCol(0, 0)
385 // new splitter is in the first row, 1st column of first splitter
388 TRACE0("Failed to create nested splitter\n");
391 // add the first splitter pane - the default view in row 0
392 if (!m_wndSplitter
.CreateView(1, 0,
393 RUNTIME_CLASS(CBottomView
), CSize(cr
.Width(), cr
.Height()), pContext
))
395 TRACE0("Failed to create first pane\n");
398 m_pwndBottomView
= (CBottomView
*)m_wndSplitter
.GetPane(1,0);
399 m_pwndBottomView
->m_pwndLocator
= &m_wndLocatorBar
;
400 m_pwndBottomView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
401 m_pwndBottomView
->m_pwndStatusBar
= &m_wndStatusBar
;
402 m_pwndBottomView
->m_pMainFrame
= this;
404 // now create the two views inside the nested splitter
406 if (!m_wndSplitter2
.CreateView(0, 0,
407 RUNTIME_CLASS(CLeftView
), CSize(cr
.Width()/2, cr
.Height()/2), pContext
))
409 TRACE0("Failed to create second pane\n");
412 m_pwndLeftView
= (CLeftView
*)m_wndSplitter2
.GetPane(0,0);
413 m_pwndLeftView
->m_pwndLocator
= &m_wndLocatorBar
;
414 m_pwndLeftView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
415 m_pwndLeftView
->m_pwndStatusBar
= &m_wndStatusBar
;
416 m_pwndLeftView
->m_pMainFrame
= this;
418 if (!m_wndSplitter2
.CreateView(0, 1,
419 RUNTIME_CLASS(CRightView
), CSize(cr
.Width()/2, cr
.Height()/2), pContext
))
421 TRACE0("Failed to create third pane\n");
424 m_pwndRightView
= (CRightView
*)m_wndSplitter2
.GetPane(0,1);
425 m_pwndRightView
->m_pwndLocator
= &m_wndLocatorBar
;
426 m_pwndRightView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
427 m_pwndRightView
->m_pwndStatusBar
= &m_wndStatusBar
;
428 m_pwndRightView
->m_pMainFrame
= this;
429 m_bInitSplitter
= TRUE
;
431 m_dlgFilePatches
.Create(IDD_FILEPATCHES
, this);
437 BOOL
CMainFrame::PatchFile(CString sFilePath
, bool /*bContentMods*/, bool bPropMods
, CString sVersion
, BOOL bAutoPatch
)
440 //"dry run" was successful, so save the patched file somewhere...
441 CString sTempFile
= CTempFiles::Instance().GetTempFilePathString();
442 CString sRejectedFile
;
443 if (m_Patch
.GetPatchResult(sFilePath
, sTempFile
, sRejectedFile
) < 0)
445 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
448 sFilePath
= m_Patch
.GetTargetPath() + _T("\\") + sFilePath
;
449 sFilePath
.Replace('/', '\\');
450 if (m_bReversedPatch
)
452 m_Data
.m_baseFile
.SetFileName(sTempFile
);
454 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
455 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
456 m_Data
.m_yourFile
.SetFileName(sFilePath
);
457 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchOriginal
);
458 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
459 m_Data
.m_theirFile
.SetOutOfUse();
460 m_Data
.m_mergedFile
.SetOutOfUse();
464 if ((!PathFileExists(sFilePath
))||(PathIsDirectory(sFilePath
)))
466 m_Data
.m_baseFile
.SetFileName(CTempFiles::Instance().GetTempFilePathString());
467 m_Data
.m_baseFile
.CreateEmptyFile();
471 m_Data
.m_baseFile
.SetFileName(sFilePath
);
473 CString sDescription
;
474 sDescription
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchOriginal
);
475 m_Data
.m_baseFile
.SetDescriptiveName(sDescription
);
476 m_Data
.m_yourFile
.SetFileName(sTempFile
);
478 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
479 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
480 m_Data
.m_theirFile
.SetOutOfUse();
481 m_Data
.m_mergedFile
.SetFileName(sFilePath
);
482 m_Data
.m_bPatchRequired
= bPropMods
;
484 TRACE(_T("comparing %s\nwith the patched result %s\n"), (LPCTSTR
)sFilePath
, (LPCTSTR
)sTempFile
);
487 if (!sRejectedFile
.IsEmpty())
490 // start TortoiseUDiff with the rejected hunks
492 sTitle
.Format(IDS_TITLE_REJECTEDHUNKS
, (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
));
493 CAppUtils::StartUnifiedDiffViewer(sRejectedFile
, sTitle
);
504 BOOL
CMainFrame::DiffFiles(CString sURL1
, CString sRev1
, CString sURL2
, CString sRev2
)
506 CString tempfile1
= CTempFiles::Instance().GetTempFilePathString();
507 CString tempfile2
= CTempFiles::Instance().GetTempFilePathString();
509 ASSERT(tempfile1
.Compare(tempfile2
));
512 CSysProgressDlg progDlg
;
513 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sRev1
);
514 progDlg
.SetLine(1, sTemp
, true);
515 progDlg
.SetLine(2, sURL1
, true);
516 sTemp
.LoadString(IDS_GETVERSIONOFFILETITLE
);
517 progDlg
.SetTitle(sTemp
);
518 progDlg
.SetShowProgressBar(true);
519 progDlg
.SetAnimation(IDR_DOWNLOAD
);
520 progDlg
.SetTime(FALSE
);
521 progDlg
.SetProgress(1,100);
522 progDlg
.ShowModeless(this);
523 if (!CAppUtils::GetVersionedFile(sURL1
, sRev1
, tempfile1
, &progDlg
, m_hWnd
))
527 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sRev1
, (LPCTSTR
)sURL1
);
528 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
531 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sRev2
);
532 progDlg
.SetLine(1, sTemp
, true);
533 progDlg
.SetLine(2, sURL2
, true);
534 progDlg
.SetProgress(50, 100);
535 if (!CAppUtils::GetVersionedFile(sURL2
, sRev2
, tempfile2
, &progDlg
, m_hWnd
))
539 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sRev2
, (LPCTSTR
)sURL2
);
540 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
543 progDlg
.SetProgress(100,100);
546 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sURL1
), (LPCTSTR
)sRev1
);
547 m_Data
.m_baseFile
.SetFileName(tempfile1
);
548 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
549 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sURL2
), (LPCTSTR
)sRev2
);
550 m_Data
.m_yourFile
.SetFileName(tempfile2
);
551 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
558 void CMainFrame::OnFileOpen()
560 if (CheckForSave()==IDCANCEL
)
563 if (dlg
.DoModal()!=IDOK
)
567 m_dlgFilePatches
.ShowWindow(SW_HIDE
);
568 m_dlgFilePatches
.Init(NULL
, NULL
, CString(), NULL
);
569 TRACE(_T("got the files:\n %s\n %s\n %s\n %s\n %s\n"), (LPCTSTR
)dlg
.m_sBaseFile
, (LPCTSTR
)dlg
.m_sTheirFile
, (LPCTSTR
)dlg
.m_sYourFile
,
570 (LPCTSTR
)dlg
.m_sUnifiedDiffFile
, (LPCTSTR
)dlg
.m_sPatchDirectory
);
571 m_Data
.m_baseFile
.SetFileName(dlg
.m_sBaseFile
);
572 m_Data
.m_theirFile
.SetFileName(dlg
.m_sTheirFile
);
573 m_Data
.m_yourFile
.SetFileName(dlg
.m_sYourFile
);
574 m_Data
.m_sDiffFile
= dlg
.m_sUnifiedDiffFile
;
575 m_Data
.m_sPatchPath
= dlg
.m_sPatchDirectory
;
576 m_Data
.m_mergedFile
.SetOutOfUse();
577 CCrashReport::Instance().AddFile2(dlg
.m_sBaseFile
, NULL
, _T("Basefile"), CR_AF_MAKE_FILE_COPY
);
578 CCrashReport::Instance().AddFile2(dlg
.m_sTheirFile
, NULL
, _T("Theirfile"), CR_AF_MAKE_FILE_COPY
);
579 CCrashReport::Instance().AddFile2(dlg
.m_sYourFile
, NULL
, _T("Yourfile"), CR_AF_MAKE_FILE_COPY
);
580 CCrashReport::Instance().AddFile2(dlg
.m_sUnifiedDiffFile
, NULL
, _T("Difffile"), CR_AF_MAKE_FILE_COPY
);
582 if (!m_Data
.IsBaseFileInUse() && m_Data
.IsTheirFileInUse() && m_Data
.IsYourFileInUse())
584 // a diff between two files means "Yours" against "Base", not "Theirs" against "Yours"
585 m_Data
.m_baseFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
587 if (m_Data
.IsBaseFileInUse() && m_Data
.IsTheirFileInUse() && !m_Data
.IsYourFileInUse())
589 // a diff between two files means "Yours" against "Base", not "Theirs" against "Base"
590 m_Data
.m_yourFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
592 m_bSaveRequired
= false;
597 void CMainFrame::ClearViewNamesAndPaths()
599 m_pwndLeftView
->m_sWindowName
.Empty();
600 m_pwndLeftView
->m_sFullFilePath
.Empty();
601 m_pwndRightView
->m_sWindowName
.Empty();
602 m_pwndRightView
->m_sFullFilePath
.Empty();
603 m_pwndBottomView
->m_sWindowName
.Empty();
604 m_pwndBottomView
->m_sFullFilePath
.Empty();
607 bool CMainFrame::LoadViews(int line
)
609 m_Data
.SetBlame(m_bBlame
);
610 m_Data
.SetMovedBlocks(m_bViewMovedBlocks
);
611 m_bHasConflicts
= false;
612 CBaseView
* pwndActiveView
= m_pwndLeftView
;
613 int nOldLine
= m_pwndRightView
? m_pwndRightView
->m_nTopLine
: -1;
615 m_pwndRightView
&& m_pwndRightView
->m_pViewData
?
616 m_pwndRightView
->m_pViewData
->GetLineNumber(m_pwndRightView
->m_nTopLine
) : -1;
617 POINT ptOldCaretPos
= {-1, -1};
618 if (m_pwndRightView
&& m_pwndRightView
->IsTarget())
619 ptOldCaretPos
= m_pwndRightView
->GetCaretPosition();
620 if (m_pwndBottomView
&& m_pwndBottomView
->IsTarget())
621 ptOldCaretPos
= m_pwndBottomView
->GetCaretPosition();
624 m_pwndLeftView
->BuildAllScreen2ViewVector();
625 m_pwndLeftView
->DocumentUpdated();
626 m_pwndRightView
->DocumentUpdated();
627 m_pwndBottomView
->DocumentUpdated();
628 m_wndLocatorBar
.DocumentUpdated();
629 m_wndLineDiffBar
.DocumentUpdated();
630 ::MessageBox(m_hWnd
, m_Data
.GetError(), _T("TortoiseGitMerge"), MB_ICONERROR
);
631 m_Data
.m_mergedFile
.SetOutOfUse();
632 m_bSaveRequired
= false;
636 m_pwndLeftView
->BuildAllScreen2ViewVector();
637 m_pwndLeftView
->DocumentUpdated();
638 m_pwndRightView
->DocumentUpdated();
639 m_pwndBottomView
->DocumentUpdated();
640 m_wndLocatorBar
.DocumentUpdated();
641 m_wndLineDiffBar
.DocumentUpdated();
643 m_pwndRightView
->SetWritable(false);
644 m_pwndRightView
->SetTarget(false);
645 m_pwndBottomView
->SetWritable(false);
646 m_pwndBottomView
->SetTarget(false);
648 if (!m_Data
.IsBaseFileInUse())
650 CSysProgressDlg progDlg
;
651 if (m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
653 m_Data
.m_baseFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
655 else if ((!m_Data
.m_sDiffFile
.IsEmpty())&&(!m_Patch
.Init(m_Data
.m_sDiffFile
, m_Data
.m_sPatchPath
, &progDlg
)))
658 ClearViewNamesAndPaths();
659 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
660 m_bSaveRequired
= false;
664 if (m_Patch
.GetNumberOfFiles() > 0)
666 CString betterpatchpath
= m_Patch
.CheckPatchPath(m_Data
.m_sPatchPath
);
667 if (betterpatchpath
.CompareNoCase(m_Data
.m_sPatchPath
)!=0)
670 msg
.Format(IDS_WARNBETTERPATCHPATHFOUND
, (LPCTSTR
)m_Data
.m_sPatchPath
, (LPCTSTR
)betterpatchpath
);
671 if (CMessageBox::Show(m_hWnd
, msg
, _T("TortoiseGitMerge"), MB_ICONQUESTION
| MB_YESNO
)==IDYES
)
673 m_Data
.m_sPatchPath
= betterpatchpath
;
674 m_Patch
.Init(m_Data
.m_sDiffFile
, m_Data
.m_sPatchPath
, &progDlg
);
677 m_dlgFilePatches
.Init(&m_Patch
, this, m_Data
.m_sPatchPath
, this);
678 m_dlgFilePatches
.ShowWindow(SW_SHOW
);
679 ClearViewNamesAndPaths();
680 if (!m_wndSplitter
.IsRowHidden(1))
681 m_wndSplitter
.HideRow(1);
682 m_pwndLeftView
->SetHidden(FALSE
);
683 m_pwndRightView
->SetHidden(FALSE
);
684 m_pwndBottomView
->SetHidden(TRUE
);
687 if (m_Data
.IsBaseFileInUse() && !m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
689 m_Data
.m_yourFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
691 if (m_Data
.IsBaseFileInUse() && m_Data
.IsYourFileInUse() && !m_Data
.IsTheirFileInUse())
693 //diff between YOUR and BASE
694 m_pwndRightView
->SetWritable();
695 m_pwndRightView
->SetTarget();
698 if (!m_wndSplitter2
.IsColumnHidden(1))
699 m_wndSplitter2
.HideColumn(1);
701 m_pwndLeftView
->m_pViewData
= &m_Data
.m_YourBaseBoth
;
702 m_pwndLeftView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
703 m_pwndLeftView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
704 m_pwndLeftView
->m_sWindowName
= m_Data
.m_baseFile
.GetWindowName() + _T(" - ") + m_Data
.m_yourFile
.GetWindowName();
705 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_baseFile
.GetFilename() + _T(" - ") + m_Data
.m_yourFile
.GetFilename();
707 m_pwndRightView
->m_pViewData
= NULL
;
708 m_pwndBottomView
->m_pViewData
= NULL
;
710 if (!m_wndSplitter
.IsRowHidden(1))
711 m_wndSplitter
.HideRow(1);
712 m_pwndLeftView
->SetHidden(FALSE
);
713 m_pwndRightView
->SetHidden(TRUE
);
714 m_pwndBottomView
->SetHidden(TRUE
);
715 ::SetWindowPos(m_pwndLeftView
->m_hWnd
, NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
719 pwndActiveView
= m_pwndRightView
;
720 if (m_wndSplitter2
.IsColumnHidden(1))
721 m_wndSplitter2
.ShowColumn();
723 m_pwndLeftView
->m_pViewData
= &m_Data
.m_YourBaseLeft
;
724 m_pwndLeftView
->texttype
= m_Data
.m_arBaseFile
.GetUnicodeType();
725 m_pwndLeftView
->lineendings
= m_Data
.m_arBaseFile
.GetLineEndings();
726 m_pwndLeftView
->m_sWindowName
= m_Data
.m_baseFile
.GetWindowName();
727 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_baseFile
.GetFilename();
729 m_pwndRightView
->m_pViewData
= &m_Data
.m_YourBaseRight
;
730 m_pwndRightView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
731 m_pwndRightView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
732 m_pwndRightView
->m_sWindowName
= m_Data
.m_yourFile
.GetWindowName();
733 m_pwndRightView
->m_sFullFilePath
= m_Data
.m_yourFile
.GetFilename();
735 m_pwndBottomView
->m_pViewData
= NULL
;
737 if (!m_wndSplitter
.IsRowHidden(1))
738 m_wndSplitter
.HideRow(1);
739 m_pwndLeftView
->SetHidden(FALSE
);
740 m_pwndRightView
->SetHidden(FALSE
);
741 m_pwndBottomView
->SetHidden(TRUE
);
744 else if (m_Data
.IsBaseFileInUse() && m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
746 //diff between THEIR, YOUR and BASE
747 m_pwndBottomView
->SetWritable();
748 m_pwndBottomView
->SetTarget();
749 pwndActiveView
= m_pwndBottomView
;
751 m_pwndLeftView
->m_pViewData
= &m_Data
.m_TheirBaseBoth
;
752 m_pwndLeftView
->texttype
= m_Data
.m_arTheirFile
.GetUnicodeType();
753 m_pwndLeftView
->lineendings
= m_Data
.m_arTheirFile
.GetLineEndings();
754 m_pwndLeftView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_THEIRS
);
755 m_pwndLeftView
->m_sWindowName
+= _T(" - ") + m_Data
.m_theirFile
.GetWindowName();
756 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_theirFile
.GetFilename();
758 m_pwndRightView
->m_pViewData
= &m_Data
.m_YourBaseBoth
;
759 m_pwndRightView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
760 m_pwndRightView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
761 m_pwndRightView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_MINE
);
762 m_pwndRightView
->m_sWindowName
+= _T(" - ") + m_Data
.m_yourFile
.GetWindowName();
763 m_pwndRightView
->m_sFullFilePath
= m_Data
.m_yourFile
.GetFilename();
765 m_pwndBottomView
->m_pViewData
= &m_Data
.m_Diff3
;
766 m_pwndBottomView
->texttype
= m_Data
.m_arTheirFile
.GetUnicodeType();
767 m_pwndBottomView
->lineendings
= m_Data
.m_arTheirFile
.GetLineEndings();
768 m_pwndBottomView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_MERGED
);
769 m_pwndBottomView
->m_sWindowName
+= _T(" - ") + m_Data
.m_mergedFile
.GetWindowName();
770 m_pwndBottomView
->m_sFullFilePath
= m_Data
.m_mergedFile
.GetFilename();
772 if (m_wndSplitter2
.IsColumnHidden(1))
773 m_wndSplitter2
.ShowColumn();
774 if (m_wndSplitter
.IsRowHidden(1))
775 m_wndSplitter
.ShowRow();
776 m_pwndLeftView
->SetHidden(FALSE
);
777 m_pwndRightView
->SetHidden(FALSE
);
778 m_pwndBottomView
->SetHidden(FALSE
);
779 // in three pane view, hide the line diff bar
780 m_wndLineDiffBar
.ShowPane(false, false, true);
781 m_wndLineDiffBar
.DocumentUpdated();
783 if (!m_Data
.m_mergedFile
.InUse())
785 m_Data
.m_mergedFile
.SetFileName(m_Data
.m_yourFile
.GetFilename());
787 m_pwndLeftView
->BuildAllScreen2ViewVector();
788 m_pwndLeftView
->DocumentUpdated();
789 m_pwndRightView
->DocumentUpdated();
790 m_pwndBottomView
->DocumentUpdated();
791 m_wndLocatorBar
.DocumentUpdated();
792 m_wndLineDiffBar
.DocumentUpdated();
794 SetActiveView(pwndActiveView
);
796 if ((line
>= -1) && m_pwndRightView
->m_pViewData
)
798 int n
= line
== -1 ? min( nOldLineNumber
, nOldLine
) : line
;
800 n
= m_pwndRightView
->m_pViewData
->FindLineNumber(n
);
804 m_pwndRightView
->ScrollAllToLine(n
);
808 if ((ptOldCaretPos
.x
>= 0) || (ptOldCaretPos
.y
>= 0))
810 m_pwndLeftView
->SetCaretPosition(p
);
811 m_pwndRightView
->SetCaretPosition(p
);
812 m_pwndBottomView
->SetCaretPosition(p
);
813 m_pwndBottomView
->ScrollToChar(0);
814 m_pwndLeftView
->ScrollToChar(0);
815 m_pwndRightView
->ScrollToChar(0);
819 CRegDWORD regFirstDiff
= CRegDWORD(_T("Software\\TortoiseGitMerge\\FirstDiffOnLoad"), TRUE
);
820 CRegDWORD regFirstConflict
= CRegDWORD(_T("Software\\TortoiseGitMerge\\FirstConflictOnLoad"), TRUE
);
821 bool bGoFirstDiff
= (0 != (DWORD
)regFirstDiff
);
822 bool bGoFirstConflict
= (0 != (DWORD
)regFirstConflict
);
823 if (bGoFirstConflict
&& (CheckResolved()>=0))
825 pwndActiveView
->GoToFirstConflict();
826 // Ignore the first few Mouse Move messages, so that the line diff stays on
827 // the first diff line until the user actually moves the mouse
828 m_nMoveMovesToIgnore
= MOVESTOIGNORE
;
830 else if (bGoFirstDiff
)
832 pwndActiveView
->GoToFirstDifference();
833 // Ignore the first few Mouse Move messages, so that the line diff stays on
834 // the first diff line until the user actually moves the mouse
835 m_nMoveMovesToIgnore
= MOVESTOIGNORE
;
839 // Avoid incorrect rendering of active pane.
840 m_pwndBottomView
->ScrollToChar(0);
841 m_pwndLeftView
->ScrollToChar(0);
842 m_pwndRightView
->ScrollToChar(0);
847 m_bSaveRequired
= false;
848 CUndo::GetInstance().Clear();
852 void CMainFrame::UpdateLayout()
856 m_wndSplitter
.CenterSplitter();
857 m_wndSplitter2
.CenterSplitter();
861 void CMainFrame::OnSize(UINT nType
, int cx
, int cy
)
863 CFrameWndEx::OnSize(nType
, cx
, cy
);
864 if (m_bInitSplitter
&& nType
!= SIZE_MINIMIZED
)
866 if (m_wndSplitter
.GetSafeHwnd())
868 if (m_wndSplitter
.HasOldRowSize() && (m_wndSplitter
.GetOldRowCount() == 2))
870 int oldTotal
= m_wndSplitter
.GetOldRowSize(0) + m_wndSplitter
.GetOldRowSize(1);
873 int cxCur0
, cxCur1
, cxMin0
, cxMin1
;
874 m_wndSplitter
.GetRowInfo(0, cxCur0
, cxMin0
);
875 m_wndSplitter
.GetRowInfo(1, cxCur1
, cxMin1
);
876 cxCur0
= m_wndSplitter
.GetOldRowSize(0) * (cxCur0
+ cxCur1
) / oldTotal
;
877 cxCur1
= m_wndSplitter
.GetOldRowSize(1) * (cxCur0
+ cxCur1
) / oldTotal
;
878 m_wndSplitter
.SetRowInfo(0, cxCur0
, 0);
879 m_wndSplitter
.SetRowInfo(1, cxCur1
, 0);
880 m_wndSplitter
.RecalcLayout();
884 if (m_wndSplitter2
.HasOldColSize() && (m_wndSplitter2
.GetOldColCount() == 2))
886 int oldTotal
= m_wndSplitter2
.GetOldColSize(0) + m_wndSplitter2
.GetOldColSize(1);
889 int cyCur0
, cyCur1
, cyMin0
, cyMin1
;
890 m_wndSplitter2
.GetColumnInfo(0, cyCur0
, cyMin0
);
891 m_wndSplitter2
.GetColumnInfo(1, cyCur1
, cyMin1
);
892 cyCur0
= m_wndSplitter2
.GetOldColSize(0) * (cyCur0
+ cyCur1
) / oldTotal
;
893 cyCur1
= m_wndSplitter2
.GetOldColSize(1) * (cyCur0
+ cyCur1
) / oldTotal
;
894 m_wndSplitter2
.SetColumnInfo(0, cyCur0
, 0);
895 m_wndSplitter2
.SetColumnInfo(1, cyCur1
, 0);
896 m_wndSplitter2
.RecalcLayout();
901 if ((nType
== SIZE_RESTORED
)&&m_bCheckReload
)
903 m_bCheckReload
= false;
908 void CMainFrame::OnViewWhitespaces()
910 CRegDWORD regViewWhitespaces
= CRegDWORD(_T("Software\\TortoiseGitMerge\\ViewWhitespaces"), 1);
911 BOOL bViewWhitespaces
= regViewWhitespaces
;
913 bViewWhitespaces
= m_pwndLeftView
->m_bViewWhitespace
;
915 bViewWhitespaces
= !bViewWhitespaces
;
916 regViewWhitespaces
= bViewWhitespaces
;
919 m_pwndLeftView
->m_bViewWhitespace
= bViewWhitespaces
;
920 m_pwndLeftView
->Invalidate();
924 m_pwndRightView
->m_bViewWhitespace
= bViewWhitespaces
;
925 m_pwndRightView
->Invalidate();
927 if (m_pwndBottomView
)
929 m_pwndBottomView
->m_bViewWhitespace
= bViewWhitespaces
;
930 m_pwndBottomView
->Invalidate();
934 void CMainFrame::OnUpdateViewWhitespaces(CCmdUI
*pCmdUI
)
937 pCmdUI
->SetCheck(m_pwndLeftView
->m_bViewWhitespace
);
940 void CMainFrame::OnViewCollapsed()
942 m_regCollapsed
= !(DWORD
)m_regCollapsed
;
943 m_bCollapsed
= !!(DWORD
)m_regCollapsed
;
945 OnViewTextFoldUnfold();
946 m_wndLocatorBar
.Invalidate();
949 void CMainFrame::OnUpdateViewCollapsed(CCmdUI
*pCmdUI
)
951 pCmdUI
->SetCheck(m_bCollapsed
);
954 void CMainFrame::OnViewWraplonglines()
956 m_bWrapLines
= !(DWORD
)m_regWrapLines
;
957 m_regWrapLines
= m_bWrapLines
;
959 if (m_pwndLeftView
) m_pwndLeftView
->WrapChanged();
960 if (m_pwndRightView
) m_pwndRightView
->WrapChanged();
961 if (m_pwndBottomView
) m_pwndBottomView
->WrapChanged();
962 OnViewTextFoldUnfold();
963 m_wndLocatorBar
.DocumentUpdated();
966 void CMainFrame::OnViewTextFoldUnfold()
968 OnViewTextFoldUnfold(m_pwndLeftView
);
969 OnViewTextFoldUnfold(m_pwndRightView
);
970 OnViewTextFoldUnfold(m_pwndBottomView
);
973 void CMainFrame::OnViewTextFoldUnfold(CBaseView
* view
)
977 view
->BuildAllScreen2ViewVector();
980 view
->EnsureCaretVisible();
983 void CMainFrame::OnUpdateViewWraplonglines(CCmdUI
*pCmdUI
)
985 pCmdUI
->SetCheck(m_bWrapLines
);
988 void CMainFrame::OnViewOnewaydiff()
990 if (CheckForSave()==IDCANCEL
)
992 m_bOneWay
= !m_bOneWay
;
993 ShowDiffBar(!m_bOneWay
);
997 void CMainFrame::ShowDiffBar(bool bShow
)
1001 // restore the line diff bar
1002 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
1003 m_wndLineDiffBar
.DocumentUpdated();
1004 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
1005 m_wndLocatorBar
.DocumentUpdated();
1009 // in one way view, hide the line diff bar
1010 m_wndLineDiffBar
.ShowPane(false, false, true);
1011 m_wndLineDiffBar
.DocumentUpdated();
1015 int CMainFrame::CheckResolved()
1017 //only in three way diffs can be conflicts!
1018 m_bHasConflicts
= true;
1019 if (m_pwndBottomView
->IsWindowVisible())
1021 CViewData
* viewdata
= m_pwndBottomView
->m_pViewData
;
1024 for (int i
=0; i
<viewdata
->GetCount(); i
++)
1026 const DiffStates state
= viewdata
->GetState(i
);
1027 if ((DIFFSTATE_CONFLICTED
== state
)||(DIFFSTATE_CONFLICTED_IGNORED
== state
))
1032 m_bHasConflicts
= false;
1036 int CMainFrame::SaveFile(const CString
& sFilePath
)
1038 CViewData
* pViewData
= NULL
;
1039 CFileTextLines
* pOriginFile
= &m_Data
.m_arBaseFile
;
1040 if (IsViewGood(m_pwndBottomView
))
1042 pViewData
= m_pwndBottomView
->m_pViewData
;
1045 else if (IsViewGood(m_pwndRightView
))
1047 pViewData
= m_pwndRightView
->m_pViewData
;
1048 if (m_Data
.IsYourFileInUse())
1049 pOriginFile
= &m_Data
.m_arYourFile
;
1050 else if (m_Data
.IsTheirFileInUse())
1051 pOriginFile
= &m_Data
.m_arTheirFile
;
1059 if ((pViewData
)&&(pOriginFile
))
1061 CFileTextLines file
;
1062 pOriginFile
->CopySettings(&file
);
1063 for (int i
=0; i
<pViewData
->GetCount(); i
++)
1065 //only copy non-removed lines
1066 DiffStates state
= pViewData
->GetState(i
);
1069 case DIFFSTATE_CONFLICTED
:
1070 case DIFFSTATE_CONFLICTED_IGNORED
:
1077 } while((last
<pViewData
->GetCount()) && ((pViewData
->GetState(last
)==DIFFSTATE_CONFLICTED
)||(pViewData
->GetState(last
)==DIFFSTATE_CONFLICTED_IGNORED
)));
1078 // TortoiseGitMerge changes here
1079 file
.Add(_T("<<<<<<< .mine"), m_pwndRightView
->lineendings
);
1080 for (int j
=first
; j
<last
; j
++)
1082 EOL lineending
= m_pwndRightView
->m_pViewData
->GetLineEnding(j
);
1083 if (lineending
== EOL_NOENDING
)
1084 lineending
= m_pwndRightView
->lineendings
;
1085 file
.Add(m_pwndRightView
->m_pViewData
->GetLine(j
), lineending
);
1087 file
.Add(_T("======="), m_pwndRightView
->lineendings
);
1088 for (int j
=first
; j
<last
; j
++)
1090 EOL lineending
= m_pwndLeftView
->m_pViewData
->GetLineEnding(j
);
1091 if (lineending
== EOL_NOENDING
)
1092 lineending
= m_pwndLeftView
->lineendings
;
1093 file
.Add(m_pwndLeftView
->m_pViewData
->GetLine(j
), lineending
);
1095 file
.Add(_T(">>>>>>> .theirs"), m_pwndRightView
->lineendings
);
1099 case DIFFSTATE_EMPTY
:
1100 case DIFFSTATE_CONFLICTEMPTY
:
1101 case DIFFSTATE_IDENTICALREMOVED
:
1102 case DIFFSTATE_REMOVED
:
1103 case DIFFSTATE_THEIRSREMOVED
:
1104 case DIFFSTATE_YOURSREMOVED
:
1105 case DIFFSTATE_CONFLICTRESOLVEDEMPTY
:
1106 // do not save removed lines
1109 file
.Add(pViewData
->GetLine(i
), pViewData
->GetLineEnding(i
));
1113 if (!file
.Save(sFilePath
, false, false))
1115 CMessageBox::Show(m_hWnd
, file
.GetErrorString(), _T("TortoiseGitMerge"), MB_ICONERROR
);
1118 if (sFilePath
== m_Data
.m_baseFile
.GetFilename())
1120 m_Data
.m_baseFile
.StoreFileAttributes();
1122 if (sFilePath
== m_Data
.m_theirFile
.GetFilename())
1124 m_Data
.m_theirFile
.StoreFileAttributes();
1126 if (sFilePath
== m_Data
.m_yourFile
.GetFilename())
1128 m_Data
.m_yourFile
.StoreFileAttributes();
1130 /*if (sFilePath == m_Data.m_mergedFile.GetFilename())
1132 m_Data.m_mergedFile.StoreFileAttributes();
1134 m_dlgFilePatches
.SetFileStatusAsPatched(sFilePath
);
1135 if (m_pwndBottomView
)
1136 m_pwndBottomView
->SetModified(FALSE
);
1137 if (m_pwndRightView
)
1138 m_pwndRightView
->SetModified(FALSE
);
1139 CUndo::GetInstance().MarkAsOriginalState();
1140 if (file
.GetCount() == 1 && file
.GetLineEnding(0) == EOL_NOENDING
)
1142 return file
.GetCount();
1147 void CMainFrame::OnFileSave()
1152 void CMainFrame::PatchSave()
1154 bool bDoesNotExist
= !PathFileExists(m_Data
.m_mergedFile
.GetFilename());
1155 if (m_Data
.m_bPatchRequired
)
1157 m_Patch
.PatchPath(m_Data
.m_mergedFile
.GetFilename());
1159 if (!PathIsDirectory(m_Data
.m_mergedFile
.GetFilename()))
1161 int saveret
= SaveFile(m_Data
.m_mergedFile
.GetFilename());
1164 // file was saved with 0 lines, remove it.
1165 m_Patch
.RemoveFile(m_Data
.m_mergedFile
.GetFilename());
1167 DeleteFile(m_Data
.m_mergedFile
.GetFilename());
1169 m_Data
.m_mergedFile
.StoreFileAttributes();
1170 if (m_Data
.m_mergedFile
.GetFilename() == m_Data
.m_yourFile
.GetFilename())
1171 m_Data
.m_yourFile
.StoreFileAttributes();
1172 if ((bDoesNotExist
)&&(DWORD(CRegDWORD(_T("Software\\TortoiseGitMerge\\AutoAdd"), TRUE
))))
1174 // call TortoiseProc to add the new file to version control
1175 CString cmd
= _T("/command:add /noui /path:\"");
1176 cmd
+= m_Data
.m_mergedFile
.GetFilename() + _T("\"");
1177 CAppUtils::RunTortoiseGitProc(cmd
);
1182 bool CMainFrame::FileSave(bool bCheckResolved
/*=true*/)
1184 if (!m_Data
.m_mergedFile
.InUse())
1185 return FileSaveAs(bCheckResolved
);
1186 // check if the file has the readonly attribute set
1187 bool bDoesNotExist
= false;
1188 DWORD fAttribs
= GetFileAttributes(m_Data
.m_mergedFile
.GetFilename());
1189 if ((fAttribs
!= INVALID_FILE_ATTRIBUTES
)&&(fAttribs
& FILE_ATTRIBUTE_READONLY
))
1190 return FileSaveAs(bCheckResolved
);
1191 if (fAttribs
== INVALID_FILE_ATTRIBUTES
)
1193 bDoesNotExist
= (GetLastError() == ERROR_FILE_NOT_FOUND
);
1195 if (bCheckResolved
&& HasConflictsWontKeep())
1198 if (((DWORD
)CRegDWORD(_T("Software\\TortoiseGitMerge\\Backup"))) != 0)
1200 MoveFileEx(m_Data
.m_mergedFile
.GetFilename(), m_Data
.m_mergedFile
.GetFilename() + _T(".bak"), MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
| MOVEFILE_WRITE_THROUGH
);
1202 if (m_Data
.m_bPatchRequired
)
1204 m_Patch
.PatchPath(m_Data
.m_mergedFile
.GetFilename());
1206 int saveret
= SaveFile(m_Data
.m_mergedFile
.GetFilename());
1209 // file was saved with 0 lines!
1210 // ask the user if the file should be deleted
1212 sTemp
.Format(IDS_DELETEWHENEMPTY
, (LPCTSTR
)m_Data
.m_mergedFile
.GetFilename());
1213 if (CMessageBox::ShowCheck(m_hWnd
, sTemp
, _T("TortoiseGitMerge"), MB_YESNO
, _T("DeleteFileWhenEmpty")) == IDYES
)
1215 m_Patch
.RemoveFile(m_Data
.m_mergedFile
.GetFilename());
1216 DeleteFile(m_Data
.m_mergedFile
.GetFilename());
1219 else if (saveret
< 0)
1221 // error while saving the file
1225 // if we're in conflict resolve mode (three pane view), check if there are no more conflicts
1226 // and if there aren't, ask to mark the file as resolved
1227 if (IsViewGood(m_pwndBottomView
) && !m_bHasConflicts
)
1230 CTGitPath svnpath
= CTGitPath(m_Data
.m_mergedFile
.GetFilename());
1231 if (SVNHelper::IsVersioned(svnpath
, true))
1234 svn_opt_revision_t rev
;
1235 rev
.kind
= svn_opt_revision_unspecified
;
1236 svn_wc_status_kind statuskind
= svn_wc_status_none
;
1237 svn_client_ctx_t
* ctx
= NULL
;
1238 svn_error_clear(svn_client_create_context2(&ctx
, SVNConfig::Instance().GetConfig(pool
), pool
));
1239 svn_error_t
* err
= svn_client_status5(NULL
, ctx
, svnpath
.GetSVNApiPath(pool
), &rev
,
1250 if ((err
== NULL
) && (statuskind
== svn_wc_status_conflicted
))
1253 sTemp
.Format(IDS_MARKASRESOLVED
, (LPCTSTR
)CPathUtils::GetFileNameFromPath(m_Data
.m_mergedFile
.GetFilename()));
1254 if (CMessageBox::Show(m_hWnd
, sTemp
, _T("TortoiseGitMerge"), MB_YESNO
) == IDYES
))
1257 svn_error_clear(err
);
1262 m_bSaveRequired
= false;
1263 m_Data
.m_mergedFile
.StoreFileAttributes();
1265 if ((bDoesNotExist
)&&(DWORD(CRegDWORD(_T("Software\\TortoiseGitMerge\\AutoAdd"), TRUE
))))
1267 // call TortoiseProc to add the new file to version control
1268 CString cmd
= _T("/command:add /noui /path:\"");
1269 cmd
+= m_Data
.m_mergedFile
.GetFilename() + _T("\"");
1270 if(!CAppUtils::RunTortoiseGitProc(cmd
))
1276 void CMainFrame::OnFileSaveAs()
1281 bool CMainFrame::FileSaveAs(bool bCheckResolved
/*=true*/)
1283 if (bCheckResolved
&& HasConflictsWontKeep())
1287 if(!TryGetFileName(fileName
))
1294 void CMainFrame::OnUpdateFileSave(CCmdUI
*pCmdUI
)
1296 BOOL bEnable
= FALSE
;
1297 if (m_Data
.m_mergedFile
.InUse())
1299 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1301 else if ( (IsViewGood(m_pwndRightView
)&&(m_pwndRightView
->m_pViewData
)) &&
1302 (m_pwndRightView
->IsModified() || (m_Data
.m_yourFile
.GetWindowName().Right(9).Compare(_T(": patched"))==0)) )
1305 pCmdUI
->Enable(bEnable
);
1308 void CMainFrame::OnUpdateFileSaveAs(CCmdUI
*pCmdUI
)
1310 BOOL bEnable
= FALSE
;
1311 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1313 else if (IsViewGood(m_pwndRightView
)&&(m_pwndRightView
->m_pViewData
))
1315 pCmdUI
->Enable(bEnable
);
1318 void CMainFrame::OnUpdateViewOnewaydiff(CCmdUI
*pCmdUI
)
1320 pCmdUI
->SetCheck(!m_bOneWay
);
1321 BOOL bEnable
= TRUE
;
1322 if (IsViewGood(m_pwndBottomView
))
1326 pCmdUI
->Enable(bEnable
);
1329 void CMainFrame::OnViewOptions()
1332 sTemp
.LoadString(IDS_SETTINGSTITLE
);
1333 CSettings
dlg(sTemp
);
1335 if (dlg
.IsReloadNeeded())
1337 if (CheckForSave()==IDCANCEL
)
1339 CDiffColors::GetInstance().LoadRegistry();
1343 CDiffColors::GetInstance().LoadRegistry();
1344 if (m_pwndBottomView
)
1345 m_pwndBottomView
->Invalidate();
1347 m_pwndLeftView
->Invalidate();
1348 if (m_pwndRightView
)
1349 m_pwndRightView
->Invalidate();
1352 void CMainFrame::OnClose()
1355 if (HasUnsavedEdits())
1358 sTemp
.LoadString(IDS_ASKFORSAVE
);
1359 ret
= MessageBox(sTemp
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
1367 if ((ret
== IDNO
)||(ret
== IDYES
))
1371 // before it is destroyed, save the position of the window
1372 wp
.length
= sizeof wp
;
1374 if (GetWindowPlacement(&wp
))
1378 // never restore to Iconic state
1379 wp
.showCmd
= SW_SHOW
;
1381 if ((wp
.flags
& WPF_RESTORETOMAXIMIZED
) != 0)
1382 // if maximized and maybe iconic restore maximized state
1383 wp
.showCmd
= SW_SHOWMAXIMIZED
;
1385 // and write it to the .INI file
1386 WriteWindowPlacement(&wp
);
1392 void CMainFrame::OnActivate(UINT nValue
, CWnd
* /*pwnd*/, BOOL
/*bActivated?*/) {
1393 if (nValue
!= 0) // activated
1397 m_bCheckReload
= TRUE
;
1404 void CMainFrame::OnViewLinedown()
1406 OnViewLineUpDown(1);
1409 void CMainFrame::OnViewLineup()
1411 OnViewLineUpDown(-1);
1414 void CMainFrame::OnViewLineUpDown(int direction
)
1417 m_pwndLeftView
->ScrollToLine(m_pwndLeftView
->m_nTopLine
+direction
);
1418 if (m_pwndRightView
)
1419 m_pwndRightView
->ScrollToLine(m_pwndRightView
->m_nTopLine
+direction
);
1420 if (m_pwndBottomView
)
1421 m_pwndBottomView
->ScrollToLine(m_pwndBottomView
->m_nTopLine
+direction
);
1422 m_wndLocatorBar
.Invalidate();
1423 m_nMoveMovesToIgnore
= MOVESTOIGNORE
;
1426 void CMainFrame::OnViewLineleft()
1428 OnViewLineLeftRight(-1);
1431 void CMainFrame::OnViewLineright()
1433 OnViewLineLeftRight(1);
1436 void CMainFrame::OnViewLineLeftRight(int direction
)
1439 m_pwndLeftView
->ScrollSide(direction
);
1440 if (m_pwndRightView
)
1441 m_pwndRightView
->ScrollSide(direction
);
1442 if (m_pwndBottomView
)
1443 m_pwndBottomView
->ScrollSide(direction
);
1446 void CMainFrame::OnEditUseTheirs()
1448 if (m_pwndBottomView
)
1449 m_pwndBottomView
->UseTheirTextBlock();
1451 void CMainFrame::OnUpdateEditUsetheirblock(CCmdUI
*pCmdUI
)
1453 pCmdUI
->Enable(m_pwndBottomView
&& m_pwndBottomView
->HasSelection());
1456 void CMainFrame::OnEditUseMine()
1458 if (m_pwndBottomView
)
1459 m_pwndBottomView
->UseMyTextBlock();
1461 void CMainFrame::OnUpdateEditUsemyblock(CCmdUI
*pCmdUI
)
1463 OnUpdateEditUsetheirblock(pCmdUI
);
1466 void CMainFrame::OnEditUseTheirsThenMine()
1468 if (m_pwndBottomView
)
1469 m_pwndBottomView
->UseTheirAndYourBlock();
1472 void CMainFrame::OnUpdateEditUsetheirthenmyblock(CCmdUI
*pCmdUI
)
1474 OnUpdateEditUsetheirblock(pCmdUI
);
1477 void CMainFrame::OnEditUseMineThenTheirs()
1479 if (m_pwndBottomView
)
1480 m_pwndBottomView
->UseYourAndTheirBlock();
1483 void CMainFrame::OnUpdateEditUseminethentheirblock(CCmdUI
*pCmdUI
)
1485 OnUpdateEditUsetheirblock(pCmdUI
);
1488 void CMainFrame::OnEditUseleftblock()
1490 if (m_pwndBottomView
->IsWindowVisible())
1491 m_pwndBottomView
->UseRightBlock();
1493 m_pwndRightView
->UseLeftBlock();
1496 void CMainFrame::OnUpdateEditUseleftblock(CCmdUI
*pCmdUI
)
1498 pCmdUI
->Enable(IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsTarget() && m_pwndRightView
->HasSelection());
1501 void CMainFrame::OnUpdateUseBlock(CCmdUI
*pCmdUI
)
1503 pCmdUI
->Enable(TRUE
);
1506 void CMainFrame::OnEditUseleftfile()
1508 if (m_pwndBottomView
->IsWindowVisible())
1509 m_pwndBottomView
->UseRightFile();
1511 m_pwndRightView
->UseLeftFile();
1514 void CMainFrame::OnUpdateEditUseleftfile(CCmdUI
*pCmdUI
)
1516 pCmdUI
->Enable(IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsTarget());
1519 void CMainFrame::OnEditUseblockfromleftbeforeright()
1521 if (m_pwndRightView
)
1522 m_pwndRightView
->UseBothLeftFirst();
1525 void CMainFrame::OnUpdateEditUseblockfromleftbeforeright(CCmdUI
*pCmdUI
)
1527 OnUpdateEditUseleftblock(pCmdUI
);
1530 void CMainFrame::OnEditUseblockfromrightbeforeleft()
1532 if (m_pwndRightView
)
1533 m_pwndRightView
->UseBothRightFirst();
1536 void CMainFrame::OnUpdateEditUseblockfromrightbeforeleft(CCmdUI
*pCmdUI
)
1538 OnUpdateEditUseleftblock(pCmdUI
);
1541 void CMainFrame::OnFileReload()
1543 if (CheckForSave()==IDCANCEL
)
1545 CDiffColors::GetInstance().LoadRegistry();
1549 void CMainFrame::ActivateFrame(int nCmdShow
)
1551 // nCmdShow is the normal show mode this frame should be in
1552 // translate default nCmdShow (-1)
1555 if (!IsWindowVisible())
1556 nCmdShow
= SW_SHOWNORMAL
;
1557 else if (IsIconic())
1558 nCmdShow
= SW_RESTORE
;
1561 // bring to top before showing
1562 BringToTop(nCmdShow
);
1566 // show the window as specified
1569 if ( !ReadWindowPlacement(&wp
) )
1571 ShowWindow(nCmdShow
);
1575 if ( nCmdShow
!= SW_SHOWNORMAL
)
1576 wp
.showCmd
= nCmdShow
;
1578 SetWindowPlacement(&wp
);
1581 // and finally, bring to top after showing
1582 BringToTop(nCmdShow
);
1586 BOOL
CMainFrame::ReadWindowPlacement(WINDOWPLACEMENT
* pwp
)
1588 CRegString placement
= CRegString(_T("Software\\TortoiseGitMerge\\WindowPos"));
1589 CString sPlacement
= placement
;
1590 if (sPlacement
.IsEmpty())
1592 int nRead
= _stscanf_s(sPlacement
, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
1593 &pwp
->flags
, &pwp
->showCmd
,
1594 &pwp
->ptMinPosition
.x
, &pwp
->ptMinPosition
.y
,
1595 &pwp
->ptMaxPosition
.x
, &pwp
->ptMaxPosition
.y
,
1596 &pwp
->rcNormalPosition
.left
, &pwp
->rcNormalPosition
.top
,
1597 &pwp
->rcNormalPosition
.right
, &pwp
->rcNormalPosition
.bottom
);
1600 pwp
->length
= sizeof(WINDOWPLACEMENT
);
1605 void CMainFrame::WriteWindowPlacement(WINDOWPLACEMENT
* pwp
)
1607 CRegString placement
= CRegString(_T("Software\\TortoiseGitMerge\\WindowPos"));
1608 TCHAR szBuffer
[_countof("-32767")*8 + sizeof("65535")*2];
1610 _stprintf_s(szBuffer
, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
1611 pwp
->flags
, pwp
->showCmd
,
1612 pwp
->ptMinPosition
.x
, pwp
->ptMinPosition
.y
,
1613 pwp
->ptMaxPosition
.x
, pwp
->ptMaxPosition
.y
,
1614 pwp
->rcNormalPosition
.left
, pwp
->rcNormalPosition
.top
,
1615 pwp
->rcNormalPosition
.right
, pwp
->rcNormalPosition
.bottom
);
1616 placement
= szBuffer
;
1619 void CMainFrame::OnUpdateMergeMarkasresolved(CCmdUI
*pCmdUI
)
1623 BOOL bEnable
= FALSE
;
1624 if ((!m_bReadOnly
)&&(m_Data
.m_mergedFile
.InUse()))
1626 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1631 pCmdUI
->Enable(bEnable
);
1634 void CMainFrame::OnMergeMarkasresolved()
1636 if(HasConflictsWontKeep())
1639 // now check if the file has already been saved and if not, save it.
1640 if (m_Data
.m_mergedFile
.InUse())
1642 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1645 m_bSaveRequired
= false;
1651 BOOL
CMainFrame::MarkAsResolved()
1655 if (!IsViewGood(m_pwndBottomView
))
1658 CString cmd
= _T("/command:resolve /path:\"");
1659 cmd
+= m_Data
.m_mergedFile
.GetFilename();
1660 cmd
+= _T("\" /closeonend:1 /noquestion /skipcheck /silent");
1664 s
.Format(L
" /resolvemsghwnd:%I64d /resolvemsgwparam:%I64d /resolvemsglparam:%I64d", (__int64
)resolveMsgWnd
, (__int64
)resolveMsgWParam
, (__int64
)resolveMsgLParam
);
1667 if(!CAppUtils::RunTortoiseGitProc(cmd
))
1669 m_bSaveRequired
= false;
1673 void CMainFrame::OnUpdateMergeNextconflict(CCmdUI
*pCmdUI
)
1676 if (HasNextConflict(m_pwndBottomView
))
1678 else if (HasNextConflict(m_pwndRightView
))
1680 else if (HasNextConflict(m_pwndLeftView
))
1682 pCmdUI
->Enable(bShow
);
1685 bool CMainFrame::HasNextConflict(CBaseView
* view
)
1689 if (!view
->IsTarget())
1691 return view
->HasNextConflict();
1694 void CMainFrame::OnUpdateMergePreviousconflict(CCmdUI
*pCmdUI
)
1697 if (HasPrevConflict(m_pwndBottomView
))
1699 else if (HasPrevConflict(m_pwndRightView
))
1701 else if (HasPrevConflict(m_pwndLeftView
))
1703 pCmdUI
->Enable(bShow
);
1706 bool CMainFrame::HasPrevConflict(CBaseView
* view
)
1710 if (!view
->IsTarget())
1712 return view
->HasPrevConflict();
1715 void CMainFrame::OnUpdateNavigateNextdifference(CCmdUI
*pCmdUI
)
1717 CBaseView
* baseView
= GetActiveBaseView();
1720 bShow
= baseView
->HasNextDiff();
1721 pCmdUI
->Enable(bShow
);
1724 void CMainFrame::OnUpdateNavigatePreviousdifference(CCmdUI
*pCmdUI
)
1726 CBaseView
* baseView
= GetActiveBaseView();
1729 bShow
= baseView
->HasPrevDiff();
1730 pCmdUI
->Enable(bShow
);
1733 void CMainFrame::OnUpdateNavigateNextinlinediff(CCmdUI
*pCmdUI
)
1736 if (HasNextInlineDiff(m_pwndBottomView
))
1738 else if (HasNextInlineDiff(m_pwndRightView
))
1740 else if (HasNextInlineDiff(m_pwndLeftView
))
1742 pCmdUI
->Enable(bShow
);
1745 bool CMainFrame::HasNextInlineDiff(CBaseView
* view
)
1749 if (!view
->IsTarget())
1751 return view
->HasNextInlineDiff();
1754 void CMainFrame::OnUpdateNavigatePrevinlinediff(CCmdUI
*pCmdUI
)
1757 if (HasPrevInlineDiff(m_pwndBottomView
))
1759 else if (HasPrevInlineDiff(m_pwndRightView
))
1761 else if (HasPrevInlineDiff(m_pwndLeftView
))
1763 pCmdUI
->Enable(bShow
);
1766 bool CMainFrame::HasPrevInlineDiff(CBaseView
* view
)
1770 if (!view
->IsTarget())
1772 return view
->HasPrevInlineDiff();
1775 void CMainFrame::OnMoving(UINT fwSide
, LPRECT pRect
)
1777 // if the pathfilelist dialog is attached to the mainframe,
1778 // move it along with the mainframe
1779 if (::IsWindow(m_dlgFilePatches
.m_hWnd
))
1782 m_dlgFilePatches
.GetWindowRect(&patchrect
);
1783 if (::IsWindow(m_hWnd
))
1786 GetWindowRect(&thisrect
);
1787 if (patchrect
.right
== thisrect
.left
)
1789 m_dlgFilePatches
.SetWindowPos(NULL
, patchrect
.left
- (thisrect
.left
- pRect
->left
), patchrect
.top
- (thisrect
.top
- pRect
->top
),
1790 0, 0, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
| SWP_NOSIZE
| SWP_NOZORDER
);
1794 __super::OnMoving(fwSide
, pRect
);
1797 void CMainFrame::OnUpdateEditCopy(CCmdUI
*pCmdUI
)
1800 if ((m_pwndBottomView
)&&(m_pwndBottomView
->HasSelection()))
1802 else if ((m_pwndRightView
)&&(m_pwndRightView
->HasSelection()))
1804 else if ((m_pwndLeftView
)&&(m_pwndLeftView
->HasSelection()))
1806 pCmdUI
->Enable(bShow
);
1809 void CMainFrame::OnUpdateEditPaste(CCmdUI
*pCmdUI
)
1811 BOOL bWritable
= FALSE
;
1812 if ((m_pwndBottomView
)&&(m_pwndBottomView
->IsWritable()))
1814 else if ((m_pwndRightView
)&&(m_pwndRightView
->IsWritable()))
1816 else if ((m_pwndLeftView
)&&(m_pwndLeftView
->IsWritable()))
1818 pCmdUI
->Enable(bWritable
&& ::IsClipboardFormatAvailable(CF_TEXT
));
1821 void CMainFrame::OnViewSwitchleft()
1824 if (HasUnsavedEdits())
1827 sTemp
.LoadString(IDS_ASKFORSAVE
);
1828 ret
= MessageBox(sTemp
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
1835 if ((ret
== IDNO
)||(ret
== IDYES
))
1837 CWorkingFile file
= m_Data
.m_baseFile
;
1838 m_Data
.m_baseFile
= m_Data
.m_yourFile
;
1839 m_Data
.m_yourFile
= file
;
1840 if (m_Data
.m_mergedFile
.GetFilename().CompareNoCase(m_Data
.m_yourFile
.GetFilename())==0)
1842 m_Data
.m_mergedFile
= m_Data
.m_baseFile
;
1844 else if (m_Data
.m_mergedFile
.GetFilename().CompareNoCase(m_Data
.m_baseFile
.GetFilename())==0)
1846 m_Data
.m_mergedFile
= m_Data
.m_yourFile
;
1852 void CMainFrame::OnUpdateViewSwitchleft(CCmdUI
*pCmdUI
)
1854 BOOL bEnable
= !IsViewGood(m_pwndBottomView
);
1855 pCmdUI
->Enable(bEnable
);
1858 void CMainFrame::OnUpdateViewShowfilelist(CCmdUI
*pCmdUI
)
1860 BOOL bEnable
= m_dlgFilePatches
.HasFiles();
1861 pCmdUI
->Enable(bEnable
);
1862 pCmdUI
->SetCheck(m_dlgFilePatches
.IsWindowVisible());
1865 void CMainFrame::OnViewShowfilelist()
1867 m_dlgFilePatches
.ShowWindow(m_dlgFilePatches
.IsWindowVisible() ? SW_HIDE
: SW_SHOW
);
1870 void CMainFrame::OnEditUndo()
1872 if (CUndo::GetInstance().CanUndo())
1874 CUndo::GetInstance().Undo(m_pwndLeftView
, m_pwndRightView
, m_pwndBottomView
);
1878 void CMainFrame::OnUpdateEditUndo(CCmdUI
*pCmdUI
)
1880 pCmdUI
->Enable(CUndo::GetInstance().CanUndo());
1883 int CMainFrame::CheckForReload()
1885 static bool bLock
= false; //we don't want to check when activated after MessageBox we just created ... this is simple, but we don't need multithread lock
1891 bool bSourceChanged
=
1892 m_Data
.m_baseFile
.HasSourceFileChanged()
1893 || m_Data
.m_yourFile
.HasSourceFileChanged()
1894 || m_Data
.m_theirFile
.HasSourceFileChanged()
1895 /*|| m_Data.m_mergedFile.HasSourceFileChanged()*/;
1896 if (!bSourceChanged
)
1902 int idsMessage
= HasUnsavedEdits() ? IDS_WARNMODIFIEDOUTSIDELOOSECHANGES
: IDS_WARNMODIFIEDOUTSIDE
;
1903 UINT ret
= CMessageBox::Show(m_hWnd
, idsMessage
, IDS_APPNAME
, MB_YESNO
| MB_ICONQUESTION
);
1907 CDiffColors::GetInstance().LoadRegistry();
1912 if (IsViewGood(m_pwndBottomView
)) // three pane view
1914 /*if (m_Data.m_sourceFile.HasSourceFileChanged())
1915 m_pwndBottomView->SetModified();
1916 if (m_Data.m_mergedFile.HasSourceFileChanged())
1917 m_pwndBottomView->SetModified();//*/
1918 if (m_Data
.m_yourFile
.HasSourceFileChanged())
1919 m_pwndRightView
->SetModified();
1920 if (m_Data
.m_theirFile
.HasSourceFileChanged())
1921 m_pwndLeftView
->SetModified();
1923 else if (IsViewGood(m_pwndRightView
)) // two pane view
1925 if (m_Data
.m_baseFile
.HasSourceFileChanged())
1926 m_pwndLeftView
->SetModified();
1927 if (m_Data
.m_yourFile
.HasSourceFileChanged())
1928 m_pwndRightView
->SetModified();
1932 if (m_Data
.m_yourFile
.HasSourceFileChanged())
1933 m_pwndLeftView
->SetModified();
1936 // no reload just store updated file time
1937 m_Data
.m_baseFile
.StoreFileAttributes();
1938 m_Data
.m_theirFile
.StoreFileAttributes();
1939 m_Data
.m_yourFile
.StoreFileAttributes();
1940 //m_Data.m_mergedFile.StoreFileAttributes();
1946 int CMainFrame::CheckForSave()
1949 if (HasUnsavedEdits())
1952 sTemp
.LoadString(IDS_WARNMODIFIEDLOOSECHANGES
);
1953 ret
= MessageBox(sTemp
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
1964 bool CMainFrame::HasUnsavedEdits() const
1966 return HasUnsavedEdits(m_pwndBottomView
) || HasUnsavedEdits(m_pwndRightView
) || m_bSaveRequired
;
1969 bool CMainFrame::HasUnsavedEdits(const CBaseView
* view
)
1973 return view
->IsModified();
1976 bool CMainFrame::IsViewGood(const CBaseView
* view
)
1978 return CBaseView::IsViewGood(view
);
1981 void CMainFrame::OnViewInlinediffword()
1983 m_bInlineWordDiff
= !m_bInlineWordDiff
;
1986 m_pwndLeftView
->SetInlineWordDiff(m_bInlineWordDiff
);
1987 m_pwndLeftView
->BuildAllScreen2ViewVector();
1988 m_pwndLeftView
->DocumentUpdated();
1990 if (m_pwndRightView
)
1992 m_pwndRightView
->SetInlineWordDiff(m_bInlineWordDiff
);
1993 m_pwndRightView
->BuildAllScreen2ViewVector();
1994 m_pwndRightView
->DocumentUpdated();
1996 if (m_pwndBottomView
)
1998 m_pwndBottomView
->SetInlineWordDiff(m_bInlineWordDiff
);
1999 m_pwndBottomView
->BuildAllScreen2ViewVector();
2000 m_pwndBottomView
->DocumentUpdated();
2002 m_wndLineDiffBar
.DocumentUpdated();
2005 void CMainFrame::OnUpdateViewInlinediffword(CCmdUI
*pCmdUI
)
2007 pCmdUI
->Enable(m_bInlineDiff
&& IsViewGood(m_pwndLeftView
) && IsViewGood(m_pwndRightView
));
2008 pCmdUI
->SetCheck(m_bInlineWordDiff
);
2011 void CMainFrame::OnViewInlinediff()
2013 m_bInlineDiff
= !m_bInlineDiff
;
2016 m_pwndLeftView
->SetInlineDiff(m_bInlineDiff
);
2017 m_pwndLeftView
->BuildAllScreen2ViewVector();
2018 m_pwndLeftView
->DocumentUpdated();
2020 if (m_pwndRightView
)
2022 m_pwndRightView
->SetInlineDiff(m_bInlineDiff
);
2023 m_pwndRightView
->BuildAllScreen2ViewVector();
2024 m_pwndRightView
->DocumentUpdated();
2026 if (m_pwndBottomView
)
2028 m_pwndBottomView
->SetInlineDiff(m_bInlineDiff
);
2029 m_pwndBottomView
->BuildAllScreen2ViewVector();
2030 m_pwndBottomView
->DocumentUpdated();
2032 m_wndLineDiffBar
.DocumentUpdated();
2035 void CMainFrame::OnUpdateViewInlinediff(CCmdUI
*pCmdUI
)
2037 pCmdUI
->Enable(IsViewGood(m_pwndLeftView
) && IsViewGood(m_pwndRightView
));
2038 pCmdUI
->SetCheck(m_bInlineDiff
);
2041 void CMainFrame::OnUpdateEditCreateunifieddifffile(CCmdUI
*pCmdUI
)
2043 // "create unified diff file" is only available if two files
2044 // are diffed, not three.
2045 bool bEnabled
= true;
2046 if (!IsViewGood(m_pwndLeftView
))
2048 else if (!IsViewGood(m_pwndRightView
))
2050 else if (IsViewGood(m_pwndBottomView
)) //no negation here
2052 pCmdUI
->Enable(bEnabled
);
2055 void CMainFrame::OnEditCreateunifieddifffile()
2057 CString origFile
, modifiedFile
;
2058 // the original file is the one on the left
2060 origFile
= m_pwndLeftView
->m_sFullFilePath
;
2061 if (m_pwndRightView
)
2062 modifiedFile
= m_pwndRightView
->m_sFullFilePath
;
2063 if (origFile
.IsEmpty() || modifiedFile
.IsEmpty())
2067 if(!TryGetFileName(outputFile
))
2070 CAppUtils::CreateUnifiedDiff(origFile
, modifiedFile
, outputFile
, true);
2073 void CMainFrame::OnUpdateViewLinediffbar(CCmdUI
*pCmdUI
)
2075 pCmdUI
->SetCheck(m_bLineDiff
);
2079 void CMainFrame::OnViewLinediffbar()
2081 m_bLineDiff
= !m_bLineDiff
;
2082 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
2083 m_wndLineDiffBar
.DocumentUpdated();
2084 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
2085 m_wndLocatorBar
.DocumentUpdated();
2088 void CMainFrame::OnUpdateViewLocatorbar(CCmdUI
*pCmdUI
)
2090 pCmdUI
->SetCheck(m_bLocatorBar
);
2094 void CMainFrame::OnViewLocatorbar()
2096 m_bLocatorBar
= !m_bLocatorBar
;
2097 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
2098 m_wndLocatorBar
.DocumentUpdated();
2099 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
2100 m_wndLineDiffBar
.DocumentUpdated();
2103 void CMainFrame::OnViewComparewhitespaces()
2105 if (CheckForSave()==IDCANCEL
)
2107 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2112 void CMainFrame::OnUpdateViewComparewhitespaces(CCmdUI
*pCmdUI
)
2114 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2115 DWORD dwIgnoreWS
= regIgnoreWS
;
2116 pCmdUI
->SetCheck(dwIgnoreWS
== 0);
2119 void CMainFrame::OnViewIgnorewhitespacechanges()
2121 if (CheckForSave()==IDCANCEL
)
2123 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2128 void CMainFrame::OnUpdateViewIgnorewhitespacechanges(CCmdUI
*pCmdUI
)
2130 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2131 DWORD dwIgnoreWS
= regIgnoreWS
;
2132 pCmdUI
->SetCheck(dwIgnoreWS
== 2);
2135 void CMainFrame::OnViewIgnoreallwhitespacechanges()
2137 if (CheckForSave()==IDCANCEL
)
2139 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2144 void CMainFrame::OnUpdateViewIgnoreallwhitespacechanges(CCmdUI
*pCmdUI
)
2146 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2147 DWORD dwIgnoreWS
= regIgnoreWS
;
2148 pCmdUI
->SetCheck(dwIgnoreWS
== 1);
2151 void CMainFrame::OnViewMovedBlocks()
2153 m_bViewMovedBlocks
= !(DWORD
)m_regViewModedBlocks
;
2154 m_regViewModedBlocks
= m_bViewMovedBlocks
;
2158 void CMainFrame::OnUpdateViewMovedBlocks(CCmdUI
*pCmdUI
)
2160 pCmdUI
->SetCheck(m_bViewMovedBlocks
);
2161 BOOL bEnable
= TRUE
;
2162 if (IsViewGood(m_pwndBottomView
))
2166 pCmdUI
->Enable(bEnable
);
2169 bool CMainFrame::HasConflictsWontKeep()
2171 const int nConflictLine
= CheckResolved();
2172 if (nConflictLine
< 0)
2176 sTemp
.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS
, m_pwndBottomView
->m_pViewData
->GetLineNumber(nConflictLine
)+1);
2177 if (MessageBox(sTemp
, 0, MB_ICONERROR
| MB_YESNO
)==IDYES
)
2180 if (m_pwndBottomView
)
2181 m_pwndBottomView
->GoToLine(nConflictLine
);
2185 bool CMainFrame::TryGetFileName(CString
& result
)
2187 return CCommonAppUtils::FileOpenSave(result
, NULL
, IDS_SAVEASTITLE
, IDS_COMMONFILEFILTER
, false, m_hWnd
);
2190 CBaseView
* CMainFrame::GetActiveBaseView() const
2192 CView
* activeView
= GetActiveView();
2193 CBaseView
* activeBase
= dynamic_cast<CBaseView
*>( activeView
);
2197 void CMainFrame::SetWindowTitle()
2199 // try to find a suitable window title
2200 CString sYour
= m_Data
.m_yourFile
.GetDescriptiveName();
2201 if (sYour
.Find(_T(" - "))>=0)
2202 sYour
= sYour
.Left(sYour
.Find(_T(" - ")));
2203 if (sYour
.Find(_T(" : "))>=0)
2204 sYour
= sYour
.Left(sYour
.Find(_T(" : ")));
2205 CString sTheir
= m_Data
.m_theirFile
.GetDescriptiveName();
2206 if (sTheir
.IsEmpty())
2207 sTheir
= m_Data
.m_baseFile
.GetDescriptiveName();
2208 if (sTheir
.Find(_T(" - "))>=0)
2209 sTheir
= sTheir
.Left(sTheir
.Find(_T(" - ")));
2210 if (sTheir
.Find(_T(" : "))>=0)
2211 sTheir
= sTheir
.Left(sTheir
.Find(_T(" : ")));
2213 if (!sYour
.IsEmpty() && !sTheir
.IsEmpty())
2215 if (sYour
.CompareNoCase(sTheir
)==0)
2216 SetWindowText(sYour
+ _T(" - TortoiseGitMerge"));
2217 else if ((sYour
.GetLength() < 10) &&
2218 (sTheir
.GetLength() < 10))
2219 SetWindowText(sYour
+ _T(" - ") + sTheir
+ _T(" - TortoiseGitMerge"));
2222 // we have two very long descriptive texts here, which
2223 // means we have to find a way to use them as a window
2224 // title in a shorter way.
2225 // for simplicity, we just use the one from "yourfile"
2226 SetWindowText(sYour
+ _T(" - TortoiseGitMerge"));
2229 else if (!sYour
.IsEmpty())
2230 SetWindowText(sYour
+ _T(" - TortoiseGitMerge"));
2231 else if (!sTheir
.IsEmpty())
2232 SetWindowText(sTheir
+ _T(" - TortoiseGitMerge"));
2234 SetWindowText(L
"TortoiseGitMerge");