1 // TortoiseMerge - a Diff/Patch program
3 // Copyright (C) 2008-2012 - TortoiseGit
4 // Copyright (C) 2012 - Sven Strickroth <email@cs-ware.de>
5 // Copyright (C) 2004-2009 - TortoiseSVN
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"
25 #include "SysProgressDlg.h"
27 #include "MessageBox.h"
29 #include "PathUtils.h"
32 #include "RightView.h"
33 #include "BottomView.h"
34 #include "DiffColors.h"
35 #include ".\mainfrm.h"
36 #include "FormatMessageWrapper.h"
37 #include "EditGotoDlg.h"
45 const UINT
CMainFrame::m_FindDialogMessage
= RegisterWindowMessage(FINDMSGSTRING
);
47 IMPLEMENT_DYNCREATE(CMainFrame
, CFrameWndEx
)
49 BEGIN_MESSAGE_MAP(CMainFrame
, CFrameWndEx
)
51 ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000
, ID_VIEW_APPLOOK_OFF_2007_AQUA
, &CMainFrame::OnApplicationLook
)
52 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000
, ID_VIEW_APPLOOK_OFF_2007_AQUA
, &CMainFrame::OnUpdateApplicationLook
)
53 // Global help commands
54 ON_COMMAND(ID_HELP_FINDER
, CFrameWndEx::OnHelpFinder
)
55 ON_COMMAND(ID_HELP
, CFrameWndEx::OnHelp
)
56 ON_COMMAND(ID_CONTEXT_HELP
, CFrameWndEx::OnContextHelp
)
57 ON_COMMAND(ID_DEFAULT_HELP
, CFrameWndEx::OnHelpFinder
)
58 ON_COMMAND(ID_FILE_OPEN
, OnFileOpen
)
59 ON_COMMAND(ID_VIEW_WHITESPACES
, OnViewWhitespaces
)
61 ON_COMMAND(ID_FILE_SAVE
, OnFileSave
)
62 ON_COMMAND(ID_FILE_SAVE_AS
, OnFileSaveAs
)
63 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE
, OnUpdateFileSave
)
64 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS
, OnUpdateFileSaveAs
)
65 ON_COMMAND(ID_VIEW_ONEWAYDIFF
, OnViewOnewaydiff
)
66 ON_UPDATE_COMMAND_UI(ID_VIEW_ONEWAYDIFF
, OnUpdateViewOnewaydiff
)
67 ON_UPDATE_COMMAND_UI(ID_VIEW_WHITESPACES
, OnUpdateViewWhitespaces
)
68 ON_COMMAND(ID_VIEW_OPTIONS
, OnViewOptions
)
70 ON_COMMAND(ID_EDIT_FIND
, OnEditFind
)
71 ON_REGISTERED_MESSAGE(m_FindDialogMessage
, OnFindDialogMessage
)
72 ON_COMMAND(ID_EDIT_FINDNEXT
, OnEditFindnext
)
73 ON_COMMAND(ID_EDIT_FINDPREV
, OnEditFindprev
)
74 ON_COMMAND(ID_EDIT_GOTO
, OnEditGoto
)
75 ON_COMMAND(ID_FILE_RELOAD
, OnFileReload
)
76 ON_COMMAND(ID_VIEW_LINEDOWN
, OnViewLinedown
)
77 ON_COMMAND(ID_VIEW_LINEUP
, OnViewLineup
)
78 ON_UPDATE_COMMAND_UI(ID_EDIT_MARKASRESOLVED
, OnUpdateMergeMarkasresolved
)
79 ON_COMMAND(ID_EDIT_MARKASRESOLVED
, OnMergeMarkasresolved
)
80 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTCONFLICT
, OnUpdateMergeNextconflict
)
81 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSCONFLICT
, OnUpdateMergePreviousconflict
)
84 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY
, OnUpdateEditCopy
)
85 ON_COMMAND(ID_VIEW_SWITCHLEFT
, OnViewSwitchleft
)
86 ON_UPDATE_COMMAND_UI(ID_VIEW_SWITCHLEFT
, OnUpdateViewSwitchleft
)
87 ON_COMMAND(ID_VIEW_LINELEFT
, &CMainFrame::OnViewLineleft
)
88 ON_COMMAND(ID_VIEW_LINERIGHT
, &CMainFrame::OnViewLineright
)
89 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILELIST
, &CMainFrame::OnUpdateViewShowfilelist
)
90 ON_COMMAND(ID_VIEW_SHOWFILELIST
, &CMainFrame::OnViewShowfilelist
)
91 ON_COMMAND(ID_EDIT_USETHEIRBLOCK
, &CMainFrame::OnEditUseTheirs
)
92 ON_COMMAND(ID_EDIT_USEMYBLOCK
, &CMainFrame::OnEditUseMine
)
93 ON_COMMAND(ID_EDIT_USETHEIRTHENMYBLOCK
, &CMainFrame::OnEditUseTheirsThenMine
)
94 ON_COMMAND(ID_EDIT_USEMINETHENTHEIRBLOCK
, &CMainFrame::OnEditUseMineThenTheirs
)
95 ON_COMMAND(ID_EDIT_UNDO
, &CMainFrame::OnEditUndo
)
96 ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO
, &CMainFrame::OnUpdateEditUndo
)
97 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMINETHENTHEIRBLOCK
, &CMainFrame::OnUpdateEditUseminethentheirblock
)
98 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMYBLOCK
, &CMainFrame::OnUpdateEditUsemyblock
)
99 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRBLOCK
, &CMainFrame::OnUpdateEditUsetheirblock
)
100 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRTHENMYBLOCK
, &CMainFrame::OnUpdateEditUsetheirthenmyblock
)
101 ON_COMMAND(ID_VIEW_INLINEDIFFWORD
, &CMainFrame::OnViewInlinediffword
)
102 ON_UPDATE_COMMAND_UI(ID_VIEW_INLINEDIFFWORD
, &CMainFrame::OnUpdateViewInlinediffword
)
103 ON_UPDATE_COMMAND_UI(ID_EDIT_CREATEUNIFIEDDIFFFILE
, &CMainFrame::OnUpdateEditCreateunifieddifffile
)
104 ON_COMMAND(ID_EDIT_CREATEUNIFIEDDIFFFILE
, &CMainFrame::OnEditCreateunifieddifffile
)
105 ON_UPDATE_COMMAND_UI(ID_VIEW_LINEDIFFBAR
, &CMainFrame::OnUpdateViewLinediffbar
)
106 ON_COMMAND(ID_VIEW_LINEDIFFBAR
, &CMainFrame::OnViewLinediffbar
)
107 ON_UPDATE_COMMAND_UI(ID_VIEW_LOCATORBAR
, &CMainFrame::OnUpdateViewLocatorbar
)
108 ON_COMMAND(ID_VIEW_LOCATORBAR
, &CMainFrame::OnViewLocatorbar
)
109 ON_COMMAND(ID_EDIT_USELEFTBLOCK
, &CMainFrame::OnEditUseleftblock
)
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
)
119 static UINT indicators
[] =
121 ID_SEPARATOR
, // status line indicator
122 ID_INDICATOR_LEFTVIEW
,
123 ID_INDICATOR_RIGHTVIEW
,
124 ID_INDICATOR_BOTTOMVIEW
,
131 // CMainFrame construction/destruction
133 CMainFrame::CMainFrame()
134 : m_pFindDialog(NULL
)
136 , m_bInitSplitter(FALSE
)
137 , m_bReversedPatch(FALSE
)
138 , m_bHasConflicts(false)
139 , m_bInlineWordDiff(true)
141 , m_bLocatorBar(true)
142 , m_nMoveMovesToIgnore(0)
143 , m_bLimitToDiff(false)
144 , m_bWholeWord(false)
145 , m_pwndLeftView(NULL
)
146 , m_pwndRightView(NULL
)
147 , m_pwndBottomView(NULL
)
151 m_bOneWay
= (0 != ((DWORD
)CRegDWORD(_T("Software\\TortoiseMerge\\OnePane"))));
152 theApp
.m_nAppLook
= theApp
.GetInt(_T("ApplicationLook"), ID_VIEW_APPLOOK_VS_2005
);
155 CMainFrame::~CMainFrame()
159 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct
)
161 if (CFrameWndEx::OnCreate(lpCreateStruct
) == -1)
164 OnApplicationLook(theApp
.m_nAppLook
);
166 if (!m_wndMenuBar
.Create(this))
168 TRACE0("Failed to create menubar\n");
169 return -1; // fail to create
172 m_wndMenuBar
.SetPaneStyle(m_wndMenuBar
.GetPaneStyle() | CBRS_SIZE_DYNAMIC
| CBRS_TOOLTIPS
| CBRS_FLYBY
);
174 // prevent the menu bar from taking the focus on activation
175 CMFCPopupMenu::SetForceMenuFocus(FALSE
);
177 if (!m_wndToolBar
.CreateEx(this, TBSTYLE_FLAT
, WS_CHILD
| WS_VISIBLE
| CBRS_ALIGN_TOP
| CBRS_GRIPPER
| CBRS_TOOLTIPS
| CBRS_FLYBY
) ||
178 !m_wndToolBar
.LoadToolBar(IDR_MAINFRAME
))
180 TRACE0("Failed to create toolbar\n");
181 return -1; // fail to create
183 m_wndToolBar
.SetWindowText(_T("Main"));
185 if (!m_wndStatusBar
.Create(this) ||
186 !m_wndStatusBar
.SetIndicators(indicators
,
187 _countof(indicators
)))
189 TRACE0("Failed to create status bar\n");
190 return -1; // fail to create
193 if (!m_wndLocatorBar
.Create(this, IDD_DIFFLOCATOR
,
194 CBRS_ALIGN_LEFT
| CBRS_SIZE_FIXED
, ID_VIEW_LOCATORBAR
))
196 TRACE0("Failed to create dialogbar\n");
197 return -1; // fail to create
199 if (!m_wndLineDiffBar
.Create(this, IDD_LINEDIFF
,
200 CBRS_ALIGN_BOTTOM
| CBRS_SIZE_FIXED
, ID_VIEW_LINEDIFFBAR
))
202 TRACE0("Failed to create dialogbar\n");
203 return -1; // fail to create
205 m_wndLocatorBar
.m_pMainFrm
= this;
206 m_wndLineDiffBar
.m_pMainFrm
= this;
208 EnableDocking(CBRS_ALIGN_ANY
);
209 m_wndMenuBar
.EnableDocking(CBRS_ALIGN_TOP
);
210 m_wndToolBar
.EnableDocking(CBRS_ALIGN_TOP
);
211 DockPane(&m_wndMenuBar
);
212 DockPane(&m_wndToolBar
);
213 DockPane(&m_wndLocatorBar
);
214 DockPane(&m_wndLineDiffBar
);
215 ShowPane(&m_wndLocatorBar
, true, false, true);
216 ShowPane(&m_wndLineDiffBar
, true, false, true);
218 m_wndLocatorBar
.EnableGripper(FALSE
);
219 m_wndLineDiffBar
.EnableGripper(FALSE
);
224 BOOL
CMainFrame::PreCreateWindow(CREATESTRUCT
& cs
)
226 if( !CFrameWndEx::PreCreateWindow(cs
) )
231 void CMainFrame::OnApplicationLook(UINT id
)
235 theApp
.m_nAppLook
= id
;
237 switch (theApp
.m_nAppLook
)
239 case ID_VIEW_APPLOOK_WIN_2000
:
240 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager
));
243 case ID_VIEW_APPLOOK_OFF_XP
:
244 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP
));
247 case ID_VIEW_APPLOOK_WIN_XP
:
248 CMFCVisualManagerWindows::m_b3DTabsXPTheme
= TRUE
;
249 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows
));
252 case ID_VIEW_APPLOOK_OFF_2003
:
253 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003
));
254 CDockingManager::SetDockingMode(DT_SMART
);
257 case ID_VIEW_APPLOOK_VS_2005
:
258 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005
));
259 CDockingManager::SetDockingMode(DT_SMART
);
263 switch (theApp
.m_nAppLook
)
265 case ID_VIEW_APPLOOK_OFF_2007_BLUE
:
266 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue
);
269 case ID_VIEW_APPLOOK_OFF_2007_BLACK
:
270 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack
);
273 case ID_VIEW_APPLOOK_OFF_2007_SILVER
:
274 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver
);
277 case ID_VIEW_APPLOOK_OFF_2007_AQUA
:
278 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua
);
282 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007
));
283 CDockingManager::SetDockingMode(DT_SMART
);
286 RedrawWindow(NULL
, NULL
, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_FRAME
| RDW_ERASE
);
288 theApp
.WriteInt(_T("ApplicationLook"), theApp
.m_nAppLook
);
291 void CMainFrame::OnUpdateApplicationLook(CCmdUI
* pCmdUI
)
293 pCmdUI
->SetRadio(theApp
.m_nAppLook
== pCmdUI
->m_nID
);
297 // CMainFrame diagnostics
300 void CMainFrame::AssertValid() const
302 CFrameWndEx::AssertValid();
305 void CMainFrame::Dump(CDumpContext
& dc
) const
307 CFrameWndEx::Dump(dc
);
313 // CMainFrame message handlers
316 BOOL
CMainFrame::OnCreateClient(LPCREATESTRUCT
/*lpcs*/, CCreateContext
* pContext
)
322 // split into three panes:
331 // create a splitter with 2 rows, 1 column
332 if (!m_wndSplitter
.CreateStatic(this, 2, 1))
334 TRACE0("Failed to CreateStaticSplitter\n");
338 // add the second splitter pane - which is a nested splitter with 2 columns
339 if (!m_wndSplitter2
.CreateStatic(
340 &m_wndSplitter
, // our parent window is the first splitter
341 1, 2, // the new splitter is 1 row, 2 columns
342 WS_CHILD
| WS_VISIBLE
| WS_BORDER
, // style, WS_BORDER is needed
343 m_wndSplitter
.IdFromRowCol(0, 0)
344 // new splitter is in the first row, 1st column of first splitter
347 TRACE0("Failed to create nested splitter\n");
350 // add the first splitter pane - the default view in row 0
351 if (!m_wndSplitter
.CreateView(1, 0,
352 RUNTIME_CLASS(CBottomView
), CSize(cr
.Width(), cr
.Height()), pContext
))
354 TRACE0("Failed to create first pane\n");
357 m_pwndBottomView
= (CBottomView
*)m_wndSplitter
.GetPane(1,0);
358 m_pwndBottomView
->m_pwndLocator
= &m_wndLocatorBar
;
359 m_pwndBottomView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
360 m_pwndBottomView
->m_pwndStatusBar
= &m_wndStatusBar
;
361 m_pwndBottomView
->m_pMainFrame
= this;
363 // now create the two views inside the nested splitter
365 if (!m_wndSplitter2
.CreateView(0, 0,
366 RUNTIME_CLASS(CLeftView
), CSize(cr
.Width()/2, cr
.Height()/2), pContext
))
368 TRACE0("Failed to create second pane\n");
371 m_pwndLeftView
= (CLeftView
*)m_wndSplitter2
.GetPane(0,0);
372 m_pwndLeftView
->m_pwndLocator
= &m_wndLocatorBar
;
373 m_pwndLeftView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
374 m_pwndLeftView
->m_pwndStatusBar
= &m_wndStatusBar
;
375 m_pwndLeftView
->m_pMainFrame
= this;
377 if (!m_wndSplitter2
.CreateView(0, 1,
378 RUNTIME_CLASS(CRightView
), CSize(cr
.Width()/2, cr
.Height()/2), pContext
))
380 TRACE0("Failed to create third pane\n");
383 m_pwndRightView
= (CRightView
*)m_wndSplitter2
.GetPane(0,1);
384 m_pwndRightView
->m_pwndLocator
= &m_wndLocatorBar
;
385 m_pwndRightView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
386 m_pwndRightView
->m_pwndStatusBar
= &m_wndStatusBar
;
387 m_pwndRightView
->m_pMainFrame
= this;
388 m_bInitSplitter
= TRUE
;
390 m_dlgFilePatches
.Create(IDD_FILEPATCHES
, this);
396 BOOL
CMainFrame::PatchFile(int nIndex
, bool bAutoPatch
, bool bIsReview
)
398 CString Path2
= m_Patch
.GetFullPath(m_Data
.m_sPatchPath
, nIndex
, 1);
399 CString sFilePath
= m_Patch
.GetFullPath(m_Data
.m_sPatchPath
, nIndex
);
400 //first, do a "dry run" of patching...
401 if (!m_Patch
.PatchFile(nIndex
, m_Data
.m_sPatchPath
))
403 //patching not successful, so retrieve the
404 //base file from version control and try
406 CString sVersion
= m_Patch
.GetRevision(nIndex
);
409 if (sVersion
== _T("0000000") || sFilePath
== _T("NUL"))
410 sBaseFile
= m_TempFiles
.GetTempFilePath();
413 CSysProgressDlg progDlg
;
415 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sVersion
);
416 progDlg
.SetLine(1, sTemp
, true);
417 progDlg
.SetLine(2, sFilePath
, true);
418 sTemp
.LoadString(IDS_GETVERSIONOFFILETITLE
);
419 progDlg
.SetTitle(sTemp
);
420 progDlg
.SetShowProgressBar(false);
421 progDlg
.SetAnimation(IDR_DOWNLOAD
);
422 progDlg
.SetTime(FALSE
);
424 if(!m_Patch
.m_IsGitPatch
)
425 progDlg
.ShowModeless(this);
427 sBaseFile
= m_TempFiles
.GetTempFilePath();
428 if (!CAppUtils::GetVersionedFile(sFilePath
, sVersion
, sBaseFile
, &progDlg
, m_hWnd
))
432 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sVersion
, (LPCTSTR
)sFilePath
);
433 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
440 CString sTempFile
= m_TempFiles
.GetTempFilePath();
441 if (!m_Patch
.PatchFile(nIndex
, m_Data
.m_sPatchPath
, sTempFile
, sBaseFile
, true))
443 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
448 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)sVersion
);
449 m_Data
.m_baseFile
.SetFileName(sBaseFile
);
450 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
451 if(!Path2
.IsEmpty() && Path2
!= _T("NUL"))
452 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(Path2
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
454 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
456 if (sVersion
== _T("0000000") || sFilePath
== _T("NUL"))
458 m_Data
.m_baseFile
.SetFileName(Path2
);
459 m_Data
.m_yourFile
.SetFileName(Path2
);
460 m_Data
.m_theirFile
.SetFileName(sTempFile
);
461 m_Data
.m_theirFile
.SetDescriptiveName(CPathUtils::GetFileNameFromPath(Path2
));
462 m_Data
.m_mergedFile
.SetFileName(Path2
);
471 m_Data
.m_yourFile
.SetFileName(sTempFile
);
472 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
473 m_Data
.m_theirFile
.SetOutOfUse();
474 m_Data
.m_mergedFile
.SetOutOfUse();
478 m_Data
.m_theirFile
.SetFileName(sTempFile
);
479 m_Data
.m_theirFile
.SetDescriptiveName(temp
);
480 m_Data
.m_yourFile
.SetFileName(sFilePath
);
481 m_Data
.m_yourFile
.SetDescriptiveName(CPathUtils::GetFileNameFromPath(sFilePath
));
482 m_Data
.m_mergedFile
.SetFileName(sFilePath
);
483 m_Data
.m_mergedFile
.SetDescriptiveName(CPathUtils::GetFileNameFromPath(sFilePath
));
485 TRACE(_T("comparing %s and %s\nagainst the base file %s\n"), (LPCTSTR
)sTempFile
, (LPCTSTR
)sFilePath
, (LPCTSTR
)sBaseFile
);
491 //"dry run" was successful, so save the patched file somewhere...
492 CString sTempFile
= m_TempFiles
.GetTempFilePath();
493 if (!m_Patch
.PatchFile(nIndex
, m_Data
.m_sPatchPath
, sTempFile
))
495 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
498 if (m_bReversedPatch
)
500 m_Data
.m_baseFile
.SetFileName(sTempFile
);
502 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
503 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
504 m_Data
.m_yourFile
.SetFileName(sFilePath
);
505 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchOriginal
);
506 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
507 m_Data
.m_theirFile
.SetOutOfUse();
508 m_Data
.m_mergedFile
.SetOutOfUse();
512 if (!PathFileExists(sFilePath
))
514 m_Data
.m_baseFile
.SetFileName(m_TempFiles
.GetTempFilePath());
515 m_Data
.m_baseFile
.CreateEmptyFile();
519 m_Data
.m_baseFile
.SetFileName(sFilePath
);
521 CString sDescription
;
522 sDescription
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchOriginal
);
523 m_Data
.m_baseFile
.SetDescriptiveName(sDescription
);
524 m_Data
.m_yourFile
.SetFileName(sTempFile
);
526 if (!Path2
.IsEmpty() && Path2
!= _T("NUL"))
528 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(Path2
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
529 m_Data
.m_mergedFile
.SetFileName(Path2
);
533 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
534 m_Data
.m_mergedFile
.SetFileName(sFilePath
);
537 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
538 m_Data
.m_theirFile
.SetOutOfUse();
540 TRACE(_T("comparing %s\nwith the patched result %s\n"), (LPCTSTR
)sFilePath
, (LPCTSTR
)sTempFile
);
551 BOOL
CMainFrame::DiffFiles(CString sURL1
, CString sRev1
, CString sURL2
, CString sRev2
)
553 CString tempfile1
= m_TempFiles
.GetTempFilePath();
554 CString tempfile2
= m_TempFiles
.GetTempFilePath();
556 ASSERT(tempfile1
.Compare(tempfile2
));
559 CSysProgressDlg progDlg
;
560 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sRev1
);
561 progDlg
.SetLine(1, sTemp
, true);
562 progDlg
.SetLine(2, sURL1
, true);
563 sTemp
.LoadString(IDS_GETVERSIONOFFILETITLE
);
564 progDlg
.SetTitle(sTemp
);
565 progDlg
.SetShowProgressBar(true);
566 progDlg
.SetAnimation(IDR_DOWNLOAD
);
567 progDlg
.SetTime(FALSE
);
568 progDlg
.SetProgress(1,100);
569 progDlg
.ShowModeless(this);
570 if (!CAppUtils::GetVersionedFile(sURL1
, sRev1
, tempfile1
, &progDlg
, m_hWnd
))
574 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sRev1
, (LPCTSTR
)sURL1
);
575 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
578 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sRev2
);
579 progDlg
.SetLine(1, sTemp
, true);
580 progDlg
.SetLine(2, sURL2
, true);
581 progDlg
.SetProgress(50, 100);
582 if (!CAppUtils::GetVersionedFile(sURL2
, sRev2
, tempfile2
, &progDlg
, m_hWnd
))
586 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sRev2
, (LPCTSTR
)sURL2
);
587 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
590 progDlg
.SetProgress(100,100);
593 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sURL1
), (LPCTSTR
)sRev1
);
594 m_Data
.m_baseFile
.SetFileName(tempfile1
);
595 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
596 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sURL2
), (LPCTSTR
)sRev2
);
597 m_Data
.m_yourFile
.SetFileName(tempfile2
);
598 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
605 void CMainFrame::OnFileOpen()
607 if (CheckForSave()==IDCANCEL
)
610 if (dlg
.DoModal()!=IDOK
)
614 m_dlgFilePatches
.ShowWindow(SW_HIDE
);
615 m_dlgFilePatches
.Init(NULL
, NULL
, CString(), NULL
);
616 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
,
617 (LPCTSTR
)dlg
.m_sUnifiedDiffFile
, (LPCTSTR
)dlg
.m_sPatchDirectory
);
618 m_Data
.m_baseFile
.SetFileName(dlg
.m_sBaseFile
);
619 m_Data
.m_theirFile
.SetFileName(dlg
.m_sTheirFile
);
620 m_Data
.m_yourFile
.SetFileName(dlg
.m_sYourFile
);
621 m_Data
.m_sDiffFile
= dlg
.m_sUnifiedDiffFile
;
622 m_Data
.m_sPatchPath
= dlg
.m_sPatchDirectory
;
623 m_Data
.m_mergedFile
.SetOutOfUse();
624 CCrashReport::Instance().AddFile2(dlg
.m_sBaseFile
, NULL
, _T("Basefile"), CR_AF_MAKE_FILE_COPY
);
625 CCrashReport::Instance().AddFile2(dlg
.m_sTheirFile
, NULL
, _T("Theirfile"), CR_AF_MAKE_FILE_COPY
);
626 CCrashReport::Instance().AddFile2(dlg
.m_sYourFile
, NULL
, _T("Yourfile"), CR_AF_MAKE_FILE_COPY
);
627 CCrashReport::Instance().AddFile2(dlg
.m_sUnifiedDiffFile
, NULL
, _T("Difffile"), CR_AF_MAKE_FILE_COPY
);
629 if (!m_Data
.IsBaseFileInUse() && m_Data
.IsTheirFileInUse() && m_Data
.IsYourFileInUse())
631 // a diff between two files means "Yours" against "Base", not "Theirs" against "Yours"
632 m_Data
.m_baseFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
634 if (m_Data
.IsBaseFileInUse() && m_Data
.IsTheirFileInUse() && !m_Data
.IsYourFileInUse())
636 // a diff between two files means "Yours" against "Base", not "Theirs" against "Base"
637 m_Data
.m_yourFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
643 void CMainFrame::ClearViewNamesAndPaths() {
644 m_pwndLeftView
->m_sWindowName
.Empty();
645 m_pwndLeftView
->m_sFullFilePath
.Empty();
646 m_pwndRightView
->m_sWindowName
.Empty();
647 m_pwndRightView
->m_sFullFilePath
.Empty();
648 m_pwndBottomView
->m_sWindowName
.Empty();
649 m_pwndBottomView
->m_sFullFilePath
.Empty();
652 bool CMainFrame::LoadViews(bool bRetainPosition
)
654 m_Data
.SetBlame(m_bBlame
);
655 m_bHasConflicts
= false;
656 CBaseView
* pwndActiveView
= m_pwndLeftView
;
657 int nOldLine
= m_pwndLeftView
? m_pwndLeftView
->m_nTopLine
: -1;
659 m_pwndLeftView
&& m_pwndLeftView
->m_pViewData
?
660 m_pwndLeftView
->m_pViewData
->GetLineNumber(m_pwndLeftView
->m_nTopLine
) : -1;
663 ::MessageBox(NULL
, m_Data
.GetError(), _T("TortoiseMerge"), MB_ICONERROR
);
664 m_Data
.m_mergedFile
.SetOutOfUse();
668 m_pwndRightView
->UseCaret(false);
669 m_pwndBottomView
->UseCaret(false);
671 if (!m_Data
.IsBaseFileInUse())
673 if (m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
675 m_Data
.m_baseFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
677 else if ((!m_Data
.m_sDiffFile
.IsEmpty())&&(!m_Patch
.OpenUnifiedDiffFile(m_Data
.m_sDiffFile
)))
679 ClearViewNamesAndPaths();
680 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
683 if (m_Patch
.GetNumberOfFiles() > 0)
685 CString firstpath
= m_Patch
.GetFilename(0);
686 CString path
=firstpath
;
687 path
.Replace('/','\\');
688 if ( !PathIsRelative(path
) && !PathFileExists(path
) )
690 // The absolute path mentioned in the patch does not exist. Lets
691 // try to find the correct relative path by stripping prefixes.
692 BOOL bFound
= m_Patch
.StripPrefixes(m_Data
.m_sPatchPath
);
693 CString strippedpath
= m_Patch
.GetFilename(0);
697 msg
.Format(IDS_WARNABSOLUTEPATHFOUND
, (LPCTSTR
)firstpath
, (LPCTSTR
)strippedpath
);
698 if (CMessageBox::Show(m_hWnd
, msg
, _T("TortoiseMerge"), MB_ICONQUESTION
| MB_YESNO
)==IDNO
)
704 msg
.Format(IDS_WARNABSOLUTEPATHNOTFOUND
, (LPCTSTR
)firstpath
);
705 CMessageBox::Show(m_hWnd
, msg
, _T("TortoiseMerge"), MB_ICONEXCLAMATION
);
709 CString betterpatchpath
= m_Patch
.CheckPatchPath(m_Data
.m_sPatchPath
);
710 if (betterpatchpath
.CompareNoCase(m_Data
.m_sPatchPath
)!=0)
713 msg
.Format(IDS_WARNBETTERPATCHPATHFOUND
, (LPCTSTR
)m_Data
.m_sPatchPath
, (LPCTSTR
)betterpatchpath
);
714 if (CMessageBox::Show(m_hWnd
, msg
, _T("TortoiseMerge"), MB_ICONQUESTION
| MB_YESNO
)==IDYES
)
715 m_Data
.m_sPatchPath
= betterpatchpath
;
717 m_dlgFilePatches
.Init(&m_Patch
, this, m_Data
.m_sPatchPath
, this);
718 m_dlgFilePatches
.ShowWindow(SW_SHOW
);
719 ClearViewNamesAndPaths();
720 if (!m_wndSplitter
.IsRowHidden(1))
721 m_wndSplitter
.HideRow(1);
722 m_pwndLeftView
->SetHidden(FALSE
);
723 m_pwndRightView
->SetHidden(FALSE
);
724 m_pwndBottomView
->SetHidden(TRUE
);
727 if (m_Data
.IsBaseFileInUse() && !m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
729 m_Data
.m_yourFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
731 if (m_Data
.IsBaseFileInUse() && m_Data
.IsYourFileInUse() && !m_Data
.IsTheirFileInUse())
733 //diff between YOUR and BASE
734 m_pwndRightView
->UseCaret();
737 if (!m_wndSplitter2
.IsColumnHidden(1))
738 m_wndSplitter2
.HideColumn(1);
740 m_pwndLeftView
->m_pViewData
= &m_Data
.m_YourBaseBoth
;
741 m_pwndLeftView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
742 m_pwndLeftView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
743 m_pwndLeftView
->m_sWindowName
= m_Data
.m_baseFile
.GetWindowName() + _T(" - ") + m_Data
.m_yourFile
.GetWindowName();
744 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_baseFile
.GetFilename() + _T(" - ") + m_Data
.m_yourFile
.GetFilename();
746 m_pwndRightView
->m_pViewData
= NULL
;
747 m_pwndBottomView
->m_pViewData
= NULL
;
749 if (!m_wndSplitter
.IsRowHidden(1))
750 m_wndSplitter
.HideRow(1);
751 m_pwndLeftView
->SetHidden(FALSE
);
752 m_pwndRightView
->SetHidden(TRUE
);
753 m_pwndBottomView
->SetHidden(TRUE
);
754 ::SetWindowPos(m_pwndLeftView
->m_hWnd
, NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
758 pwndActiveView
= m_pwndRightView
;
759 if (m_wndSplitter2
.IsColumnHidden(1))
760 m_wndSplitter2
.ShowColumn();
762 m_pwndLeftView
->m_pViewData
= &m_Data
.m_YourBaseLeft
;
763 m_pwndLeftView
->texttype
= m_Data
.m_arBaseFile
.GetUnicodeType();
764 m_pwndLeftView
->lineendings
= m_Data
.m_arBaseFile
.GetLineEndings();
765 m_pwndLeftView
->m_sWindowName
= m_Data
.m_baseFile
.GetWindowName();
766 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_baseFile
.GetFilename();
768 m_pwndRightView
->m_pViewData
= &m_Data
.m_YourBaseRight
;
769 m_pwndRightView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
770 m_pwndRightView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
771 m_pwndRightView
->m_sWindowName
= m_Data
.m_yourFile
.GetWindowName();
772 m_pwndRightView
->m_sFullFilePath
= m_Data
.m_yourFile
.GetFilename();
774 m_pwndBottomView
->m_pViewData
= NULL
;
776 if (!m_wndSplitter
.IsRowHidden(1))
777 m_wndSplitter
.HideRow(1);
778 m_pwndLeftView
->SetHidden(FALSE
);
779 m_pwndRightView
->SetHidden(FALSE
);
780 m_pwndBottomView
->SetHidden(TRUE
);
783 else if (m_Data
.IsBaseFileInUse() && m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
785 //diff between THEIR, YOUR and BASE
786 m_pwndBottomView
->UseCaret();
787 pwndActiveView
= m_pwndBottomView
;
789 m_pwndLeftView
->m_pViewData
= &m_Data
.m_TheirBaseBoth
;
790 m_pwndLeftView
->texttype
= m_Data
.m_arTheirFile
.GetUnicodeType();
791 m_pwndLeftView
->lineendings
= m_Data
.m_arTheirFile
.GetLineEndings();
792 m_pwndLeftView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_THEIRS
);
793 m_pwndLeftView
->m_sWindowName
+= _T(" - ") + m_Data
.m_theirFile
.GetWindowName();
794 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_theirFile
.GetFilename();
796 m_pwndRightView
->m_pViewData
= &m_Data
.m_YourBaseBoth
;
797 m_pwndRightView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
798 m_pwndRightView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
799 m_pwndRightView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_MINE
);
800 m_pwndRightView
->m_sWindowName
+= _T(" - ") + m_Data
.m_yourFile
.GetWindowName();
801 m_pwndRightView
->m_sFullFilePath
= m_Data
.m_yourFile
.GetFilename();
803 m_pwndBottomView
->m_pViewData
= &m_Data
.m_Diff3
;
804 m_pwndBottomView
->texttype
= m_Data
.m_arTheirFile
.GetUnicodeType();
805 m_pwndBottomView
->lineendings
= m_Data
.m_arTheirFile
.GetLineEndings();
806 m_pwndBottomView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_MERGED
);
807 m_pwndBottomView
->m_sWindowName
+= _T(" - ") + m_Data
.m_mergedFile
.GetWindowName();
808 m_pwndBottomView
->m_sFullFilePath
= m_Data
.m_mergedFile
.GetFilename();
810 if (m_wndSplitter2
.IsColumnHidden(1))
811 m_wndSplitter2
.ShowColumn();
812 if (m_wndSplitter
.IsRowHidden(1))
813 m_wndSplitter
.ShowRow();
814 m_pwndLeftView
->SetHidden(FALSE
);
815 m_pwndRightView
->SetHidden(FALSE
);
816 m_pwndBottomView
->SetHidden(FALSE
);
817 // in three pane view, hide the line diff bar
818 m_wndLineDiffBar
.ShowPane(false, false, true);
819 m_wndLineDiffBar
.DocumentUpdated();
821 if (!m_Data
.m_mergedFile
.InUse())
823 m_Data
.m_mergedFile
.SetFileName(m_Data
.m_yourFile
.GetFilename());
825 m_pwndLeftView
->DocumentUpdated();
826 m_pwndRightView
->DocumentUpdated();
827 m_pwndBottomView
->DocumentUpdated();
828 m_wndLocatorBar
.DocumentUpdated();
829 m_wndLineDiffBar
.DocumentUpdated();
831 SetActiveView(pwndActiveView
);
833 if (bRetainPosition
&& m_pwndLeftView
->m_pViewData
)
835 int n
= nOldLineNumber
;
837 n
= m_pwndLeftView
->m_pViewData
->FindLineNumber(n
);
841 m_pwndLeftView
->ScrollAllToLine(n
);
845 m_pwndLeftView
->SetCaretPosition(p
);
849 bool bGoFirstDiff
= (0 != (DWORD
)CRegDWORD(_T("Software\\TortoiseMerge\\FirstDiffOnLoad"), TRUE
));
851 pwndActiveView
->GoToFirstDifference();
852 // Ignore the first few Mouse Move messages, so that the line diff stays on
853 // the first diff line until the user actually moves the mouse
854 m_nMoveMovesToIgnore
= 3;
858 // Avoid incorrect rendering of active pane.
859 m_pwndBottomView
->ScrollToChar(0);
860 m_pwndLeftView
->ScrollToChar(0);
861 m_pwndRightView
->ScrollToChar(0);
863 CUndo::GetInstance().Clear();
867 void CMainFrame::UpdateLayout()
873 int width
= cr
.Width();
874 if (::IsWindow(m_wndLocatorBar
) && m_wndLocatorBar
.IsWindowVisible())
876 m_wndLocatorBar
.GetWindowRect(&rclocbar
);
877 width
-= rclocbar
.Width();
879 m_wndSplitter
.SetRowInfo(0, cr
.Height()/2, 0);
880 m_wndSplitter
.SetRowInfo(1, cr
.Height()/2, 0);
881 m_wndSplitter
.SetColumnInfo(0, width
/ 2, 50);
882 m_wndSplitter2
.SetRowInfo(0, cr
.Height()/2, 0);
883 m_wndSplitter2
.SetColumnInfo(0, width
/ 2, 50);
884 m_wndSplitter2
.SetColumnInfo(1, width
/ 2, 50);
886 m_wndSplitter
.RecalcLayout();
890 void CMainFrame::OnSize(UINT nType
, int cx
, int cy
)
892 if (m_bInitSplitter
&& nType
!= SIZE_MINIMIZED
)
896 CFrameWndEx::OnSize(nType
, cx
, cy
);
899 void CMainFrame::OnViewWhitespaces()
901 CRegDWORD regViewWhitespaces
= CRegDWORD(_T("Software\\TortoiseMerge\\ViewWhitespaces"), 1);
902 BOOL bViewWhitespaces
= regViewWhitespaces
;
904 bViewWhitespaces
= m_pwndLeftView
->m_bViewWhitespace
;
906 bViewWhitespaces
= !bViewWhitespaces
;
907 regViewWhitespaces
= bViewWhitespaces
;
910 m_pwndLeftView
->m_bViewWhitespace
= bViewWhitespaces
;
911 m_pwndLeftView
->Invalidate();
915 m_pwndRightView
->m_bViewWhitespace
= bViewWhitespaces
;
916 m_pwndRightView
->Invalidate();
918 if (m_pwndBottomView
)
920 m_pwndBottomView
->m_bViewWhitespace
= bViewWhitespaces
;
921 m_pwndBottomView
->Invalidate();
925 void CMainFrame::OnUpdateViewWhitespaces(CCmdUI
*pCmdUI
)
928 pCmdUI
->SetCheck(m_pwndLeftView
->m_bViewWhitespace
);
931 void CMainFrame::OnViewOnewaydiff()
933 if (CheckForSave()==IDCANCEL
)
935 m_bOneWay
= !m_bOneWay
;
938 // in one way view, hide the line diff bar
939 m_wndLineDiffBar
.ShowPane(false, false, true);
940 m_wndLineDiffBar
.DocumentUpdated();
944 // restore the line diff bar
945 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
946 m_wndLineDiffBar
.DocumentUpdated();
947 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
948 m_wndLocatorBar
.DocumentUpdated();
953 void CMainFrame::ShowDiffBar(bool bShow
)
957 // restore the line diff bar
958 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
959 m_wndLineDiffBar
.DocumentUpdated();
960 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
961 m_wndLocatorBar
.DocumentUpdated();
965 // in one way view, hide the line diff bar
966 m_wndLineDiffBar
.ShowPane(false, false, true);
967 m_wndLineDiffBar
.DocumentUpdated();
971 int CMainFrame::CheckResolved()
973 //only in three way diffs can be conflicts!
974 m_bHasConflicts
= true;
975 if (m_pwndBottomView
->IsWindowVisible())
977 if (m_pwndBottomView
->m_pViewData
)
979 for (int i
=0; i
<m_pwndBottomView
->m_pViewData
->GetCount(); i
++)
981 if ((DIFFSTATE_CONFLICTED
== m_pwndBottomView
->m_pViewData
->GetState(i
))||
982 (DIFFSTATE_CONFLICTED_IGNORED
== m_pwndBottomView
->m_pViewData
->GetState(i
)))
987 m_bHasConflicts
= false;
991 int CMainFrame::SaveFile(const CString
& sFilePath
)
993 CViewData
* pViewData
= NULL
;
994 CFileTextLines
* pOriginFile
= &m_Data
.m_arBaseFile
;
995 if ((m_pwndBottomView
)&&(m_pwndBottomView
->IsWindowVisible()))
997 pViewData
= m_pwndBottomView
->m_pViewData
;
1000 else if ((m_pwndRightView
)&&(m_pwndRightView
->IsWindowVisible()))
1002 pViewData
= m_pwndRightView
->m_pViewData
;
1003 if (m_Data
.IsYourFileInUse())
1004 pOriginFile
= &m_Data
.m_arYourFile
;
1005 else if (m_Data
.IsTheirFileInUse())
1006 pOriginFile
= &m_Data
.m_arTheirFile
;
1014 if ((pViewData
)&&(pOriginFile
))
1016 CFileTextLines file
;
1017 pOriginFile
->CopySettings(&file
);
1018 for (int i
=0; i
<pViewData
->GetCount(); i
++)
1020 //only copy non-removed lines
1021 DiffStates state
= pViewData
->GetState(i
);
1024 case DIFFSTATE_CONFLICTED
:
1025 case DIFFSTATE_CONFLICTED_IGNORED
:
1032 } while((last
<pViewData
->GetCount()) && ((pViewData
->GetState(last
)==DIFFSTATE_CONFLICTED
)||(pViewData
->GetState(last
)==DIFFSTATE_CONFLICTED_IGNORED
)));
1033 file
.Add(_T("<<<<<<< .mine"), m_pwndRightView
->lineendings
);
1034 for (int j
=first
; j
<last
; j
++)
1036 EOL lineending
= m_pwndRightView
->m_pViewData
->GetLineEnding(j
);
1037 if (lineending
== EOL_NOENDING
)
1038 lineending
= m_pwndRightView
->lineendings
;
1039 file
.Add(m_pwndRightView
->m_pViewData
->GetLine(j
), lineending
);
1041 file
.Add(_T("======="), m_pwndRightView
->lineendings
);
1042 for (int j
=first
; j
<last
; j
++)
1044 EOL lineending
= m_pwndLeftView
->m_pViewData
->GetLineEnding(j
);
1045 if (lineending
== EOL_NOENDING
)
1046 lineending
= m_pwndLeftView
->lineendings
;
1047 file
.Add(m_pwndLeftView
->m_pViewData
->GetLine(j
), lineending
);
1049 file
.Add(_T(">>>>>>> .theirs"), m_pwndRightView
->lineendings
);
1053 case DIFFSTATE_EMPTY
:
1054 case DIFFSTATE_CONFLICTEMPTY
:
1055 case DIFFSTATE_IDENTICALREMOVED
:
1056 case DIFFSTATE_REMOVED
:
1057 case DIFFSTATE_THEIRSREMOVED
:
1058 case DIFFSTATE_YOURSREMOVED
:
1059 case DIFFSTATE_CONFLICTRESOLVEDEMPTY
:
1060 // do not save removed lines
1063 file
.Add(pViewData
->GetLine(i
), pViewData
->GetLineEnding(i
));
1067 if (!file
.Save(sFilePath
, false))
1069 CMessageBox::Show(m_hWnd
, file
.GetErrorString(), _T("TortoiseMerge"), MB_ICONERROR
);
1072 m_dlgFilePatches
.SetFileStatusAsPatched(sFilePath
);
1073 if (m_pwndBottomView
)
1074 m_pwndBottomView
->SetModified(FALSE
);
1075 if (m_pwndRightView
)
1076 m_pwndRightView
->SetModified(FALSE
);
1077 CUndo::GetInstance().MarkAsOriginalState();
1078 return file
.GetCount();
1083 void CMainFrame::OnFileSave()
1088 bool CMainFrame::FileSave(bool bCheckResolved
/*=true*/)
1090 if (!m_Data
.m_mergedFile
.InUse())
1091 return FileSaveAs(bCheckResolved
);
1092 // check if the file has the readonly attribute set
1093 bool bDoesNotExist
= false;
1094 DWORD fAttribs
= GetFileAttributes(m_Data
.m_mergedFile
.GetFilename());
1095 if ((fAttribs
!= INVALID_FILE_ATTRIBUTES
)&&(fAttribs
& FILE_ATTRIBUTE_READONLY
))
1096 return FileSaveAs(bCheckResolved
);
1097 if (fAttribs
== INVALID_FILE_ATTRIBUTES
)
1099 bDoesNotExist
= (GetLastError() == ERROR_FILE_NOT_FOUND
);
1103 int nConflictLine
= CheckResolved();
1104 if (nConflictLine
>= 0)
1107 sTemp
.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS
, m_pwndBottomView
->m_pViewData
->GetLineNumber(nConflictLine
)+1);
1108 if (MessageBox(sTemp
, 0, MB_ICONERROR
| MB_YESNO
)!=IDYES
)
1110 if (m_pwndBottomView
)
1111 m_pwndBottomView
->GoToLine(nConflictLine
);
1116 if (((DWORD
)CRegDWORD(_T("Software\\TortoiseMerge\\Backup"))) != 0)
1118 MoveFileEx(m_Data
.m_mergedFile
.GetFilename(), m_Data
.m_mergedFile
.GetFilename() + _T(".bak"), MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
| MOVEFILE_WRITE_THROUGH
);
1120 if (SaveFile(m_Data
.m_mergedFile
.GetFilename())==0)
1122 // file was saved with 0 lines!
1123 // ask the user if the file should be deleted
1125 sTemp
.Format(IDS_DELETEWHENEMPTY
, (LPCTSTR
)m_Data
.m_mergedFile
.GetFilename());
1126 if (CMessageBox::ShowCheck(m_hWnd
, sTemp
, _T("TortoiseMerge"), MB_YESNO
, _T("DeleteFileWhenEmpty")) == IDYES
)
1128 DeleteFile(m_Data
.m_mergedFile
.GetFilename());
1134 // call TortoiseProc to add the new file to version control
1135 CString cmd
= _T("/command:add /noui /path:\"");
1136 cmd
+= m_Data
.m_mergedFile
.GetFilename() + _T("\"");
1137 CAppUtils::RunTortoiseProc(cmd
);
1142 void CMainFrame::OnFileSaveAs()
1147 bool CMainFrame::FileSaveAs(bool bCheckResolved
/*=true*/)
1151 int nConflictLine
= CheckResolved();
1152 if (nConflictLine
>= 0)
1155 sTemp
.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS
, m_pwndBottomView
->m_pViewData
->GetLineNumber(nConflictLine
)+1);
1156 if (MessageBox(sTemp
, 0, MB_ICONERROR
| MB_YESNO
)!=IDYES
)
1158 if (m_pwndBottomView
)
1159 m_pwndBottomView
->GoToLine(nConflictLine
);
1164 OPENFILENAME ofn
= {0}; // common dialog box structure
1165 TCHAR szFile
[MAX_PATH
] = {0}; // buffer for file name
1166 ofn
.lStructSize
= sizeof(OPENFILENAME
);
1167 ofn
.hwndOwner
= m_hWnd
;
1168 ofn
.lpstrFile
= szFile
;
1169 ofn
.nMaxFile
= _countof(szFile
);
1171 temp
.LoadString(IDS_SAVEASTITLE
);
1172 if (!temp
.IsEmpty())
1173 ofn
.lpstrTitle
= temp
;
1174 ofn
.Flags
= OFN_OVERWRITEPROMPT
;
1176 sFilter
.LoadString(IDS_COMMONFILEFILTER
);
1177 TCHAR
* pszFilters
= new TCHAR
[sFilter
.GetLength()+4];
1178 _tcscpy_s (pszFilters
, sFilter
.GetLength()+4, sFilter
);
1179 // Replace '|' delimiters with '\0's
1180 TCHAR
*ptr
= pszFilters
+ _tcslen(pszFilters
); //set ptr at the NULL
1181 while (ptr
!= pszFilters
)
1187 ofn
.lpstrFilter
= pszFilters
;
1188 ofn
.nFilterIndex
= 1;
1190 // Display the Open dialog box.
1192 if (GetSaveFileName(&ofn
)==TRUE
)
1194 sFile
= CString(ofn
.lpstrFile
);
1196 delete [] pszFilters
;
1199 delete [] pszFilters
;
1203 void CMainFrame::OnUpdateFileSave(CCmdUI
*pCmdUI
)
1205 BOOL bEnable
= FALSE
;
1206 if (m_Data
.m_mergedFile
.InUse())
1208 if (m_pwndBottomView
)
1210 if ((m_pwndBottomView
->IsWindowVisible())&&(m_pwndBottomView
->m_pViewData
))
1215 if (m_pwndRightView
)
1217 if ((m_pwndRightView
->IsWindowVisible())&&(m_pwndRightView
->m_pViewData
))
1219 if (m_pwndRightView
->IsModified() || (m_Data
.m_yourFile
.GetWindowName().Right(9).Compare(_T(": patched"))==0))
1224 pCmdUI
->Enable(bEnable
);
1227 void CMainFrame::OnUpdateFileSaveAs(CCmdUI
*pCmdUI
)
1229 BOOL bEnable
= FALSE
;
1230 if (m_pwndBottomView
)
1232 if ((m_pwndBottomView
->IsWindowVisible())&&(m_pwndBottomView
->m_pViewData
))
1237 if (m_pwndRightView
)
1239 if ((m_pwndRightView
->IsWindowVisible())&&(m_pwndRightView
->m_pViewData
))
1244 pCmdUI
->Enable(bEnable
);
1248 void CMainFrame::OnUpdateViewOnewaydiff(CCmdUI
*pCmdUI
)
1250 pCmdUI
->SetCheck(!m_bOneWay
);
1251 BOOL bEnable
= TRUE
;
1252 if (m_pwndBottomView
)
1254 if (m_pwndBottomView
->IsWindowVisible())
1257 pCmdUI
->Enable(bEnable
);
1260 void CMainFrame::OnViewOptions()
1263 sTemp
.LoadString(IDS_SETTINGSTITLE
);
1264 CSettings
dlg(sTemp
);
1266 if (dlg
.IsReloadNeeded())
1268 if (CheckForSave()==IDCANCEL
)
1270 CDiffColors::GetInstance().LoadRegistry();
1274 CDiffColors::GetInstance().LoadRegistry();
1275 if (m_pwndBottomView
)
1276 m_pwndBottomView
->Invalidate();
1278 m_pwndLeftView
->Invalidate();
1279 if (m_pwndRightView
)
1280 m_pwndRightView
->Invalidate();
1283 void CMainFrame::OnClose()
1285 if ((m_pFindDialog
)&&(!m_pFindDialog
->IsTerminating()))
1287 m_pFindDialog
->SendMessage(WM_CLOSE
);
1291 if (((m_pwndBottomView
)&&(m_pwndBottomView
->IsModified())) ||
1292 ((m_pwndRightView
)&&(m_pwndRightView
->IsModified())))
1295 sTemp
.LoadString(IDS_ASKFORSAVE
);
1296 ret
= MessageBox(sTemp
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
1303 if ((ret
== IDNO
)||(ret
== IDYES
))
1307 // before it is destroyed, save the position of the window
1308 wp
.length
= sizeof wp
;
1310 if (GetWindowPlacement(&wp
))
1314 // never restore to Iconic state
1315 wp
.showCmd
= SW_SHOW
;
1317 if ((wp
.flags
& WPF_RESTORETOMAXIMIZED
) != 0)
1318 // if maximized and maybe iconic restore maximized state
1319 wp
.showCmd
= SW_SHOWMAXIMIZED
;
1321 // and write it to the .INI file
1322 WriteWindowPlacement(&wp
);
1328 void CMainFrame::OnEditFind()
1336 // start searching from the start again
1337 // if no line is selected, otherwise start from
1338 // the selected line
1339 m_nSearchIndex
= FindSearchStart(0);
1340 m_pFindDialog
= new CFindDlg();
1341 m_pFindDialog
->Create(this);
1345 LRESULT
CMainFrame::OnFindDialogMessage(WPARAM
/*wParam*/, LPARAM
/*lParam*/)
1347 ASSERT(m_pFindDialog
!= NULL
);
1349 if (m_pFindDialog
->IsTerminating())
1351 // invalidate the handle identifying the dialog box.
1352 m_pFindDialog
= NULL
;
1356 if(m_pFindDialog
->FindNext())
1358 //read data from dialog
1359 m_sFindText
= m_pFindDialog
->GetFindString();
1360 m_bMatchCase
= (m_pFindDialog
->MatchCase() == TRUE
);
1361 m_bLimitToDiff
= m_pFindDialog
->LimitToDiffs();
1362 m_bWholeWord
= m_pFindDialog
->WholeWord();
1370 bool CharIsDelimiter(const CString
& ch
)
1372 CString
delimiters(_T(" .,:;=+-*/\\\n\t()[]<>@"));
1373 return delimiters
.Find(ch
) >= 0;
1376 bool CMainFrame::StringFound(const CString
& str
)const
1378 int nSubStringStartIdx
= str
.Find(m_sFindText
);
1379 bool bStringFound
= (nSubStringStartIdx
>= 0);
1380 if (bStringFound
&& m_bWholeWord
)
1382 if (nSubStringStartIdx
)
1383 bStringFound
= CharIsDelimiter(str
.Mid(nSubStringStartIdx
-1,1));
1387 int nEndIndex
= nSubStringStartIdx
+ m_sFindText
.GetLength();
1388 if (str
.GetLength() > nEndIndex
)
1389 bStringFound
= CharIsDelimiter(str
.Mid(nEndIndex
, 1));
1392 return bStringFound
;
1395 void CMainFrame::OnEditFindprev()
1397 Search(SearchPrevious
);
1400 void CMainFrame::OnEditFindnext()
1405 void CMainFrame::Search(SearchDirection srchDir
)
1407 if (m_sFindText
.IsEmpty())
1410 if ((m_pwndLeftView
)&&(m_pwndLeftView
->m_pViewData
))
1412 bool bFound
= FALSE
;
1417 DiffStates leftstate
= DIFFSTATE_NORMAL
;
1418 DiffStates rightstate
= DIFFSTATE_NORMAL
;
1419 DiffStates bottomstate
= DIFFSTATE_NORMAL
;
1422 m_nSearchIndex
= FindSearchStart(m_nSearchIndex
);
1424 if (m_nSearchIndex
>= m_pwndLeftView
->m_pViewData
->GetCount())
1426 if (srchDir
== SearchPrevious
)
1428 // SearchIndex points 1 past where we found the last match,
1429 // so if we are searching backwards we need to adjust accordingly
1430 m_nSearchIndex
-= 2;
1431 // if at the top, start again from the end
1432 if (m_nSearchIndex
< 0)
1433 m_nSearchIndex
+= m_pwndLeftView
->m_pViewData
->GetCount();
1435 const int idxLimits
[2][2][2]={{{m_nSearchIndex
, m_pwndLeftView
->m_pViewData
->GetCount()},
1436 {0, m_nSearchIndex
}},
1437 {{m_nSearchIndex
, -1},
1438 {m_pwndLeftView
->m_pViewData
->GetCount()-1, m_nSearchIndex
}}};
1439 const int offsets
[2]={+1, -1};
1441 for (int j
=0; j
!= 2 && !bFound
; ++j
)
1443 for (i
=idxLimits
[srchDir
][j
][0]; i
!= idxLimits
[srchDir
][j
][1]; i
+= offsets
[srchDir
])
1445 left
= m_pwndLeftView
->m_pViewData
->GetLine(i
);
1446 leftstate
= m_pwndLeftView
->m_pViewData
->GetState(i
);
1447 if ((!m_bOneWay
)&&(m_pwndRightView
->m_pViewData
))
1449 right
= m_pwndRightView
->m_pViewData
->GetLine(i
);
1450 rightstate
= m_pwndRightView
->m_pViewData
->GetState(i
);
1452 if ((m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1454 bottom
= m_pwndBottomView
->m_pViewData
->GetLine(i
);
1455 bottomstate
= m_pwndBottomView
->m_pViewData
->GetState(i
);
1460 left
= left
.MakeLower();
1461 right
= right
.MakeLower();
1462 bottom
= bottom
.MakeLower();
1463 m_sFindText
= m_sFindText
.MakeLower();
1465 if (StringFound(left
))
1467 if ((!m_bLimitToDiff
)||(leftstate
!= DIFFSTATE_NORMAL
))
1473 else if (StringFound(right
))
1475 if ((!m_bLimitToDiff
)||(rightstate
!= DIFFSTATE_NORMAL
))
1481 else if (StringFound(bottom
))
1483 if ((!m_bLimitToDiff
)||(bottomstate
!= DIFFSTATE_NORMAL
))
1494 m_pwndLeftView
->GoToLine(m_nSearchIndex
);
1495 if (StringFound(left
))
1497 m_pwndLeftView
->SetFocus();
1498 m_pwndLeftView
->HiglightLines(m_nSearchIndex
);
1500 else if (StringFound(right
))
1502 m_pwndRightView
->SetFocus();
1503 m_pwndRightView
->HiglightLines(m_nSearchIndex
);
1505 else if (StringFound(bottom
))
1507 m_pwndBottomView
->SetFocus();
1508 m_pwndBottomView
->HiglightLines(m_nSearchIndex
);
1518 int CMainFrame::FindSearchStart(int nDefault
)
1520 // TortoiseMerge doesn't have a cursor which we could use to
1521 // anchor the search on.
1522 // Instead we use a line that is selected.
1523 // If however no line is selected, use the default line (which could
1524 // be the top of the document for a new search, or the line where the
1525 // search was successful on)
1526 int nLine
= nDefault
;
1531 if (m_pwndLeftView
->GetSelection(nSelStart
, nSelEnd
))
1533 if (nSelStart
== nSelEnd
)
1537 else if ((nLine
== nDefault
)&&(m_pwndRightView
))
1539 if (m_pwndRightView
->GetSelection(nSelStart
, nSelEnd
))
1541 if (nSelStart
== nSelEnd
)
1545 else if ((nLine
== nDefault
)&&(m_pwndBottomView
))
1547 if (m_pwndBottomView
->GetSelection(nSelStart
, nSelEnd
))
1549 if (nSelStart
== nSelEnd
)
1556 void CMainFrame::OnEditGoto()
1558 CWnd
*wnd
= this->GetFocus();
1559 if (wnd
!= m_pwndLeftView
&& wnd
!= m_pwndRightView
&& wnd
!= m_pwndBottomView
)
1562 CBaseView
*view
= (CBaseView
*)wnd
;
1563 CBaseView
*view2
= view
== m_pwndBottomView
|| view
== m_pwndRightView
? (CBaseView
*)m_pwndLeftView
: m_pwndRightView
;
1564 CBaseView
*view3
= view
== m_pwndBottomView
|| view
== m_pwndLeftView
? (CBaseView
*)m_pwndRightView
: m_Data
.IsTheirFileInUse() ? m_pwndBottomView
: NULL
;
1569 int count
= view
->m_pViewData
->GetCount();
1570 if (view
->GetSelection(start
, end
))
1572 int line
= DIFF_EMPTYLINENUMBER
;
1573 for (int i
= start
; i
< count
; i
++)
1575 line
= view
->m_pViewData
->GetLineNumber(i
);
1576 if (line
!= DIFF_EMPTYLINENUMBER
)
1579 dlg
.m_LineNumber
= line
== DIFF_EMPTYLINENUMBER
? 1 : (line
+ 1);
1582 if (dlg
.DoModal() == IDOK
)
1584 int index
= view
->m_pViewData
->FindLineNumber(dlg
.m_LineNumber
- 1);
1587 view
->HiglightLines(index
);
1588 view
->GoToLine(index
, FALSE
);
1589 view2
->GoToLine(index
, FALSE
);
1591 view3
->GoToLine(index
, FALSE
);
1595 void CMainFrame::OnViewLinedown()
1598 m_pwndLeftView
->ScrollToLine(m_pwndLeftView
->m_nTopLine
+1);
1599 if (m_pwndRightView
)
1600 m_pwndRightView
->ScrollToLine(m_pwndRightView
->m_nTopLine
+1);
1601 if (m_pwndBottomView
)
1602 m_pwndBottomView
->ScrollToLine(m_pwndBottomView
->m_nTopLine
+1);
1603 m_wndLocatorBar
.Invalidate();
1606 void CMainFrame::OnViewLineup()
1609 m_pwndLeftView
->ScrollToLine(m_pwndLeftView
->m_nTopLine
-1);
1610 if (m_pwndRightView
)
1611 m_pwndRightView
->ScrollToLine(m_pwndRightView
->m_nTopLine
-1);
1612 if (m_pwndBottomView
)
1613 m_pwndBottomView
->ScrollToLine(m_pwndBottomView
->m_nTopLine
-1);
1614 m_wndLocatorBar
.Invalidate();
1617 void CMainFrame::OnViewLineleft()
1620 m_pwndLeftView
->ScrollSide(-1);
1621 if (m_pwndRightView
)
1622 m_pwndRightView
->ScrollSide(-1);
1623 if (m_pwndBottomView
)
1624 m_pwndBottomView
->ScrollSide(-1);
1627 void CMainFrame::OnViewLineright()
1630 m_pwndLeftView
->ScrollSide(1);
1631 if (m_pwndRightView
)
1632 m_pwndRightView
->ScrollSide(1);
1633 if (m_pwndBottomView
)
1634 m_pwndBottomView
->ScrollSide(1);
1637 void CMainFrame::OnEditUseTheirs()
1639 if (m_pwndBottomView
)
1640 m_pwndBottomView
->UseTheirTextBlock();
1642 void CMainFrame::OnUpdateEditUsetheirblock(CCmdUI
*pCmdUI
)
1644 int nSelBlockStart
= -1;
1645 int nSelBlockEnd
= -1;
1646 if (m_pwndBottomView
)
1647 m_pwndBottomView
->GetSelection(nSelBlockStart
, nSelBlockEnd
);
1648 pCmdUI
->Enable((nSelBlockStart
>= 0)&&(nSelBlockEnd
>= 0));
1652 void CMainFrame::OnEditUseMine()
1654 if (m_pwndBottomView
)
1655 m_pwndBottomView
->UseMyTextBlock();
1657 void CMainFrame::OnUpdateEditUsemyblock(CCmdUI
*pCmdUI
)
1659 int nSelBlockStart
= -1;
1660 int nSelBlockEnd
= -1;
1661 if (m_pwndBottomView
)
1662 m_pwndBottomView
->GetSelection(nSelBlockStart
, nSelBlockEnd
);
1663 pCmdUI
->Enable((nSelBlockStart
>= 0)&&(nSelBlockEnd
>= 0));
1667 void CMainFrame::OnEditUseTheirsThenMine()
1669 if (m_pwndBottomView
)
1670 m_pwndBottomView
->UseTheirThenMyTextBlock();
1672 void CMainFrame::OnUpdateEditUsetheirthenmyblock(CCmdUI
*pCmdUI
)
1674 int nSelBlockStart
= -1;
1675 int nSelBlockEnd
= -1;
1676 if (m_pwndBottomView
)
1677 m_pwndBottomView
->GetSelection(nSelBlockStart
, nSelBlockEnd
);
1678 pCmdUI
->Enable((nSelBlockStart
>= 0)&&(nSelBlockEnd
>= 0));
1682 void CMainFrame::OnEditUseMineThenTheirs()
1684 if (m_pwndBottomView
)
1685 m_pwndBottomView
->UseMyThenTheirTextBlock();
1687 void CMainFrame::OnUpdateEditUseminethentheirblock(CCmdUI
*pCmdUI
)
1689 int nSelBlockStart
= -1;
1690 int nSelBlockEnd
= -1;
1691 if (m_pwndBottomView
)
1692 m_pwndBottomView
->GetSelection(nSelBlockStart
, nSelBlockEnd
);
1693 pCmdUI
->Enable((nSelBlockStart
>= 0)&&(nSelBlockEnd
>= 0));
1696 void CMainFrame::OnEditUseleftblock()
1698 if (m_pwndRightView
)
1699 m_pwndRightView
->UseBlock();
1702 void CMainFrame::OnUpdateEditUseleftblock(CCmdUI
*pCmdUI
)
1704 pCmdUI
->Enable(m_pwndRightView
&& m_pwndRightView
->IsWindowVisible() && m_pwndRightView
->HasCaret() && m_pwndRightView
->HasSelection());
1707 void CMainFrame::OnEditUseleftfile()
1709 if (m_pwndRightView
)
1710 m_pwndRightView
->UseFile();
1713 void CMainFrame::OnUpdateEditUseleftfile(CCmdUI
*pCmdUI
)
1715 pCmdUI
->Enable(m_pwndRightView
&& m_pwndRightView
->IsWindowVisible() && m_pwndRightView
->HasCaret());
1718 void CMainFrame::OnEditUseblockfromleftbeforeright()
1720 if (m_pwndRightView
)
1721 m_pwndRightView
->UseLeftBeforeRight();
1724 void CMainFrame::OnUpdateEditUseblockfromleftbeforeright(CCmdUI
*pCmdUI
)
1726 pCmdUI
->Enable(m_pwndRightView
&& m_pwndRightView
->IsWindowVisible() && m_pwndRightView
->HasCaret() && m_pwndRightView
->HasSelection());
1729 void CMainFrame::OnEditUseblockfromrightbeforeleft()
1731 if (m_pwndRightView
)
1732 m_pwndRightView
->UseRightBeforeLeft();
1735 void CMainFrame::OnUpdateEditUseblockfromrightbeforeleft(CCmdUI
*pCmdUI
)
1737 pCmdUI
->Enable(m_pwndRightView
&& m_pwndRightView
->IsWindowVisible() && m_pwndRightView
->HasCaret() && m_pwndRightView
->HasSelection());
1741 void CMainFrame::OnFileReload()
1743 if (CheckForSave()==IDCANCEL
)
1745 CDiffColors::GetInstance().LoadRegistry();
1749 void CMainFrame::ActivateFrame(int nCmdShow
)
1751 // nCmdShow is the normal show mode this frame should be in
1752 // translate default nCmdShow (-1)
1755 if (!IsWindowVisible())
1756 nCmdShow
= SW_SHOWNORMAL
;
1757 else if (IsIconic())
1758 nCmdShow
= SW_RESTORE
;
1761 // bring to top before showing
1762 BringToTop(nCmdShow
);
1766 // show the window as specified
1769 if ( !ReadWindowPlacement(&wp
) )
1771 ShowWindow(nCmdShow
);
1775 if ( nCmdShow
!= SW_SHOWNORMAL
)
1776 wp
.showCmd
= nCmdShow
;
1778 SetWindowPlacement(&wp
);
1781 // and finally, bring to top after showing
1782 BringToTop(nCmdShow
);
1787 BOOL
CMainFrame::ReadWindowPlacement(WINDOWPLACEMENT
* pwp
)
1789 CRegString placement
= CRegString(_T("Software\\TortoiseMerge\\WindowPos"));
1790 CString sPlacement
= placement
;
1791 if (sPlacement
.IsEmpty())
1793 int nRead
= _stscanf_s(sPlacement
, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
1794 &pwp
->flags
, &pwp
->showCmd
,
1795 &pwp
->ptMinPosition
.x
, &pwp
->ptMinPosition
.y
,
1796 &pwp
->ptMaxPosition
.x
, &pwp
->ptMaxPosition
.y
,
1797 &pwp
->rcNormalPosition
.left
, &pwp
->rcNormalPosition
.top
,
1798 &pwp
->rcNormalPosition
.right
, &pwp
->rcNormalPosition
.bottom
);
1801 pwp
->length
= sizeof(WINDOWPLACEMENT
);
1806 void CMainFrame::WriteWindowPlacement(WINDOWPLACEMENT
* pwp
)
1808 CRegString placement
= CRegString(_T("Software\\TortoiseMerge\\WindowPos"));
1809 TCHAR szBuffer
[_countof("-32767")*8 + sizeof("65535")*2];
1812 _stprintf_s(szBuffer
, _countof("-32767")*8 + sizeof("65535")*2, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
1813 pwp
->flags
, pwp
->showCmd
,
1814 pwp
->ptMinPosition
.x
, pwp
->ptMinPosition
.y
,
1815 pwp
->ptMaxPosition
.x
, pwp
->ptMaxPosition
.y
,
1816 pwp
->rcNormalPosition
.left
, pwp
->rcNormalPosition
.top
,
1817 pwp
->rcNormalPosition
.right
, pwp
->rcNormalPosition
.bottom
);
1818 placement
= szBuffer
;
1821 void CMainFrame::OnUpdateMergeMarkasresolved(CCmdUI
*pCmdUI
)
1825 BOOL bEnable
= FALSE
;
1826 if ((!m_bReadOnly
)&&(m_Data
.m_mergedFile
.InUse()))
1828 if (m_pwndBottomView
)
1830 if ((m_pwndBottomView
->IsWindowVisible())&&(m_pwndBottomView
->m_pViewData
))
1836 pCmdUI
->Enable(bEnable
);
1839 void CMainFrame::OnMergeMarkasresolved()
1841 int nConflictLine
= CheckResolved();
1842 if (nConflictLine
>= 0)
1845 sTemp
.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS
, m_pwndBottomView
->m_pViewData
->GetLineNumber(nConflictLine
)+1);
1846 if (MessageBox(sTemp
, 0, MB_ICONERROR
| MB_YESNO
)!=IDYES
)
1848 if (m_pwndBottomView
)
1849 m_pwndBottomView
->GoToLine(nConflictLine
);
1853 // now check if the file has already been saved and if not, save it.
1854 if (m_Data
.m_mergedFile
.InUse())
1856 if (m_pwndBottomView
)
1858 if ((m_pwndBottomView
->IsWindowVisible())&&(m_pwndBottomView
->m_pViewData
))
1867 BOOL
CMainFrame::MarkAsResolved()
1871 if (!((m_pwndBottomView
) && (m_pwndBottomView
->IsWindowVisible())))
1874 CString cmd
= _T("/command:resolve /path:\"");
1875 cmd
+= m_Data
.m_mergedFile
.GetFilename();
1876 cmd
+= _T("\" /closeonend:1 /noquestion /skipcheck /silent");
1877 if (!CAppUtils::RunTortoiseProc(cmd
))
1883 void CMainFrame::OnUpdateMergeNextconflict(CCmdUI
*pCmdUI
)
1885 pCmdUI
->Enable(m_bHasConflicts
);
1888 void CMainFrame::OnUpdateMergePreviousconflict(CCmdUI
*pCmdUI
)
1890 pCmdUI
->Enable(m_bHasConflicts
);
1893 void CMainFrame::OnMoving(UINT fwSide
, LPRECT pRect
)
1895 // if the pathfilelist dialog is attached to the mainframe,
1896 // move it along with the mainframe
1897 if (::IsWindow(m_dlgFilePatches
.m_hWnd
))
1900 m_dlgFilePatches
.GetWindowRect(&patchrect
);
1901 if (::IsWindow(m_hWnd
))
1904 GetWindowRect(&thisrect
);
1905 if (patchrect
.right
== thisrect
.left
)
1907 m_dlgFilePatches
.SetWindowPos(NULL
, patchrect
.left
- (thisrect
.left
- pRect
->left
), patchrect
.top
- (thisrect
.top
- pRect
->top
),
1908 0, 0, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
| SWP_NOSIZE
| SWP_NOZORDER
);
1912 __super::OnMoving(fwSide
, pRect
);
1915 void CMainFrame::OnUpdateEditCopy(CCmdUI
*pCmdUI
)
1918 if ((m_pwndBottomView
)&&(m_pwndBottomView
->HasSelection()))
1920 if ((m_pwndRightView
)&&(m_pwndRightView
->HasSelection()))
1922 if ((m_pwndLeftView
)&&(m_pwndLeftView
->HasSelection()))
1924 pCmdUI
->Enable(bShow
);
1927 void CMainFrame::OnViewSwitchleft()
1930 if (((m_pwndBottomView
)&&(m_pwndBottomView
->IsModified())) ||
1931 ((m_pwndRightView
)&&(m_pwndRightView
->IsModified())))
1934 sTemp
.LoadString(IDS_ASKFORSAVE
);
1935 ret
= MessageBox(sTemp
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
1942 if ((ret
== IDNO
)||(ret
== IDYES
))
1944 CWorkingFile file
= m_Data
.m_baseFile
;
1945 m_Data
.m_baseFile
= m_Data
.m_yourFile
;
1946 m_Data
.m_yourFile
= file
;
1947 if (m_Data
.m_mergedFile
.GetFilename().CompareNoCase(m_Data
.m_yourFile
.GetFilename())==0)
1949 m_Data
.m_mergedFile
= m_Data
.m_baseFile
;
1951 else if (m_Data
.m_mergedFile
.GetFilename().CompareNoCase(m_Data
.m_baseFile
.GetFilename())==0)
1953 m_Data
.m_mergedFile
= m_Data
.m_yourFile
;
1959 void CMainFrame::OnUpdateViewSwitchleft(CCmdUI
*pCmdUI
)
1961 BOOL bEnable
= TRUE
;
1962 if (m_pwndBottomView
)
1964 if (m_pwndBottomView
->IsWindowVisible())
1967 pCmdUI
->Enable(bEnable
);
1971 void CMainFrame::OnUpdateViewShowfilelist(CCmdUI
*pCmdUI
)
1973 if (m_dlgFilePatches
.HasFiles())
1975 pCmdUI
->Enable(true);
1978 pCmdUI
->Enable(false);
1979 pCmdUI
->SetCheck(m_dlgFilePatches
.IsWindowVisible());
1982 void CMainFrame::OnViewShowfilelist()
1984 m_dlgFilePatches
.ShowWindow(m_dlgFilePatches
.IsWindowVisible() ? SW_HIDE
: SW_SHOW
);
1987 void CMainFrame::OnEditUndo()
1989 if (CUndo::GetInstance().CanUndo())
1991 CUndo::GetInstance().Undo(m_pwndLeftView
, m_pwndRightView
, m_pwndBottomView
);
1996 void CMainFrame::OnUpdateEditUndo(CCmdUI
*pCmdUI
)
1998 pCmdUI
->Enable(CUndo::GetInstance().CanUndo());
2001 int CMainFrame::CheckForSave()
2004 if (((m_pwndBottomView
)&&(m_pwndBottomView
->IsModified())) ||
2005 ((m_pwndRightView
)&&(m_pwndRightView
->IsModified())))
2008 sTemp
.LoadString(IDS_WARNMODIFIEDLOOSECHANGES
);
2009 ret
= MessageBox(sTemp
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
2019 void CMainFrame::OnViewInlinediffword()
2021 m_bInlineWordDiff
= !m_bInlineWordDiff
;
2024 m_pwndLeftView
->SetInlineWordDiff(m_bInlineWordDiff
);
2025 m_pwndLeftView
->Invalidate();
2027 if (m_pwndRightView
)
2029 m_pwndRightView
->SetInlineWordDiff(m_bInlineWordDiff
);
2030 m_pwndRightView
->Invalidate();
2032 if (m_pwndBottomView
)
2034 m_pwndBottomView
->SetInlineWordDiff(m_bInlineWordDiff
);
2035 m_pwndBottomView
->Invalidate();
2037 m_wndLineDiffBar
.Invalidate();
2040 void CMainFrame::OnUpdateViewInlinediffword(CCmdUI
*pCmdUI
)
2042 pCmdUI
->Enable(m_pwndLeftView
&& m_pwndLeftView
->IsWindowVisible() &&
2043 m_pwndRightView
&& m_pwndRightView
->IsWindowVisible());
2044 pCmdUI
->SetCheck(m_bInlineWordDiff
);
2047 void CMainFrame::OnUpdateEditCreateunifieddifffile(CCmdUI
*pCmdUI
)
2049 // "create unified diff file" is only available if two files
2050 // are diffed, not three.
2051 bool bEnabled
= true;
2052 if ((m_pwndLeftView
== NULL
)||(!m_pwndLeftView
->IsWindowVisible()))
2054 if ((m_pwndRightView
== NULL
)||(!m_pwndRightView
->IsWindowVisible()))
2056 if ((m_pwndBottomView
)&&(m_pwndBottomView
->IsWindowVisible()))
2058 pCmdUI
->Enable(bEnabled
);
2061 void CMainFrame::OnEditCreateunifieddifffile()
2063 CString origFile
, modifiedFile
, outputFile
;
2064 // the original file is the one on the left
2066 origFile
= m_pwndLeftView
->m_sFullFilePath
;
2067 if (m_pwndRightView
)
2068 modifiedFile
= m_pwndRightView
->m_sFullFilePath
;
2069 if (!origFile
.IsEmpty() && !modifiedFile
.IsEmpty())
2071 // ask for the path to save the unified diff file to
2072 OPENFILENAME ofn
= {0}; // common dialog box structure
2073 TCHAR szFile
[MAX_PATH
] = {0}; // buffer for file name
2074 ofn
.lStructSize
= sizeof(OPENFILENAME
);
2075 ofn
.lpstrFile
= szFile
;
2076 ofn
.nMaxFile
= _countof(szFile
);
2078 temp
.LoadString(IDS_SAVEASTITLE
);
2079 if (!temp
.IsEmpty())
2080 ofn
.lpstrTitle
= temp
;
2081 ofn
.Flags
= OFN_OVERWRITEPROMPT
;
2083 sFilter
.LoadString(IDS_COMMONFILEFILTER
);
2084 TCHAR
* pszFilters
= new TCHAR
[sFilter
.GetLength()+4];
2085 _tcscpy_s (pszFilters
, sFilter
.GetLength()+4, sFilter
);
2086 // Replace '|' delimiters with '\0's
2087 TCHAR
*ptr
= pszFilters
+ _tcslen(pszFilters
); //set ptr at the NULL
2088 while (ptr
!= pszFilters
)
2094 ofn
.lpstrFilter
= pszFilters
;
2095 ofn
.nFilterIndex
= 1;
2097 // Display the Save dialog box.
2099 if (GetSaveFileName(&ofn
)==TRUE
)
2101 outputFile
= CString(ofn
.lpstrFile
);
2102 CAppUtils::CreateUnifiedDiff(origFile
, modifiedFile
, outputFile
, true);
2104 delete [] pszFilters
;
2108 void CMainFrame::OnUpdateViewLinediffbar(CCmdUI
*pCmdUI
)
2110 pCmdUI
->SetCheck(m_bLineDiff
);
2114 void CMainFrame::OnViewLinediffbar()
2116 m_bLineDiff
= !m_bLineDiff
;
2117 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
2118 m_wndLineDiffBar
.DocumentUpdated();
2119 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
2120 m_wndLocatorBar
.DocumentUpdated();
2123 void CMainFrame::OnUpdateViewLocatorbar(CCmdUI
*pCmdUI
)
2125 pCmdUI
->SetCheck(m_bLocatorBar
);
2129 void CMainFrame::OnViewLocatorbar()
2131 m_bLocatorBar
= !m_bLocatorBar
;
2132 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
2133 m_wndLocatorBar
.DocumentUpdated();
2134 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
2135 m_wndLineDiffBar
.DocumentUpdated();