1 // TortoiseMerge - a Diff/Patch program
\r
3 // Copyright (C) 2004-2009 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include "TortoiseMerge.h"
\r
21 #include "OpenDlg.h"
\r
23 #include "SysProgressDlg.h"
\r
24 #include "Settings.h"
\r
25 #include "MessageBox.h"
\r
26 #include "AppUtils.h"
\r
27 #include "PathUtils.h"
\r
28 #include "MainFrm.h"
\r
29 #include "LeftView.h"
\r
30 #include "RightView.h"
\r
31 #include "BottomView.h"
\r
32 #include "DiffColors.h"
\r
33 #include ".\mainfrm.h"
\r
36 #define new DEBUG_NEW
\r
41 const UINT CMainFrame::m_FindDialogMessage = RegisterWindowMessage(FINDMSGSTRING);
\r
43 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWndEx)
\r
45 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
\r
47 ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_OFF_2007_AQUA, &CMainFrame::OnApplicationLook)
\r
48 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_OFF_2007_AQUA, &CMainFrame::OnUpdateApplicationLook)
\r
49 // Global help commands
\r
50 ON_COMMAND(ID_HELP_FINDER, CFrameWndEx::OnHelpFinder)
\r
51 ON_COMMAND(ID_HELP, CFrameWndEx::OnHelp)
\r
52 ON_COMMAND(ID_CONTEXT_HELP, CFrameWndEx::OnContextHelp)
\r
53 ON_COMMAND(ID_DEFAULT_HELP, CFrameWndEx::OnHelpFinder)
\r
54 ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
\r
55 ON_COMMAND(ID_VIEW_WHITESPACES, OnViewWhitespaces)
\r
57 ON_COMMAND(ID_FILE_SAVE, OnFileSave)
\r
58 ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
\r
59 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave)
\r
60 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSaveAs)
\r
61 ON_COMMAND(ID_VIEW_ONEWAYDIFF, OnViewOnewaydiff)
\r
62 ON_UPDATE_COMMAND_UI(ID_VIEW_ONEWAYDIFF, OnUpdateViewOnewaydiff)
\r
63 ON_UPDATE_COMMAND_UI(ID_VIEW_WHITESPACES, OnUpdateViewWhitespaces)
\r
64 ON_COMMAND(ID_VIEW_OPTIONS, OnViewOptions)
\r
66 ON_COMMAND(ID_EDIT_FIND, OnEditFind)
\r
67 ON_REGISTERED_MESSAGE(m_FindDialogMessage, OnFindDialogMessage)
\r
68 ON_COMMAND(ID_EDIT_FINDNEXT, OnEditFindnext)
\r
69 ON_COMMAND(ID_EDIT_FINDPREV, OnEditFindprev)
\r
70 ON_COMMAND(ID_FILE_RELOAD, OnFileReload)
\r
71 ON_COMMAND(ID_VIEW_LINEDOWN, OnViewLinedown)
\r
72 ON_COMMAND(ID_VIEW_LINEUP, OnViewLineup)
\r
73 ON_UPDATE_COMMAND_UI(ID_EDIT_MARKASRESOLVED, OnUpdateMergeMarkasresolved)
\r
74 ON_COMMAND(ID_EDIT_MARKASRESOLVED, OnMergeMarkasresolved)
\r
75 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTCONFLICT, OnUpdateMergeNextconflict)
\r
76 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSCONFLICT, OnUpdateMergePreviousconflict)
\r
79 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
\r
80 ON_COMMAND(ID_VIEW_SWITCHLEFT, OnViewSwitchleft)
\r
81 ON_UPDATE_COMMAND_UI(ID_VIEW_SWITCHLEFT, OnUpdateViewSwitchleft)
\r
82 ON_COMMAND(ID_VIEW_LINELEFT, &CMainFrame::OnViewLineleft)
\r
83 ON_COMMAND(ID_VIEW_LINERIGHT, &CMainFrame::OnViewLineright)
\r
84 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILELIST, &CMainFrame::OnUpdateViewShowfilelist)
\r
85 ON_COMMAND(ID_VIEW_SHOWFILELIST, &CMainFrame::OnViewShowfilelist)
\r
86 ON_COMMAND(ID_EDIT_USETHEIRBLOCK, &CMainFrame::OnEditUseTheirs)
\r
87 ON_COMMAND(ID_EDIT_USEMYBLOCK, &CMainFrame::OnEditUseMine)
\r
88 ON_COMMAND(ID_EDIT_USETHEIRTHENMYBLOCK, &CMainFrame::OnEditUseTheirsThenMine)
\r
89 ON_COMMAND(ID_EDIT_USEMINETHENTHEIRBLOCK, &CMainFrame::OnEditUseMineThenTheirs)
\r
90 ON_COMMAND(ID_EDIT_UNDO, &CMainFrame::OnEditUndo)
\r
91 ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, &CMainFrame::OnUpdateEditUndo)
\r
92 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMINETHENTHEIRBLOCK, &CMainFrame::OnUpdateEditUseminethentheirblock)
\r
93 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMYBLOCK, &CMainFrame::OnUpdateEditUsemyblock)
\r
94 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRBLOCK, &CMainFrame::OnUpdateEditUsetheirblock)
\r
95 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRTHENMYBLOCK, &CMainFrame::OnUpdateEditUsetheirthenmyblock)
\r
96 ON_COMMAND(ID_VIEW_INLINEDIFFWORD, &CMainFrame::OnViewInlinediffword)
\r
97 ON_UPDATE_COMMAND_UI(ID_VIEW_INLINEDIFFWORD, &CMainFrame::OnUpdateViewInlinediffword)
\r
98 ON_UPDATE_COMMAND_UI(ID_EDIT_CREATEUNIFIEDDIFFFILE, &CMainFrame::OnUpdateEditCreateunifieddifffile)
\r
99 ON_COMMAND(ID_EDIT_CREATEUNIFIEDDIFFFILE, &CMainFrame::OnEditCreateunifieddifffile)
\r
100 ON_UPDATE_COMMAND_UI(ID_VIEW_LINEDIFFBAR, &CMainFrame::OnUpdateViewLinediffbar)
\r
101 ON_COMMAND(ID_VIEW_LINEDIFFBAR, &CMainFrame::OnViewLinediffbar)
\r
102 ON_UPDATE_COMMAND_UI(ID_VIEW_LOCATORBAR, &CMainFrame::OnUpdateViewLocatorbar)
\r
103 ON_COMMAND(ID_VIEW_LOCATORBAR, &CMainFrame::OnViewLocatorbar)
\r
104 ON_COMMAND(ID_EDIT_USELEFTBLOCK, &CMainFrame::OnEditUseleftblock)
\r
105 ON_UPDATE_COMMAND_UI(ID_EDIT_USELEFTBLOCK, &CMainFrame::OnUpdateEditUseleftblock)
\r
106 ON_COMMAND(ID_EDIT_USELEFTFILE, &CMainFrame::OnEditUseleftfile)
\r
107 ON_UPDATE_COMMAND_UI(ID_EDIT_USELEFTFILE, &CMainFrame::OnUpdateEditUseleftfile)
\r
108 ON_COMMAND(ID_EDIT_USEBLOCKFROMLEFTBEFORERIGHT, &CMainFrame::OnEditUseblockfromleftbeforeright)
\r
109 ON_UPDATE_COMMAND_UI(ID_EDIT_USEBLOCKFROMLEFTBEFORERIGHT, &CMainFrame::OnUpdateEditUseblockfromleftbeforeright)
\r
110 ON_COMMAND(ID_EDIT_USEBLOCKFROMRIGHTBEFORELEFT, &CMainFrame::OnEditUseblockfromrightbeforeleft)
\r
111 ON_UPDATE_COMMAND_UI(ID_EDIT_USEBLOCKFROMRIGHTBEFORELEFT, &CMainFrame::OnUpdateEditUseblockfromrightbeforeleft)
\r
114 static UINT indicators[] =
\r
116 ID_SEPARATOR, // status line indicator
\r
117 ID_INDICATOR_LEFTVIEW,
\r
118 ID_INDICATOR_RIGHTVIEW,
\r
119 ID_INDICATOR_BOTTOMVIEW,
\r
126 // CMainFrame construction/destruction
\r
128 CMainFrame::CMainFrame()
\r
130 m_pFindDialog = NULL;
\r
131 m_nSearchIndex = 0;
\r
132 m_bInitSplitter = FALSE;
\r
133 m_bOneWay = (0 != ((DWORD)CRegDWORD(_T("Software\\TortoiseMerge\\OnePane"))));
\r
134 m_bReversedPatch = FALSE;
\r
135 m_bHasConflicts = false;
\r
136 m_bInlineWordDiff = true;
\r
137 m_bLineDiff = true;
\r
138 m_bLocatorBar = true;
\r
139 m_nMoveMovesToIgnore = 0;
\r
140 theApp.m_nAppLook = theApp.GetInt(_T("ApplicationLook"), ID_VIEW_APPLOOK_VS_2005);
\r
143 CMainFrame::~CMainFrame()
\r
147 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
\r
149 if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
\r
152 OnApplicationLook(theApp.m_nAppLook);
\r
154 if (!m_wndMenuBar.Create(this))
\r
156 TRACE0("Failed to create menubar\n");
\r
157 return -1; // fail to create
\r
160 m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);
\r
162 // prevent the menu bar from taking the focus on activation
\r
163 CMFCPopupMenu::SetForceMenuFocus(FALSE);
\r
165 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY) ||
\r
166 !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
\r
168 TRACE0("Failed to create toolbar\n");
\r
169 return -1; // fail to create
\r
171 m_wndToolBar.SetWindowText(_T("Main"));
\r
173 if (!m_wndStatusBar.Create(this) ||
\r
174 !m_wndStatusBar.SetIndicators(indicators,
\r
175 sizeof(indicators)/sizeof(UINT)))
\r
177 TRACE0("Failed to create status bar\n");
\r
178 return -1; // fail to create
\r
181 if (!m_wndLocatorBar.Create(this, IDD_DIFFLOCATOR,
\r
182 CBRS_ALIGN_LEFT | CBRS_SIZE_FIXED, ID_VIEW_LOCATORBAR))
\r
184 TRACE0("Failed to create dialogbar\n");
\r
185 return -1; // fail to create
\r
187 if (!m_wndLineDiffBar.Create(this, IDD_LINEDIFF,
\r
188 CBRS_ALIGN_BOTTOM | CBRS_SIZE_FIXED, ID_VIEW_LINEDIFFBAR))
\r
190 TRACE0("Failed to create dialogbar\n");
\r
191 return -1; // fail to create
\r
193 m_wndLocatorBar.m_pMainFrm = this;
\r
194 m_wndLineDiffBar.m_pMainFrm = this;
\r
196 EnableDocking(CBRS_ALIGN_ANY);
\r
197 m_wndMenuBar.EnableDocking(CBRS_ALIGN_TOP);
\r
198 m_wndToolBar.EnableDocking(CBRS_ALIGN_TOP);
\r
199 DockPane(&m_wndMenuBar);
\r
200 DockPane(&m_wndToolBar);
\r
201 DockPane(&m_wndLocatorBar);
\r
202 DockPane(&m_wndLineDiffBar);
\r
203 ShowPane(&m_wndLocatorBar, true, false, true);
\r
204 ShowPane(&m_wndLineDiffBar, true, false, true);
\r
206 m_wndLocatorBar.EnableGripper(FALSE);
\r
207 m_wndLineDiffBar.EnableGripper(FALSE);
\r
212 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
\r
214 if( !CFrameWndEx::PreCreateWindow(cs) )
\r
219 void CMainFrame::OnApplicationLook(UINT id)
\r
223 theApp.m_nAppLook = id;
\r
225 switch (theApp.m_nAppLook)
\r
227 case ID_VIEW_APPLOOK_WIN_2000:
\r
228 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager));
\r
231 case ID_VIEW_APPLOOK_OFF_XP:
\r
232 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP));
\r
235 case ID_VIEW_APPLOOK_WIN_XP:
\r
236 CMFCVisualManagerWindows::m_b3DTabsXPTheme = TRUE;
\r
237 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
\r
240 case ID_VIEW_APPLOOK_OFF_2003:
\r
241 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003));
\r
242 CDockingManager::SetDockingMode(DT_SMART);
\r
245 case ID_VIEW_APPLOOK_VS_2005:
\r
246 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005));
\r
247 CDockingManager::SetDockingMode(DT_SMART);
\r
251 switch (theApp.m_nAppLook)
\r
253 case ID_VIEW_APPLOOK_OFF_2007_BLUE:
\r
254 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);
\r
257 case ID_VIEW_APPLOOK_OFF_2007_BLACK:
\r
258 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack);
\r
261 case ID_VIEW_APPLOOK_OFF_2007_SILVER:
\r
262 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver);
\r
265 case ID_VIEW_APPLOOK_OFF_2007_AQUA:
\r
266 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua);
\r
270 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
\r
271 CDockingManager::SetDockingMode(DT_SMART);
\r
274 RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE);
\r
276 theApp.WriteInt(_T("ApplicationLook"), theApp.m_nAppLook);
\r
279 void CMainFrame::OnUpdateApplicationLook(CCmdUI* pCmdUI)
\r
281 pCmdUI->SetRadio(theApp.m_nAppLook == pCmdUI->m_nID);
\r
285 // CMainFrame diagnostics
\r
288 void CMainFrame::AssertValid() const
\r
290 CFrameWndEx::AssertValid();
\r
293 void CMainFrame::Dump(CDumpContext& dc) const
\r
295 CFrameWndEx::Dump(dc);
\r
301 // CMainFrame message handlers
\r
304 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
\r
307 GetClientRect( &cr);
\r
310 // split into three panes:
\r
319 // create a splitter with 2 rows, 1 column
\r
320 if (!m_wndSplitter.CreateStatic(this, 2, 1))
\r
322 TRACE0("Failed to CreateStaticSplitter\n");
\r
326 // add the second splitter pane - which is a nested splitter with 2 columns
\r
327 if (!m_wndSplitter2.CreateStatic(
\r
328 &m_wndSplitter, // our parent window is the first splitter
\r
329 1, 2, // the new splitter is 1 row, 2 columns
\r
330 WS_CHILD | WS_VISIBLE | WS_BORDER, // style, WS_BORDER is needed
\r
331 m_wndSplitter.IdFromRowCol(0, 0)
\r
332 // new splitter is in the first row, 1st column of first splitter
\r
335 TRACE0("Failed to create nested splitter\n");
\r
338 // add the first splitter pane - the default view in row 0
\r
339 if (!m_wndSplitter.CreateView(1, 0,
\r
340 RUNTIME_CLASS(CBottomView), CSize(cr.Width(), cr.Height()), pContext))
\r
342 TRACE0("Failed to create first pane\n");
\r
345 m_pwndBottomView = (CBottomView *)m_wndSplitter.GetPane(1,0);
\r
346 m_pwndBottomView->m_pwndLocator = &m_wndLocatorBar;
\r
347 m_pwndBottomView->m_pwndLineDiffBar = &m_wndLineDiffBar;
\r
348 m_pwndBottomView->m_pwndStatusBar = &m_wndStatusBar;
\r
349 m_pwndBottomView->m_pMainFrame = this;
\r
351 // now create the two views inside the nested splitter
\r
353 if (!m_wndSplitter2.CreateView(0, 0,
\r
354 RUNTIME_CLASS(CLeftView), CSize(cr.Width()/2, cr.Height()/2), pContext))
\r
356 TRACE0("Failed to create second pane\n");
\r
359 m_pwndLeftView = (CLeftView *)m_wndSplitter2.GetPane(0,0);
\r
360 m_pwndLeftView->m_pwndLocator = &m_wndLocatorBar;
\r
361 m_pwndLeftView->m_pwndLineDiffBar = &m_wndLineDiffBar;
\r
362 m_pwndLeftView->m_pwndStatusBar = &m_wndStatusBar;
\r
363 m_pwndLeftView->m_pMainFrame = this;
\r
365 if (!m_wndSplitter2.CreateView(0, 1,
\r
366 RUNTIME_CLASS(CRightView), CSize(cr.Width()/2, cr.Height()/2), pContext))
\r
368 TRACE0("Failed to create third pane\n");
\r
371 m_pwndRightView = (CRightView *)m_wndSplitter2.GetPane(0,1);
\r
372 m_pwndRightView->m_pwndLocator = &m_wndLocatorBar;
\r
373 m_pwndRightView->m_pwndLineDiffBar = &m_wndLineDiffBar;
\r
374 m_pwndRightView->m_pwndStatusBar = &m_wndStatusBar;
\r
375 m_pwndRightView->m_pMainFrame = this;
\r
376 m_bInitSplitter = TRUE;
\r
378 m_dlgFilePatches.Create(IDD_FILEPATCHES, this);
\r
383 // Callback function
\r
384 BOOL CMainFrame::PatchFile(CString sFilePath, CString sVersion, BOOL bAutoPatch,BOOL bIsReview)
\r
386 //first, do a "dry run" of patching...
\r
387 if (!m_Patch.PatchFile(sFilePath))
\r
389 //patching not successful, so retrieve the
\r
390 //base file from version control and try
\r
393 CSysProgressDlg progDlg;
\r
394 sTemp.Format(IDS_GETVERSIONOFFILE, (LPCTSTR)sVersion);
\r
395 progDlg.SetLine(1, sTemp, true);
\r
396 progDlg.SetLine(2, sFilePath, true);
\r
397 sTemp.LoadString(IDS_GETVERSIONOFFILETITLE);
\r
398 progDlg.SetTitle(sTemp);
\r
399 progDlg.SetShowProgressBar(false);
\r
400 progDlg.SetAnimation(IDR_DOWNLOAD);
\r
401 progDlg.SetTime(FALSE);
\r
403 if(!m_Patch.m_IsGitPatch)
\r
404 progDlg.ShowModeless(this);
\r
406 CString sBaseFile = m_TempFiles.GetTempFilePath();
\r
407 if (!CAppUtils::GetVersionedFile(sFilePath, sVersion, sBaseFile, &progDlg, m_hWnd))
\r
411 sErrMsg.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND, (LPCTSTR)sVersion, (LPCTSTR)sFilePath);
\r
412 MessageBox(sErrMsg, NULL, MB_ICONERROR);
\r
416 CString sTempFile = m_TempFiles.GetTempFilePath();
\r
417 if (!m_Patch.PatchFile(sFilePath, sTempFile, sBaseFile))
\r
419 MessageBox(m_Patch.GetErrorMessage(), NULL, MB_ICONERROR);
\r
427 temp.Format(_T("%s Revision %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)sVersion);
\r
428 m_Data.m_baseFile.SetFileName(sBaseFile);
\r
429 m_Data.m_baseFile.SetDescriptiveName(temp);
\r
430 temp.Format(_T("%s %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)m_Data.m_sPatchPatched);
\r
431 m_Data.m_yourFile.SetFileName(sTempFile);
\r
432 m_Data.m_yourFile.SetDescriptiveName(temp);
\r
433 m_Data.m_theirFile.SetOutOfUse();
\r
434 m_Data.m_mergedFile.SetOutOfUse();
\r
438 temp.Format(_T("%s Revision %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)sVersion);
\r
439 m_Data.m_baseFile.SetFileName(sBaseFile);
\r
440 m_Data.m_baseFile.SetDescriptiveName(temp);
\r
441 temp.Format(_T("%s %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)m_Data.m_sPatchPatched);
\r
442 m_Data.m_theirFile.SetFileName(sTempFile);
\r
443 m_Data.m_theirFile.SetDescriptiveName(temp);
\r
444 m_Data.m_yourFile.SetFileName(sFilePath);
\r
445 m_Data.m_yourFile.SetDescriptiveName(CPathUtils::GetFileNameFromPath(sFilePath));
\r
446 m_Data.m_mergedFile.SetFileName(sFilePath);
\r
447 m_Data.m_mergedFile.SetDescriptiveName(CPathUtils::GetFileNameFromPath(sFilePath));
\r
449 TRACE(_T("comparing %s and %s\nagainst the base file %s\n"), (LPCTSTR)sTempFile, (LPCTSTR)sFilePath, (LPCTSTR)sBaseFile);
\r
455 //"dry run" was successful, so save the patched file somewhere...
\r
456 CString sTempFile = m_TempFiles.GetTempFilePath();
\r
457 if (!m_Patch.PatchFile(sFilePath, sTempFile))
\r
459 MessageBox(m_Patch.GetErrorMessage(), NULL, MB_ICONERROR);
\r
462 if (m_bReversedPatch)
\r
464 m_Data.m_baseFile.SetFileName(sTempFile);
\r
466 temp.Format(_T("%s %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)m_Data.m_sPatchPatched);
\r
467 m_Data.m_baseFile.SetDescriptiveName(temp);
\r
468 m_Data.m_yourFile.SetFileName(sFilePath);
\r
469 temp.Format(_T("%s %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)m_Data.m_sPatchOriginal);
\r
470 m_Data.m_yourFile.SetDescriptiveName(temp);
\r
471 m_Data.m_theirFile.SetOutOfUse();
\r
472 m_Data.m_mergedFile.SetOutOfUse();
\r
476 if (!PathFileExists(sFilePath))
\r
478 m_Data.m_baseFile.SetFileName(m_TempFiles.GetTempFilePath());
\r
479 m_Data.m_baseFile.CreateEmptyFile();
\r
483 m_Data.m_baseFile.SetFileName(sFilePath);
\r
485 CString sDescription;
\r
486 sDescription.Format(_T("%s %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)m_Data.m_sPatchOriginal);
\r
487 m_Data.m_baseFile.SetDescriptiveName(sDescription);
\r
488 m_Data.m_yourFile.SetFileName(sTempFile);
\r
490 temp.Format(_T("%s %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sFilePath), (LPCTSTR)m_Data.m_sPatchPatched);
\r
491 m_Data.m_yourFile.SetDescriptiveName(temp);
\r
492 m_Data.m_theirFile.SetOutOfUse();
\r
493 m_Data.m_mergedFile.SetFileName(sFilePath);
\r
495 TRACE(_T("comparing %s\nwith the patched result %s\n"), (LPCTSTR)sFilePath, (LPCTSTR)sTempFile);
\r
505 // Callback function
\r
506 BOOL CMainFrame::DiffFiles(CString sURL1, CString sRev1, CString sURL2, CString sRev2)
\r
508 CString tempfile1 = m_TempFiles.GetTempFilePath();
\r
509 CString tempfile2 = m_TempFiles.GetTempFilePath();
\r
511 ASSERT(tempfile1.Compare(tempfile2));
\r
514 CSysProgressDlg progDlg;
\r
515 sTemp.Format(IDS_GETVERSIONOFFILE, (LPCTSTR)sRev1);
\r
516 progDlg.SetLine(1, sTemp, true);
\r
517 progDlg.SetLine(2, sURL1, true);
\r
518 sTemp.LoadString(IDS_GETVERSIONOFFILETITLE);
\r
519 progDlg.SetTitle(sTemp);
\r
520 progDlg.SetShowProgressBar(true);
\r
521 progDlg.SetAnimation(IDR_DOWNLOAD);
\r
522 progDlg.SetTime(FALSE);
\r
523 progDlg.SetProgress(1,100);
\r
524 progDlg.ShowModeless(this);
\r
525 if (!CAppUtils::GetVersionedFile(sURL1, sRev1, tempfile1, &progDlg, m_hWnd))
\r
529 sErrMsg.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND, (LPCTSTR)sRev1, (LPCTSTR)sURL1);
\r
530 MessageBox(sErrMsg, NULL, MB_ICONERROR);
\r
533 sTemp.Format(IDS_GETVERSIONOFFILE, (LPCTSTR)sRev2);
\r
534 progDlg.SetLine(1, sTemp, true);
\r
535 progDlg.SetLine(2, sURL2, true);
\r
536 progDlg.SetProgress(50, 100);
\r
537 if (!CAppUtils::GetVersionedFile(sURL2, sRev2, tempfile2, &progDlg, m_hWnd))
\r
541 sErrMsg.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND, (LPCTSTR)sRev2, (LPCTSTR)sURL2);
\r
542 MessageBox(sErrMsg, NULL, MB_ICONERROR);
\r
545 progDlg.SetProgress(100,100);
\r
548 temp.Format(_T("%s Revision %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sURL1), (LPCTSTR)sRev1);
\r
549 m_Data.m_baseFile.SetFileName(tempfile1);
\r
550 m_Data.m_baseFile.SetDescriptiveName(temp);
\r
551 temp.Format(_T("%s Revision %s"), (LPCTSTR)CPathUtils::GetFileNameFromPath(sURL2), (LPCTSTR)sRev2);
\r
552 m_Data.m_yourFile.SetFileName(tempfile2);
\r
553 m_Data.m_yourFile.SetDescriptiveName(temp);
\r
560 void CMainFrame::OnFileOpen()
\r
562 if (CheckForSave()==IDCANCEL)
\r
565 if (dlg.DoModal()!=IDOK)
\r
569 m_dlgFilePatches.ShowWindow(SW_HIDE);
\r
570 m_dlgFilePatches.Init(NULL, NULL, CString(), NULL);
\r
571 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,
\r
572 (LPCTSTR)dlg.m_sUnifiedDiffFile, (LPCTSTR)dlg.m_sPatchDirectory);
\r
573 m_Data.m_baseFile.SetFileName(dlg.m_sBaseFile);
\r
574 m_Data.m_theirFile.SetFileName(dlg.m_sTheirFile);
\r
575 m_Data.m_yourFile.SetFileName(dlg.m_sYourFile);
\r
576 m_Data.m_sDiffFile = dlg.m_sUnifiedDiffFile;
\r
577 m_Data.m_sPatchPath = dlg.m_sPatchDirectory;
\r
578 m_Data.m_mergedFile.SetOutOfUse();
\r
579 g_crasher.AddFile((LPCSTR)(LPCTSTR)dlg.m_sBaseFile, (LPCSTR)(LPCTSTR)_T("Basefile"));
\r
580 g_crasher.AddFile((LPCSTR)(LPCTSTR)dlg.m_sTheirFile, (LPCSTR)(LPCTSTR)_T("Theirfile"));
\r
581 g_crasher.AddFile((LPCSTR)(LPCTSTR)dlg.m_sYourFile, (LPCSTR)(LPCTSTR)_T("Yourfile"));
\r
582 g_crasher.AddFile((LPCSTR)(LPCTSTR)dlg.m_sUnifiedDiffFile, (LPCSTR)(LPCTSTR)_T("Difffile"));
\r
584 if (!m_Data.IsBaseFileInUse() && m_Data.IsTheirFileInUse() && m_Data.IsYourFileInUse())
\r
586 // a diff between two files means "Yours" against "Base", not "Theirs" against "Yours"
\r
587 m_Data.m_baseFile.TransferDetailsFrom(m_Data.m_theirFile);
\r
589 if (m_Data.IsBaseFileInUse() && m_Data.IsTheirFileInUse() && !m_Data.IsYourFileInUse())
\r
591 // a diff between two files means "Yours" against "Base", not "Theirs" against "Base"
\r
592 m_Data.m_yourFile.TransferDetailsFrom(m_Data.m_theirFile);
\r
598 void CMainFrame::ClearViewNamesAndPaths() {
\r
599 m_pwndLeftView->m_sWindowName.Empty();
\r
600 m_pwndLeftView->m_sFullFilePath.Empty();
\r
601 m_pwndRightView->m_sWindowName.Empty();
\r
602 m_pwndRightView->m_sFullFilePath.Empty();
\r
603 m_pwndBottomView->m_sWindowName.Empty();
\r
604 m_pwndBottomView->m_sFullFilePath.Empty();
\r
607 bool CMainFrame::LoadViews(bool bRetainPosition)
\r
609 m_Data.SetBlame(m_bBlame);
\r
610 m_bHasConflicts = false;
\r
611 CBaseView* pwndActiveView = m_pwndLeftView;
\r
612 int nOldLine = m_pwndLeftView ? m_pwndLeftView->m_nTopLine : -1;
\r
613 int nOldLineNumber =
\r
614 m_pwndLeftView && m_pwndLeftView->m_pViewData ?
\r
615 m_pwndLeftView->m_pViewData->GetLineNumber(m_pwndLeftView->m_nTopLine) : -1;
\r
616 if (!m_Data.Load())
\r
618 ::MessageBox(NULL, m_Data.GetError(), _T("TortoiseMerge"), MB_ICONERROR);
\r
619 m_Data.m_mergedFile.SetOutOfUse();
\r
623 m_pwndRightView->UseCaret(false);
\r
624 m_pwndBottomView->UseCaret(false);
\r
626 if (!m_Data.IsBaseFileInUse())
\r
628 if (m_Data.IsYourFileInUse() && m_Data.IsTheirFileInUse())
\r
630 m_Data.m_baseFile.TransferDetailsFrom(m_Data.m_theirFile);
\r
632 else if ((!m_Data.m_sDiffFile.IsEmpty())&&(!m_Patch.OpenUnifiedDiffFile(m_Data.m_sDiffFile)))
\r
634 ClearViewNamesAndPaths();
\r
635 MessageBox(m_Patch.GetErrorMessage(), NULL, MB_ICONERROR);
\r
638 if (m_Patch.GetNumberOfFiles() > 0)
\r
640 CString firstpath = m_Patch.GetFilename(0);
\r
641 CString path=firstpath;
\r
642 path.Replace('/','\\');
\r
643 if ( !PathIsRelative(path) && !PathFileExists(path) )
\r
645 // The absolute path mentioned in the patch does not exist. Lets
\r
646 // try to find the correct relative path by stripping prefixes.
\r
647 BOOL bFound = m_Patch.StripPrefixes(m_Data.m_sPatchPath);
\r
648 CString strippedpath = m_Patch.GetFilename(0);
\r
652 msg.Format(IDS_WARNABSOLUTEPATHFOUND, (LPCTSTR)firstpath, (LPCTSTR)strippedpath);
\r
653 if (CMessageBox::Show(m_hWnd, msg, _T("TortoiseMerge"), MB_ICONQUESTION | MB_YESNO)==IDNO)
\r
659 msg.Format(IDS_WARNABSOLUTEPATHNOTFOUND, (LPCTSTR)firstpath);
\r
660 CMessageBox::Show(m_hWnd, msg, _T("TortoiseMerge"), MB_ICONEXCLAMATION);
\r
664 CString betterpatchpath = m_Patch.CheckPatchPath(m_Data.m_sPatchPath);
\r
665 if (betterpatchpath.CompareNoCase(m_Data.m_sPatchPath)!=0)
\r
668 msg.Format(IDS_WARNBETTERPATCHPATHFOUND, (LPCTSTR)m_Data.m_sPatchPath, (LPCTSTR)betterpatchpath);
\r
669 if (CMessageBox::Show(m_hWnd, msg, _T("TortoiseMerge"), MB_ICONQUESTION | MB_YESNO)==IDYES)
\r
670 m_Data.m_sPatchPath = betterpatchpath;
\r
672 m_dlgFilePatches.Init(&m_Patch, this, m_Data.m_sPatchPath, this);
\r
673 m_dlgFilePatches.ShowWindow(SW_SHOW);
\r
674 ClearViewNamesAndPaths();
\r
675 if (!m_wndSplitter.IsRowHidden(1))
\r
676 m_wndSplitter.HideRow(1);
\r
677 m_pwndLeftView->SetHidden(FALSE);
\r
678 m_pwndRightView->SetHidden(FALSE);
\r
679 m_pwndBottomView->SetHidden(TRUE);
\r
682 if (m_Data.IsBaseFileInUse() && !m_Data.IsYourFileInUse() && m_Data.IsTheirFileInUse())
\r
684 m_Data.m_yourFile.TransferDetailsFrom(m_Data.m_theirFile);
\r
686 if (m_Data.IsBaseFileInUse() && m_Data.IsYourFileInUse() && !m_Data.IsTheirFileInUse())
\r
688 //diff between YOUR and BASE
\r
689 m_pwndRightView->UseCaret();
\r
692 if (!m_wndSplitter2.IsColumnHidden(1))
\r
693 m_wndSplitter2.HideColumn(1);
\r
695 m_pwndLeftView->m_pViewData = &m_Data.m_YourBaseBoth;
\r
696 m_pwndLeftView->texttype = m_Data.m_arYourFile.GetUnicodeType();
\r
697 m_pwndLeftView->lineendings = m_Data.m_arYourFile.GetLineEndings();
\r
698 m_pwndLeftView->m_sWindowName = m_Data.m_baseFile.GetWindowName() + _T(" - ") + m_Data.m_yourFile.GetWindowName();
\r
699 m_pwndLeftView->m_sFullFilePath = m_Data.m_baseFile.GetFilename() + _T(" - ") + m_Data.m_yourFile.GetFilename();
\r
701 m_pwndRightView->m_pViewData = NULL;
\r
702 m_pwndBottomView->m_pViewData = NULL;
\r
704 if (!m_wndSplitter.IsRowHidden(1))
\r
705 m_wndSplitter.HideRow(1);
\r
706 m_pwndLeftView->SetHidden(FALSE);
\r
707 m_pwndRightView->SetHidden(TRUE);
\r
708 m_pwndBottomView->SetHidden(TRUE);
\r
709 ::SetWindowPos(m_pwndLeftView->m_hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
\r
713 pwndActiveView = m_pwndRightView;
\r
714 if (m_wndSplitter2.IsColumnHidden(1))
\r
715 m_wndSplitter2.ShowColumn();
\r
717 m_pwndLeftView->m_pViewData = &m_Data.m_YourBaseLeft;
\r
718 m_pwndLeftView->texttype = m_Data.m_arBaseFile.GetUnicodeType();
\r
719 m_pwndLeftView->lineendings = m_Data.m_arBaseFile.GetLineEndings();
\r
720 m_pwndLeftView->m_sWindowName = m_Data.m_baseFile.GetWindowName();
\r
721 m_pwndLeftView->m_sFullFilePath = m_Data.m_baseFile.GetFilename();
\r
723 m_pwndRightView->m_pViewData = &m_Data.m_YourBaseRight;
\r
724 m_pwndRightView->texttype = m_Data.m_arYourFile.GetUnicodeType();
\r
725 m_pwndRightView->lineendings = m_Data.m_arYourFile.GetLineEndings();
\r
726 m_pwndRightView->m_sWindowName = m_Data.m_yourFile.GetWindowName();
\r
727 m_pwndRightView->m_sFullFilePath = m_Data.m_yourFile.GetFilename();
\r
729 m_pwndBottomView->m_pViewData = NULL;
\r
731 if (!m_wndSplitter.IsRowHidden(1))
\r
732 m_wndSplitter.HideRow(1);
\r
733 m_pwndLeftView->SetHidden(FALSE);
\r
734 m_pwndRightView->SetHidden(FALSE);
\r
735 m_pwndBottomView->SetHidden(TRUE);
\r
738 else if (m_Data.IsBaseFileInUse() && m_Data.IsYourFileInUse() && m_Data.IsTheirFileInUse())
\r
740 //diff between THEIR, YOUR and BASE
\r
741 m_pwndBottomView->UseCaret();
\r
742 pwndActiveView = m_pwndBottomView;
\r
744 m_pwndLeftView->m_pViewData = &m_Data.m_TheirBaseBoth;
\r
745 m_pwndLeftView->texttype = m_Data.m_arTheirFile.GetUnicodeType();
\r
746 m_pwndLeftView->lineendings = m_Data.m_arTheirFile.GetLineEndings();
\r
747 m_pwndLeftView->m_sWindowName.LoadString(IDS_VIEWTITLE_THEIRS);
\r
748 m_pwndLeftView->m_sWindowName += _T(" - ") + m_Data.m_theirFile.GetWindowName();
\r
749 m_pwndLeftView->m_sFullFilePath = m_Data.m_theirFile.GetFilename();
\r
751 m_pwndRightView->m_pViewData = &m_Data.m_YourBaseBoth;
\r
752 m_pwndRightView->texttype = m_Data.m_arYourFile.GetUnicodeType();
\r
753 m_pwndRightView->lineendings = m_Data.m_arYourFile.GetLineEndings();
\r
754 m_pwndRightView->m_sWindowName.LoadString(IDS_VIEWTITLE_MINE);
\r
755 m_pwndRightView->m_sWindowName += _T(" - ") + m_Data.m_yourFile.GetWindowName();
\r
756 m_pwndRightView->m_sFullFilePath = m_Data.m_yourFile.GetFilename();
\r
758 m_pwndBottomView->m_pViewData = &m_Data.m_Diff3;
\r
759 m_pwndBottomView->texttype = m_Data.m_arTheirFile.GetUnicodeType();
\r
760 m_pwndBottomView->lineendings = m_Data.m_arTheirFile.GetLineEndings();
\r
761 m_pwndBottomView->m_sWindowName.LoadString(IDS_VIEWTITLE_MERGED);
\r
762 m_pwndBottomView->m_sWindowName += _T(" - ") + m_Data.m_mergedFile.GetWindowName();
\r
763 m_pwndBottomView->m_sFullFilePath = m_Data.m_mergedFile.GetFilename();
\r
765 if (m_wndSplitter2.IsColumnHidden(1))
\r
766 m_wndSplitter2.ShowColumn();
\r
767 if (m_wndSplitter.IsRowHidden(1))
\r
768 m_wndSplitter.ShowRow();
\r
769 m_pwndLeftView->SetHidden(FALSE);
\r
770 m_pwndRightView->SetHidden(FALSE);
\r
771 m_pwndBottomView->SetHidden(FALSE);
\r
772 // in three pane view, hide the line diff bar
\r
773 m_wndLineDiffBar.ShowPane(false, false, true);
\r
774 m_wndLineDiffBar.DocumentUpdated();
\r
776 if (!m_Data.m_mergedFile.InUse())
\r
778 m_Data.m_mergedFile.SetFileName(m_Data.m_yourFile.GetFilename());
\r
780 m_pwndLeftView->DocumentUpdated();
\r
781 m_pwndRightView->DocumentUpdated();
\r
782 m_pwndBottomView->DocumentUpdated();
\r
783 m_wndLocatorBar.DocumentUpdated();
\r
784 m_wndLineDiffBar.DocumentUpdated();
\r
786 SetActiveView(pwndActiveView);
\r
788 if (bRetainPosition && m_pwndLeftView->m_pViewData)
\r
790 int n = nOldLineNumber;
\r
792 n = m_pwndLeftView->m_pViewData->FindLineNumber(n);
\r
796 m_pwndLeftView->ScrollAllToLine(n);
\r
800 m_pwndLeftView->SetCaretPosition(p);
\r
804 bool bGoFirstDiff = (0 != (DWORD)CRegDWORD(_T("Software\\TortoiseMerge\\FirstDiffOnLoad"), TRUE));
\r
805 if (bGoFirstDiff) {
\r
806 pwndActiveView->GoToFirstDifference();
\r
807 // Ignore the first few Mouse Move messages, so that the line diff stays on
\r
808 // the first diff line until the user actually moves the mouse
\r
809 m_nMoveMovesToIgnore = 3;
\r
813 // Avoid incorrect rendering of active pane.
\r
814 m_pwndBottomView->ScrollToChar(0);
\r
815 m_pwndLeftView->ScrollToChar(0);
\r
816 m_pwndRightView->ScrollToChar(0);
\r
818 CUndo::GetInstance().Clear();
\r
822 void CMainFrame::UpdateLayout()
\r
824 if (m_bInitSplitter)
\r
826 CRect cr, rclocbar;
\r
827 GetWindowRect(&cr);
\r
828 int width = cr.Width();
\r
829 if (::IsWindow(m_wndLocatorBar) && m_wndLocatorBar.IsWindowVisible())
\r
831 m_wndLocatorBar.GetWindowRect(&rclocbar);
\r
832 width -= rclocbar.Width();
\r
834 m_wndSplitter.SetRowInfo(0, cr.Height()/2, 0);
\r
835 m_wndSplitter.SetRowInfo(1, cr.Height()/2, 0);
\r
836 m_wndSplitter.SetColumnInfo(0, width / 2, 50);
\r
837 m_wndSplitter2.SetRowInfo(0, cr.Height()/2, 0);
\r
838 m_wndSplitter2.SetColumnInfo(0, width / 2, 50);
\r
839 m_wndSplitter2.SetColumnInfo(1, width / 2, 50);
\r
841 m_wndSplitter.RecalcLayout();
\r
845 void CMainFrame::OnSize(UINT nType, int cx, int cy)
\r
847 if (m_bInitSplitter && nType != SIZE_MINIMIZED)
\r
851 CFrameWndEx::OnSize(nType, cx, cy);
\r
854 void CMainFrame::OnViewWhitespaces()
\r
856 CRegDWORD regViewWhitespaces = CRegDWORD(_T("Software\\TortoiseMerge\\ViewWhitespaces"), 1);
\r
857 BOOL bViewWhitespaces = regViewWhitespaces;
\r
858 if (m_pwndLeftView)
\r
859 bViewWhitespaces = m_pwndLeftView->m_bViewWhitespace;
\r
861 bViewWhitespaces = !bViewWhitespaces;
\r
862 regViewWhitespaces = bViewWhitespaces;
\r
863 if (m_pwndLeftView)
\r
865 m_pwndLeftView->m_bViewWhitespace = bViewWhitespaces;
\r
866 m_pwndLeftView->Invalidate();
\r
868 if (m_pwndRightView)
\r
870 m_pwndRightView->m_bViewWhitespace = bViewWhitespaces;
\r
871 m_pwndRightView->Invalidate();
\r
873 if (m_pwndBottomView)
\r
875 m_pwndBottomView->m_bViewWhitespace = bViewWhitespaces;
\r
876 m_pwndBottomView->Invalidate();
\r
880 void CMainFrame::OnUpdateViewWhitespaces(CCmdUI *pCmdUI)
\r
882 if (m_pwndLeftView)
\r
883 pCmdUI->SetCheck(m_pwndLeftView->m_bViewWhitespace);
\r
886 void CMainFrame::OnViewOnewaydiff()
\r
888 if (CheckForSave()==IDCANCEL)
\r
890 m_bOneWay = !m_bOneWay;
\r
893 // in one way view, hide the line diff bar
\r
894 m_wndLineDiffBar.ShowPane(false, false, true);
\r
895 m_wndLineDiffBar.DocumentUpdated();
\r
899 // restore the line diff bar
\r
900 m_wndLineDiffBar.ShowPane(m_bLineDiff, false, true);
\r
901 m_wndLineDiffBar.DocumentUpdated();
\r
902 m_wndLocatorBar.ShowPane(m_bLocatorBar, false, true);
\r
903 m_wndLocatorBar.DocumentUpdated();
\r
908 void CMainFrame::ShowDiffBar(bool bShow)
\r
912 // restore the line diff bar
\r
913 m_wndLineDiffBar.ShowPane(m_bLineDiff, false, true);
\r
914 m_wndLineDiffBar.DocumentUpdated();
\r
915 m_wndLocatorBar.ShowPane(m_bLocatorBar, false, true);
\r
916 m_wndLocatorBar.DocumentUpdated();
\r
920 // in one way view, hide the line diff bar
\r
921 m_wndLineDiffBar.ShowPane(false, false, true);
\r
922 m_wndLineDiffBar.DocumentUpdated();
\r
926 int CMainFrame::CheckResolved()
\r
928 //only in three way diffs can be conflicts!
\r
929 m_bHasConflicts = true;
\r
930 if (m_pwndBottomView->IsWindowVisible())
\r
932 if (m_pwndBottomView->m_pViewData)
\r
934 for (int i=0; i<m_pwndBottomView->m_pViewData->GetCount(); i++)
\r
936 if ((DIFFSTATE_CONFLICTED == m_pwndBottomView->m_pViewData->GetState(i))||
\r
937 (DIFFSTATE_CONFLICTED_IGNORED == m_pwndBottomView->m_pViewData->GetState(i)))
\r
942 m_bHasConflicts = false;
\r
946 int CMainFrame::SaveFile(const CString& sFilePath)
\r
948 CViewData * pViewData = NULL;
\r
949 CFileTextLines * pOriginFile = &m_Data.m_arBaseFile;
\r
950 if ((m_pwndBottomView)&&(m_pwndBottomView->IsWindowVisible()))
\r
952 pViewData = m_pwndBottomView->m_pViewData;
\r
955 else if ((m_pwndRightView)&&(m_pwndRightView->IsWindowVisible()))
\r
957 pViewData = m_pwndRightView->m_pViewData;
\r
958 if (m_Data.IsYourFileInUse())
\r
959 pOriginFile = &m_Data.m_arYourFile;
\r
960 else if (m_Data.IsTheirFileInUse())
\r
961 pOriginFile = &m_Data.m_arTheirFile;
\r
966 // nothing to save!
\r
969 if ((pViewData)&&(pOriginFile))
\r
971 CFileTextLines file;
\r
972 pOriginFile->CopySettings(&file);
\r
973 for (int i=0; i<pViewData->GetCount(); i++)
\r
975 //only copy non-removed lines
\r
976 DiffStates state = pViewData->GetState(i);
\r
979 case DIFFSTATE_CONFLICTED:
\r
980 case DIFFSTATE_CONFLICTED_IGNORED:
\r
987 } while((last<pViewData->GetCount()) && ((pViewData->GetState(last)==DIFFSTATE_CONFLICTED)||(pViewData->GetState(last)==DIFFSTATE_CONFLICTED_IGNORED)));
\r
988 file.Add(_T("<<<<<<< .mine"), EOL_NOENDING);
\r
989 for (int j=first; j<last; j++)
\r
991 file.Add(m_pwndRightView->m_pViewData->GetLine(j), m_pwndRightView->m_pViewData->GetLineEnding(j));
\r
993 file.Add(_T("======="), EOL_NOENDING);
\r
994 for (int j=first; j<last; j++)
\r
996 file.Add(m_pwndLeftView->m_pViewData->GetLine(j), m_pwndLeftView->m_pViewData->GetLineEnding(j));
\r
998 file.Add(_T(">>>>>>> .theirs"), EOL_NOENDING);
\r
1002 case DIFFSTATE_EMPTY:
\r
1003 case DIFFSTATE_CONFLICTEMPTY:
\r
1004 case DIFFSTATE_IDENTICALREMOVED:
\r
1005 case DIFFSTATE_REMOVED:
\r
1006 case DIFFSTATE_THEIRSREMOVED:
\r
1007 case DIFFSTATE_YOURSREMOVED:
\r
1008 case DIFFSTATE_CONFLICTRESOLVEDEMPTY:
\r
1009 // do not save removed lines
\r
1012 file.Add(pViewData->GetLine(i), pViewData->GetLineEnding(i));
\r
1016 if (!file.Save(sFilePath, false))
\r
1018 CMessageBox::Show(m_hWnd, file.GetErrorString(), _T("TortoiseMerge"), MB_ICONERROR);
\r
1021 m_dlgFilePatches.SetFileStatusAsPatched(sFilePath);
\r
1022 if (m_pwndBottomView)
\r
1023 m_pwndBottomView->SetModified(FALSE);
\r
1024 if (m_pwndRightView)
\r
1025 m_pwndRightView->SetModified(FALSE);
\r
1026 CUndo::GetInstance().MarkAsOriginalState();
\r
1027 return file.GetCount();
\r
1032 void CMainFrame::OnFileSave()
\r
1037 bool CMainFrame::FileSave(bool bCheckResolved /*=true*/)
\r
1039 if (!m_Data.m_mergedFile.InUse())
\r
1040 return FileSaveAs(bCheckResolved);
\r
1041 // check if the file has the readonly attribute set
\r
1042 bool bDoesNotExist = false;
\r
1043 DWORD fAttribs = GetFileAttributes(m_Data.m_mergedFile.GetFilename());
\r
1044 if ((fAttribs != INVALID_FILE_ATTRIBUTES)&&(fAttribs & FILE_ATTRIBUTE_READONLY))
\r
1045 return FileSaveAs(bCheckResolved);
\r
1046 if (fAttribs == INVALID_FILE_ATTRIBUTES)
\r
1048 bDoesNotExist = (GetLastError() == ERROR_FILE_NOT_FOUND);
\r
1050 if (bCheckResolved)
\r
1052 int nConflictLine = CheckResolved();
\r
1053 if (nConflictLine >= 0)
\r
1056 sTemp.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS, m_pwndBottomView->m_pViewData->GetLineNumber(nConflictLine)+1);
\r
1057 if (MessageBox(sTemp, 0, MB_ICONERROR | MB_YESNO)!=IDYES)
\r
1059 if (m_pwndBottomView)
\r
1060 m_pwndBottomView->GoToLine(nConflictLine);
\r
1065 if (((DWORD)CRegDWORD(_T("Software\\TortoiseMerge\\Backup"))) != 0)
\r
1067 MoveFileEx(m_Data.m_mergedFile.GetFilename(), m_Data.m_mergedFile.GetFilename() + _T(".bak"), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
\r
1069 if (SaveFile(m_Data.m_mergedFile.GetFilename())==0)
\r
1071 // file was saved with 0 lines!
\r
1072 // ask the user if the file should be deleted
\r
1074 sTemp.Format(IDS_DELETEWHENEMPTY, (LPCTSTR)m_Data.m_mergedFile.GetFilename());
\r
1075 if (CMessageBox::ShowCheck(m_hWnd, sTemp, _T("TortoiseMerge"), MB_YESNO, _T("DeleteFileWhenEmpty")) == IDYES)
\r
1077 DeleteFile(m_Data.m_mergedFile.GetFilename());
\r
1081 if (bDoesNotExist)
\r
1083 // call TortoiseProc to add the new file to version control
\r
1084 CString cmd = _T("\"") + CPathUtils::GetAppDirectory();
\r
1085 cmd += _T("TortoiseProc.exe\" /command:add /noui /path:\"");
\r
1086 cmd += m_Data.m_mergedFile.GetFilename() + _T("\"");
\r
1087 TCHAR * buf = new TCHAR[cmd.GetLength()+1];
\r
1088 _tcscpy_s(buf, cmd.GetLength()+1, cmd);
\r
1089 STARTUPINFO startup;
\r
1090 PROCESS_INFORMATION process;
\r
1091 memset(&startup, 0, sizeof(startup));
\r
1092 startup.cb = sizeof(startup);
\r
1093 memset(&process, 0, sizeof(process));
\r
1094 if (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)
\r
1098 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
\r
1099 FORMAT_MESSAGE_FROM_SYSTEM |
\r
1100 FORMAT_MESSAGE_IGNORE_INSERTS,
\r
1103 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
\r
1104 (LPTSTR) &lpMsgBuf,
\r
1108 MessageBox((LPCTSTR)lpMsgBuf, _T("TortoiseMerge"), MB_OK | MB_ICONINFORMATION);
\r
1109 LocalFree( lpMsgBuf );
\r
1113 CloseHandle(process.hThread);
\r
1114 CloseHandle(process.hProcess);
\r
1119 void CMainFrame::OnFileSaveAs()
\r
1124 bool CMainFrame::FileSaveAs(bool bCheckResolved /*=true*/)
\r
1126 if (bCheckResolved)
\r
1128 int nConflictLine = CheckResolved();
\r
1129 if (nConflictLine >= 0)
\r
1132 sTemp.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS, m_pwndBottomView->m_pViewData->GetLineNumber(nConflictLine)+1);
\r
1133 if (MessageBox(sTemp, 0, MB_ICONERROR | MB_YESNO)!=IDYES)
\r
1135 if (m_pwndBottomView)
\r
1136 m_pwndBottomView->GoToLine(nConflictLine);
\r
1141 OPENFILENAME ofn = {0}; // common dialog box structure
\r
1142 TCHAR szFile[MAX_PATH] = {0}; // buffer for file name
\r
1143 ofn.lStructSize = sizeof(OPENFILENAME);
\r
1144 ofn.hwndOwner = m_hWnd;
\r
1145 ofn.lpstrFile = szFile;
\r
1146 ofn.nMaxFile = sizeof(szFile)/sizeof(TCHAR);
\r
1148 temp.LoadString(IDS_SAVEASTITLE);
\r
1149 if (!temp.IsEmpty())
\r
1150 ofn.lpstrTitle = temp;
\r
1151 ofn.Flags = OFN_OVERWRITEPROMPT;
\r
1153 sFilter.LoadString(IDS_COMMONFILEFILTER);
\r
1154 TCHAR * pszFilters = new TCHAR[sFilter.GetLength()+4];
\r
1155 _tcscpy_s (pszFilters, sFilter.GetLength()+4, sFilter);
\r
1156 // Replace '|' delimiters with '\0's
\r
1157 TCHAR *ptr = pszFilters + _tcslen(pszFilters); //set ptr at the NULL
\r
1158 while (ptr != pszFilters)
\r
1164 ofn.lpstrFilter = pszFilters;
\r
1165 ofn.nFilterIndex = 1;
\r
1167 // Display the Open dialog box.
\r
1169 if (GetSaveFileName(&ofn)==TRUE)
\r
1171 sFile = CString(ofn.lpstrFile);
\r
1173 delete [] pszFilters;
\r
1176 delete [] pszFilters;
\r
1180 void CMainFrame::OnUpdateFileSave(CCmdUI *pCmdUI)
\r
1182 BOOL bEnable = FALSE;
\r
1183 if (m_Data.m_mergedFile.InUse())
\r
1185 if (m_pwndBottomView)
\r
1187 if ((m_pwndBottomView->IsWindowVisible())&&(m_pwndBottomView->m_pViewData))
\r
1192 if (m_pwndRightView)
\r
1194 if ((m_pwndRightView->IsWindowVisible())&&(m_pwndRightView->m_pViewData))
\r
1196 if (m_pwndRightView->IsModified() || (m_Data.m_yourFile.GetWindowName().Right(9).Compare(_T(": patched"))==0))
\r
1201 pCmdUI->Enable(bEnable);
\r
1204 void CMainFrame::OnUpdateFileSaveAs(CCmdUI *pCmdUI)
\r
1206 BOOL bEnable = FALSE;
\r
1207 if (m_pwndBottomView)
\r
1209 if ((m_pwndBottomView->IsWindowVisible())&&(m_pwndBottomView->m_pViewData))
\r
1214 if (m_pwndRightView)
\r
1216 if ((m_pwndRightView->IsWindowVisible())&&(m_pwndRightView->m_pViewData))
\r
1221 pCmdUI->Enable(bEnable);
\r
1225 void CMainFrame::OnUpdateViewOnewaydiff(CCmdUI *pCmdUI)
\r
1227 pCmdUI->SetCheck(!m_bOneWay);
\r
1228 BOOL bEnable = TRUE;
\r
1229 if (m_pwndBottomView)
\r
1231 if (m_pwndBottomView->IsWindowVisible())
\r
1234 pCmdUI->Enable(bEnable);
\r
1237 void CMainFrame::OnViewOptions()
\r
1240 sTemp.LoadString(IDS_SETTINGSTITLE);
\r
1241 CSettings dlg(sTemp);
\r
1243 if (dlg.IsReloadNeeded())
\r
1245 if (CheckForSave()==IDCANCEL)
\r
1247 CDiffColors::GetInstance().LoadRegistry();
\r
1251 CDiffColors::GetInstance().LoadRegistry();
\r
1252 if (m_pwndBottomView)
\r
1253 m_pwndBottomView->Invalidate();
\r
1254 if (m_pwndLeftView)
\r
1255 m_pwndLeftView->Invalidate();
\r
1256 if (m_pwndRightView)
\r
1257 m_pwndRightView->Invalidate();
\r
1260 void CMainFrame::OnClose()
\r
1262 if ((m_pFindDialog)&&(!m_pFindDialog->IsTerminating()))
\r
1264 m_pFindDialog->SendMessage(WM_CLOSE);
\r
1268 if (((m_pwndBottomView)&&(m_pwndBottomView->IsModified())) ||
\r
1269 ((m_pwndRightView)&&(m_pwndRightView->IsModified())))
\r
1272 sTemp.LoadString(IDS_ASKFORSAVE);
\r
1273 ret = MessageBox(sTemp, 0, MB_YESNOCANCEL | MB_ICONQUESTION);
\r
1280 if ((ret == IDNO)||(ret == IDYES))
\r
1282 WINDOWPLACEMENT wp;
\r
1284 // before it is destroyed, save the position of the window
\r
1285 wp.length = sizeof wp;
\r
1287 if (GetWindowPlacement(&wp))
\r
1291 // never restore to Iconic state
\r
1292 wp.showCmd = SW_SHOW ;
\r
1294 if ((wp.flags & WPF_RESTORETOMAXIMIZED) != 0)
\r
1295 // if maximized and maybe iconic restore maximized state
\r
1296 wp.showCmd = SW_SHOWMAXIMIZED ;
\r
1298 // and write it to the .INI file
\r
1299 WriteWindowPlacement(&wp);
\r
1301 __super::OnClose();
\r
1305 void CMainFrame::OnEditFind()
\r
1307 if (m_pFindDialog)
\r
1313 // start searching from the start again
\r
1314 // if no line is selected, otherwise start from
\r
1315 // the selected line
\r
1316 m_nSearchIndex = FindSearchStart(0);
\r
1317 m_pFindDialog = new CFindDlg();
\r
1318 m_pFindDialog->Create(this);
\r
1322 LRESULT CMainFrame::OnFindDialogMessage(WPARAM /*wParam*/, LPARAM /*lParam*/)
\r
1324 ASSERT(m_pFindDialog != NULL);
\r
1326 if (m_pFindDialog->IsTerminating())
\r
1328 // invalidate the handle identifying the dialog box.
\r
1329 m_pFindDialog = NULL;
\r
1333 if(m_pFindDialog->FindNext())
\r
1335 //read data from dialog
\r
1336 m_sFindText = m_pFindDialog->GetFindString();
\r
1337 m_bMatchCase = (m_pFindDialog->MatchCase() == TRUE);
\r
1338 m_bLimitToDiff = m_pFindDialog->LimitToDiffs();
\r
1339 m_bWholeWord = m_pFindDialog->WholeWord();
\r
1347 bool CharIsDelimiter(const CString& ch)
\r
1349 CString delimiters(_T(" .,:;=+-*/\\\n\t()[]<>@"));
\r
1350 return delimiters.Find(ch) >= 0;
\r
1353 bool CMainFrame::StringFound(const CString& str)const
\r
1355 int nSubStringStartIdx = str.Find(m_sFindText);
\r
1356 bool bStringFound = (nSubStringStartIdx >= 0);
\r
1357 if (bStringFound && m_bWholeWord)
\r
1359 if (nSubStringStartIdx)
\r
1360 bStringFound = CharIsDelimiter(str.Mid(nSubStringStartIdx-1,1));
\r
1364 int nEndIndex = nSubStringStartIdx + m_sFindText.GetLength();
\r
1365 if (str.GetLength() > nEndIndex)
\r
1366 bStringFound = CharIsDelimiter(str.Mid(nEndIndex, 1));
\r
1369 return bStringFound;
\r
1372 void CMainFrame::OnEditFindprev()
\r
1374 Search(SearchPrevious);
\r
1377 void CMainFrame::OnEditFindnext()
\r
1379 Search(SearchNext);
\r
1382 void CMainFrame::Search(SearchDirection srchDir)
\r
1384 if (m_sFindText.IsEmpty())
\r
1387 if ((m_pwndLeftView)&&(m_pwndLeftView->m_pViewData))
\r
1389 bool bFound = FALSE;
\r
1394 DiffStates leftstate = DIFFSTATE_NORMAL;
\r
1395 DiffStates rightstate = DIFFSTATE_NORMAL;
\r
1396 DiffStates bottomstate = DIFFSTATE_NORMAL;
\r
1399 m_nSearchIndex = FindSearchStart(m_nSearchIndex);
\r
1401 if (m_nSearchIndex >= m_pwndLeftView->m_pViewData->GetCount())
\r
1402 m_nSearchIndex = 0;
\r
1403 if (srchDir == SearchPrevious)
\r
1405 // SearchIndex points 1 past where we found the last match,
\r
1406 // so if we are searching backwards we need to adjust accordingly
\r
1407 m_nSearchIndex -= 2;
\r
1408 // if at the top, start again from the end
\r
1409 if (m_nSearchIndex < 0)
\r
1410 m_nSearchIndex += m_pwndLeftView->m_pViewData->GetCount();
\r
1412 const int idxLimits[2][2][2]={{{m_nSearchIndex, m_pwndLeftView->m_pViewData->GetCount()},
\r
1413 {0, m_nSearchIndex}},
\r
1414 {{m_nSearchIndex, -1},
\r
1415 {m_pwndLeftView->m_pViewData->GetCount()-1, m_nSearchIndex}}};
\r
1416 const int offsets[2]={+1, -1};
\r
1418 for (int j=0; j != 2 && !bFound; ++j)
\r
1420 for (i=idxLimits[srchDir][j][0]; i != idxLimits[srchDir][j][1]; i += offsets[srchDir])
\r
1422 left = m_pwndLeftView->m_pViewData->GetLine(i);
\r
1423 leftstate = m_pwndLeftView->m_pViewData->GetState(i);
\r
1424 if ((!m_bOneWay)&&(m_pwndRightView->m_pViewData))
\r
1426 right = m_pwndRightView->m_pViewData->GetLine(i);
\r
1427 rightstate = m_pwndRightView->m_pViewData->GetState(i);
\r
1429 if ((m_pwndBottomView)&&(m_pwndBottomView->m_pViewData))
\r
1431 bottom = m_pwndBottomView->m_pViewData->GetLine(i);
\r
1432 bottomstate = m_pwndBottomView->m_pViewData->GetState(i);
\r
1435 if (!m_bMatchCase)
\r
1437 left = left.MakeLower();
\r
1438 right = right.MakeLower();
\r
1439 bottom = bottom.MakeLower();
\r
1440 m_sFindText = m_sFindText.MakeLower();
\r
1442 if (StringFound(left))
\r
1444 if ((!m_bLimitToDiff)||(leftstate != DIFFSTATE_NORMAL))
\r
1450 else if (StringFound(right))
\r
1452 if ((!m_bLimitToDiff)||(rightstate != DIFFSTATE_NORMAL))
\r
1458 else if (StringFound(bottom))
\r
1460 if ((!m_bLimitToDiff)||(bottomstate != DIFFSTATE_NORMAL))
\r
1470 m_nSearchIndex = i;
\r
1471 m_pwndLeftView->GoToLine(m_nSearchIndex);
\r
1472 if (StringFound(left))
\r
1474 m_pwndLeftView->SetFocus();
\r
1475 m_pwndLeftView->HiglightLines(m_nSearchIndex);
\r
1477 else if (StringFound(right))
\r
1479 m_pwndRightView->SetFocus();
\r
1480 m_pwndRightView->HiglightLines(m_nSearchIndex);
\r
1482 else if (StringFound(bottom))
\r
1484 m_pwndBottomView->SetFocus();
\r
1485 m_pwndBottomView->HiglightLines(m_nSearchIndex);
\r
1490 m_nSearchIndex = 0;
\r
1495 int CMainFrame::FindSearchStart(int nDefault)
\r
1497 // TortoiseMerge doesn't have a cursor which we could use to
\r
1498 // anchor the search on.
\r
1499 // Instead we use a line that is selected.
\r
1500 // If however no line is selected, use the default line (which could
\r
1501 // be the top of the document for a new search, or the line where the
\r
1502 // search was successful on)
\r
1503 int nLine = nDefault;
\r
1504 int nSelStart = 0;
\r
1506 if (m_pwndLeftView)
\r
1508 if (m_pwndLeftView->GetSelection(nSelStart, nSelEnd))
\r
1510 if (nSelStart == nSelEnd)
\r
1511 nLine = nSelStart;
\r
1514 else if ((nLine == nDefault)&&(m_pwndRightView))
\r
1516 if (m_pwndRightView->GetSelection(nSelStart, nSelEnd))
\r
1518 if (nSelStart == nSelEnd)
\r
1519 nLine = nSelStart;
\r
1522 else if ((nLine == nDefault)&&(m_pwndBottomView))
\r
1524 if (m_pwndBottomView->GetSelection(nSelStart, nSelEnd))
\r
1526 if (nSelStart == nSelEnd)
\r
1527 nLine = nSelStart;
\r
1533 void CMainFrame::OnViewLinedown()
\r
1535 if (m_pwndLeftView)
\r
1536 m_pwndLeftView->ScrollToLine(m_pwndLeftView->m_nTopLine+1);
\r
1537 if (m_pwndRightView)
\r
1538 m_pwndRightView->ScrollToLine(m_pwndRightView->m_nTopLine+1);
\r
1539 if (m_pwndBottomView)
\r
1540 m_pwndBottomView->ScrollToLine(m_pwndBottomView->m_nTopLine+1);
\r
1541 m_wndLocatorBar.Invalidate();
\r
1544 void CMainFrame::OnViewLineup()
\r
1546 if (m_pwndLeftView)
\r
1547 m_pwndLeftView->ScrollToLine(m_pwndLeftView->m_nTopLine-1);
\r
1548 if (m_pwndRightView)
\r
1549 m_pwndRightView->ScrollToLine(m_pwndRightView->m_nTopLine-1);
\r
1550 if (m_pwndBottomView)
\r
1551 m_pwndBottomView->ScrollToLine(m_pwndBottomView->m_nTopLine-1);
\r
1552 m_wndLocatorBar.Invalidate();
\r
1555 void CMainFrame::OnViewLineleft()
\r
1557 if (m_pwndLeftView)
\r
1558 m_pwndLeftView->ScrollSide(-1);
\r
1559 if (m_pwndRightView)
\r
1560 m_pwndRightView->ScrollSide(-1);
\r
1561 if (m_pwndBottomView)
\r
1562 m_pwndBottomView->ScrollSide(-1);
\r
1565 void CMainFrame::OnViewLineright()
\r
1567 if (m_pwndLeftView)
\r
1568 m_pwndLeftView->ScrollSide(1);
\r
1569 if (m_pwndRightView)
\r
1570 m_pwndRightView->ScrollSide(1);
\r
1571 if (m_pwndBottomView)
\r
1572 m_pwndBottomView->ScrollSide(1);
\r
1575 void CMainFrame::OnEditUseTheirs()
\r
1577 if (m_pwndBottomView)
\r
1578 m_pwndBottomView->UseTheirTextBlock();
\r
1580 void CMainFrame::OnUpdateEditUsetheirblock(CCmdUI *pCmdUI)
\r
1582 int nSelBlockStart = -1;
\r
1583 int nSelBlockEnd = -1;
\r
1584 if (m_pwndBottomView)
\r
1585 m_pwndBottomView->GetSelection(nSelBlockStart, nSelBlockEnd);
\r
1586 pCmdUI->Enable((nSelBlockStart >= 0)&&(nSelBlockEnd >= 0));
\r
1590 void CMainFrame::OnEditUseMine()
\r
1592 if (m_pwndBottomView)
\r
1593 m_pwndBottomView->UseMyTextBlock();
\r
1595 void CMainFrame::OnUpdateEditUsemyblock(CCmdUI *pCmdUI)
\r
1597 int nSelBlockStart = -1;
\r
1598 int nSelBlockEnd = -1;
\r
1599 if (m_pwndBottomView)
\r
1600 m_pwndBottomView->GetSelection(nSelBlockStart, nSelBlockEnd);
\r
1601 pCmdUI->Enable((nSelBlockStart >= 0)&&(nSelBlockEnd >= 0));
\r
1605 void CMainFrame::OnEditUseTheirsThenMine()
\r
1607 if (m_pwndBottomView)
\r
1608 m_pwndBottomView->UseTheirThenMyTextBlock();
\r
1610 void CMainFrame::OnUpdateEditUsetheirthenmyblock(CCmdUI *pCmdUI)
\r
1612 int nSelBlockStart = -1;
\r
1613 int nSelBlockEnd = -1;
\r
1614 if (m_pwndBottomView)
\r
1615 m_pwndBottomView->GetSelection(nSelBlockStart, nSelBlockEnd);
\r
1616 pCmdUI->Enable((nSelBlockStart >= 0)&&(nSelBlockEnd >= 0));
\r
1620 void CMainFrame::OnEditUseMineThenTheirs()
\r
1622 if (m_pwndBottomView)
\r
1623 m_pwndBottomView->UseMyThenTheirTextBlock();
\r
1625 void CMainFrame::OnUpdateEditUseminethentheirblock(CCmdUI *pCmdUI)
\r
1627 int nSelBlockStart = -1;
\r
1628 int nSelBlockEnd = -1;
\r
1629 if (m_pwndBottomView)
\r
1630 m_pwndBottomView->GetSelection(nSelBlockStart, nSelBlockEnd);
\r
1631 pCmdUI->Enable((nSelBlockStart >= 0)&&(nSelBlockEnd >= 0));
\r
1634 void CMainFrame::OnEditUseleftblock()
\r
1636 if (m_pwndRightView)
\r
1637 m_pwndRightView->UseBlock();
\r
1640 void CMainFrame::OnUpdateEditUseleftblock(CCmdUI *pCmdUI)
\r
1642 pCmdUI->Enable(m_pwndRightView && m_pwndRightView->IsWindowVisible() && m_pwndRightView->HasCaret() && m_pwndRightView->HasSelection());
\r
1645 void CMainFrame::OnEditUseleftfile()
\r
1647 if (m_pwndRightView)
\r
1648 m_pwndRightView->UseFile();
\r
1651 void CMainFrame::OnUpdateEditUseleftfile(CCmdUI *pCmdUI)
\r
1653 pCmdUI->Enable(m_pwndRightView && m_pwndRightView->IsWindowVisible() && m_pwndRightView->HasCaret());
\r
1656 void CMainFrame::OnEditUseblockfromleftbeforeright()
\r
1658 if (m_pwndRightView)
\r
1659 m_pwndRightView->UseLeftBeforeRight();
\r
1662 void CMainFrame::OnUpdateEditUseblockfromleftbeforeright(CCmdUI *pCmdUI)
\r
1664 pCmdUI->Enable(m_pwndRightView && m_pwndRightView->IsWindowVisible() && m_pwndRightView->HasCaret() && m_pwndRightView->HasSelection());
\r
1667 void CMainFrame::OnEditUseblockfromrightbeforeleft()
\r
1669 if (m_pwndRightView)
\r
1670 m_pwndRightView->UseRightBeforeLeft();
\r
1673 void CMainFrame::OnUpdateEditUseblockfromrightbeforeleft(CCmdUI *pCmdUI)
\r
1675 pCmdUI->Enable(m_pwndRightView && m_pwndRightView->IsWindowVisible() && m_pwndRightView->HasCaret() && m_pwndRightView->HasSelection());
\r
1679 void CMainFrame::OnFileReload()
\r
1681 if (CheckForSave()==IDCANCEL)
\r
1683 CDiffColors::GetInstance().LoadRegistry();
\r
1687 void CMainFrame::ActivateFrame(int nCmdShow)
\r
1689 // nCmdShow is the normal show mode this frame should be in
\r
1690 // translate default nCmdShow (-1)
\r
1691 if (nCmdShow == -1)
\r
1693 if (!IsWindowVisible())
\r
1694 nCmdShow = SW_SHOWNORMAL;
\r
1695 else if (IsIconic())
\r
1696 nCmdShow = SW_RESTORE;
\r
1699 // bring to top before showing
\r
1700 BringToTop(nCmdShow);
\r
1702 if (nCmdShow != -1)
\r
1704 // show the window as specified
\r
1705 WINDOWPLACEMENT wp;
\r
1707 if ( !ReadWindowPlacement(&wp) )
\r
1709 ShowWindow(nCmdShow);
\r
1713 if ( nCmdShow != SW_SHOWNORMAL )
\r
1714 wp.showCmd = nCmdShow;
\r
1716 SetWindowPlacement(&wp);
\r
1719 // and finally, bring to top after showing
\r
1720 BringToTop(nCmdShow);
\r
1725 BOOL CMainFrame::ReadWindowPlacement(WINDOWPLACEMENT * pwp)
\r
1727 CRegString placement = CRegString(_T("Software\\TortoiseMerge\\WindowPos"));
\r
1728 CString sPlacement = placement;
\r
1729 if (sPlacement.IsEmpty())
\r
1731 int nRead = _stscanf_s(sPlacement, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
\r
1732 &pwp->flags, &pwp->showCmd,
\r
1733 &pwp->ptMinPosition.x, &pwp->ptMinPosition.y,
\r
1734 &pwp->ptMaxPosition.x, &pwp->ptMaxPosition.y,
\r
1735 &pwp->rcNormalPosition.left, &pwp->rcNormalPosition.top,
\r
1736 &pwp->rcNormalPosition.right, &pwp->rcNormalPosition.bottom);
\r
1737 if ( nRead != 10 )
\r
1739 pwp->length = sizeof(WINDOWPLACEMENT);
\r
1744 void CMainFrame::WriteWindowPlacement(WINDOWPLACEMENT * pwp)
\r
1746 CRegString placement = CRegString(_T("Software\\TortoiseMerge\\WindowPos"));
\r
1747 TCHAR szBuffer[sizeof("-32767")*8 + sizeof("65535")*2];
\r
1750 _stprintf_s(szBuffer, sizeof("-32767")*8 + sizeof("65535")*2, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
\r
1751 pwp->flags, pwp->showCmd,
\r
1752 pwp->ptMinPosition.x, pwp->ptMinPosition.y,
\r
1753 pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
\r
1754 pwp->rcNormalPosition.left, pwp->rcNormalPosition.top,
\r
1755 pwp->rcNormalPosition.right, pwp->rcNormalPosition.bottom);
\r
1756 placement = szBuffer;
\r
1759 void CMainFrame::OnUpdateMergeMarkasresolved(CCmdUI *pCmdUI)
\r
1761 if (pCmdUI == NULL)
\r
1763 BOOL bEnable = FALSE;
\r
1764 if ((!m_bReadOnly)&&(m_Data.m_mergedFile.InUse()))
\r
1766 if (m_pwndBottomView)
\r
1768 if ((m_pwndBottomView->IsWindowVisible())&&(m_pwndBottomView->m_pViewData))
\r
1774 pCmdUI->Enable(bEnable);
\r
1777 void CMainFrame::OnMergeMarkasresolved()
\r
1779 int nConflictLine = CheckResolved();
\r
1780 if (nConflictLine >= 0)
\r
1783 sTemp.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS, m_pwndBottomView->m_pViewData->GetLineNumber(nConflictLine)+1);
\r
1784 if (MessageBox(sTemp, 0, MB_ICONERROR | MB_YESNO)!=IDYES)
\r
1786 if (m_pwndBottomView)
\r
1787 m_pwndBottomView->GoToLine(nConflictLine);
\r
1791 // now check if the file has already been saved and if not, save it.
\r
1792 if (m_Data.m_mergedFile.InUse())
\r
1794 if (m_pwndBottomView)
\r
1796 if ((m_pwndBottomView->IsWindowVisible())&&(m_pwndBottomView->m_pViewData))
\r
1805 BOOL CMainFrame::MarkAsResolved()
\r
1809 if ((m_pwndBottomView)&&(m_pwndBottomView->IsWindowVisible()))
\r
1811 TCHAR buf[MAX_PATH*3];
\r
1812 GetModuleFileName(NULL, buf, MAX_PATH);
\r
1813 TCHAR * end = _tcsrchr(buf, '\\');
\r
1816 _tcscat_s(buf, MAX_PATH*3, _T("TortoiseProc.exe /command:resolve /path:\""));
\r
1817 _tcscat_s(buf, MAX_PATH*3, m_Data.m_mergedFile.GetFilename());
\r
1818 _tcscat_s(buf, MAX_PATH*3, _T("\" /closeonend:1 /noquestion /skipcheck"));
\r
1819 STARTUPINFO startup;
\r
1820 PROCESS_INFORMATION process;
\r
1821 memset(&startup, 0, sizeof(startup));
\r
1822 startup.cb = sizeof(startup);
\r
1823 memset(&process, 0, sizeof(process));
\r
1824 if (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)
\r
1827 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
\r
1828 FORMAT_MESSAGE_FROM_SYSTEM |
\r
1829 FORMAT_MESSAGE_IGNORE_INSERTS,
\r
1832 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
\r
1833 (LPTSTR) &lpMsgBuf,
\r
1837 MessageBox((LPCTSTR)lpMsgBuf, _T("TortoiseMerge"), MB_OK | MB_ICONINFORMATION);
\r
1838 LocalFree( lpMsgBuf );
\r
1841 CloseHandle(process.hThread);
\r
1842 CloseHandle(process.hProcess);
\r
1849 void CMainFrame::OnUpdateMergeNextconflict(CCmdUI *pCmdUI)
\r
1851 pCmdUI->Enable(m_bHasConflicts);
\r
1854 void CMainFrame::OnUpdateMergePreviousconflict(CCmdUI *pCmdUI)
\r
1856 pCmdUI->Enable(m_bHasConflicts);
\r
1859 void CMainFrame::OnMoving(UINT fwSide, LPRECT pRect)
\r
1861 // if the pathfilelist dialog is attached to the mainframe,
\r
1862 // move it along with the mainframe
\r
1863 if (::IsWindow(m_dlgFilePatches.m_hWnd))
\r
1866 m_dlgFilePatches.GetWindowRect(&patchrect);
\r
1867 if (::IsWindow(m_hWnd))
\r
1870 GetWindowRect(&thisrect);
\r
1871 if (patchrect.right == thisrect.left)
\r
1873 m_dlgFilePatches.SetWindowPos(NULL, patchrect.left - (thisrect.left - pRect->left), patchrect.top - (thisrect.top - pRect->top),
\r
1874 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
\r
1878 __super::OnMoving(fwSide, pRect);
\r
1881 void CMainFrame::OnUpdateEditCopy(CCmdUI *pCmdUI)
\r
1883 BOOL bShow = FALSE;
\r
1884 if ((m_pwndBottomView)&&(m_pwndBottomView->HasSelection()))
\r
1886 if ((m_pwndRightView)&&(m_pwndRightView->HasSelection()))
\r
1888 if ((m_pwndLeftView)&&(m_pwndLeftView->HasSelection()))
\r
1890 pCmdUI->Enable(bShow);
\r
1893 void CMainFrame::OnViewSwitchleft()
\r
1896 if (((m_pwndBottomView)&&(m_pwndBottomView->IsModified())) ||
\r
1897 ((m_pwndRightView)&&(m_pwndRightView->IsModified())))
\r
1900 sTemp.LoadString(IDS_ASKFORSAVE);
\r
1901 ret = MessageBox(sTemp, 0, MB_YESNOCANCEL | MB_ICONQUESTION);
\r
1908 if ((ret == IDNO)||(ret == IDYES))
\r
1910 CWorkingFile file = m_Data.m_baseFile;
\r
1911 m_Data.m_baseFile = m_Data.m_yourFile;
\r
1912 m_Data.m_yourFile = file;
\r
1913 if (m_Data.m_mergedFile.GetFilename().CompareNoCase(m_Data.m_yourFile.GetFilename())==0)
\r
1915 m_Data.m_mergedFile = m_Data.m_baseFile;
\r
1917 else if (m_Data.m_mergedFile.GetFilename().CompareNoCase(m_Data.m_baseFile.GetFilename())==0)
\r
1919 m_Data.m_mergedFile = m_Data.m_yourFile;
\r
1925 void CMainFrame::OnUpdateViewSwitchleft(CCmdUI *pCmdUI)
\r
1927 BOOL bEnable = TRUE;
\r
1928 if (m_pwndBottomView)
\r
1930 if (m_pwndBottomView->IsWindowVisible())
\r
1933 pCmdUI->Enable(bEnable);
\r
1937 void CMainFrame::OnUpdateViewShowfilelist(CCmdUI *pCmdUI)
\r
1939 if (m_dlgFilePatches.HasFiles())
\r
1941 pCmdUI->Enable(true);
\r
1944 pCmdUI->Enable(false);
\r
1945 pCmdUI->SetCheck(m_dlgFilePatches.IsWindowVisible());
\r
1948 void CMainFrame::OnViewShowfilelist()
\r
1950 m_dlgFilePatches.ShowWindow(m_dlgFilePatches.IsWindowVisible() ? SW_HIDE : SW_SHOW);
\r
1953 void CMainFrame::OnEditUndo()
\r
1955 if (CUndo::GetInstance().CanUndo())
\r
1957 CUndo::GetInstance().Undo(m_pwndLeftView, m_pwndRightView, m_pwndBottomView);
\r
1962 void CMainFrame::OnUpdateEditUndo(CCmdUI *pCmdUI)
\r
1964 pCmdUI->Enable(CUndo::GetInstance().CanUndo());
\r
1967 int CMainFrame::CheckForSave()
\r
1970 if (((m_pwndBottomView)&&(m_pwndBottomView->IsModified())) ||
\r
1971 ((m_pwndRightView)&&(m_pwndRightView->IsModified())))
\r
1974 sTemp.LoadString(IDS_WARNMODIFIEDLOOSECHANGES);
\r
1975 ret = MessageBox(sTemp, 0, MB_YESNOCANCEL | MB_ICONQUESTION);
\r
1985 void CMainFrame::OnViewInlinediffword()
\r
1987 m_bInlineWordDiff = !m_bInlineWordDiff;
\r
1988 if (m_pwndLeftView)
\r
1990 m_pwndLeftView->SetInlineWordDiff(m_bInlineWordDiff);
\r
1991 m_pwndLeftView->Invalidate();
\r
1993 if (m_pwndRightView)
\r
1995 m_pwndRightView->SetInlineWordDiff(m_bInlineWordDiff);
\r
1996 m_pwndRightView->Invalidate();
\r
1998 if (m_pwndBottomView)
\r
2000 m_pwndBottomView->SetInlineWordDiff(m_bInlineWordDiff);
\r
2001 m_pwndBottomView->Invalidate();
\r
2003 m_wndLineDiffBar.Invalidate();
\r
2006 void CMainFrame::OnUpdateViewInlinediffword(CCmdUI *pCmdUI)
\r
2008 pCmdUI->Enable(m_pwndLeftView && m_pwndLeftView->IsWindowVisible() &&
\r
2009 m_pwndRightView && m_pwndRightView->IsWindowVisible());
\r
2010 pCmdUI->SetCheck(m_bInlineWordDiff);
\r
2013 void CMainFrame::OnUpdateEditCreateunifieddifffile(CCmdUI *pCmdUI)
\r
2015 // "create unified diff file" is only available if two files
\r
2016 // are diffed, not three.
\r
2017 bool bEnabled = true;
\r
2018 if ((m_pwndLeftView == NULL)||(!m_pwndLeftView->IsWindowVisible()))
\r
2020 if ((m_pwndRightView == NULL)||(!m_pwndRightView->IsWindowVisible()))
\r
2022 if ((m_pwndBottomView)&&(m_pwndBottomView->IsWindowVisible()))
\r
2024 pCmdUI->Enable(bEnabled);
\r
2027 void CMainFrame::OnEditCreateunifieddifffile()
\r
2029 CString origFile, modifiedFile, outputFile;
\r
2030 // the original file is the one on the left
\r
2031 if (m_pwndLeftView)
\r
2032 origFile = m_pwndLeftView->m_sFullFilePath;
\r
2033 if (m_pwndRightView)
\r
2034 modifiedFile = m_pwndRightView->m_sFullFilePath;
\r
2035 if (!origFile.IsEmpty() && !modifiedFile.IsEmpty())
\r
2037 // ask for the path to save the unified diff file to
\r
2038 OPENFILENAME ofn = {0}; // common dialog box structure
\r
2039 TCHAR szFile[MAX_PATH] = {0}; // buffer for file name
\r
2040 ofn.lStructSize = sizeof(OPENFILENAME);
\r
2041 ofn.lpstrFile = szFile;
\r
2042 ofn.nMaxFile = sizeof(szFile)/sizeof(TCHAR);
\r
2044 temp.LoadString(IDS_SAVEASTITLE);
\r
2045 if (!temp.IsEmpty())
\r
2046 ofn.lpstrTitle = temp;
\r
2047 ofn.Flags = OFN_OVERWRITEPROMPT;
\r
2049 sFilter.LoadString(IDS_COMMONFILEFILTER);
\r
2050 TCHAR * pszFilters = new TCHAR[sFilter.GetLength()+4];
\r
2051 _tcscpy_s (pszFilters, sFilter.GetLength()+4, sFilter);
\r
2052 // Replace '|' delimiters with '\0's
\r
2053 TCHAR *ptr = pszFilters + _tcslen(pszFilters); //set ptr at the NULL
\r
2054 while (ptr != pszFilters)
\r
2060 ofn.lpstrFilter = pszFilters;
\r
2061 ofn.nFilterIndex = 1;
\r
2063 // Display the Save dialog box.
\r
2065 if (GetSaveFileName(&ofn)==TRUE)
\r
2067 outputFile = CString(ofn.lpstrFile);
\r
2068 CAppUtils::CreateUnifiedDiff(origFile, modifiedFile, outputFile, true);
\r
2070 delete [] pszFilters;
\r
2074 void CMainFrame::OnUpdateViewLinediffbar(CCmdUI *pCmdUI)
\r
2076 pCmdUI->SetCheck(m_bLineDiff);
\r
2080 void CMainFrame::OnViewLinediffbar()
\r
2082 m_bLineDiff = !m_bLineDiff;
\r
2083 m_wndLineDiffBar.ShowPane(m_bLineDiff, false, true);
\r
2084 m_wndLineDiffBar.DocumentUpdated();
\r
2085 m_wndLocatorBar.ShowPane(m_bLocatorBar, false, true);
\r
2086 m_wndLocatorBar.DocumentUpdated();
\r
2089 void CMainFrame::OnUpdateViewLocatorbar(CCmdUI *pCmdUI)
\r
2091 pCmdUI->SetCheck(m_bLocatorBar);
\r
2095 void CMainFrame::OnViewLocatorbar()
\r
2097 m_bLocatorBar = !m_bLocatorBar;
\r
2098 m_wndLocatorBar.ShowPane(m_bLocatorBar, false, true);
\r
2099 m_wndLocatorBar.DocumentUpdated();
\r
2100 m_wndLineDiffBar.ShowPane(m_bLineDiff, false, true);
\r
2101 m_wndLineDiffBar.DocumentUpdated();
\r