1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2008-2013 - TortoiseGit
4 // Copyright (C) 2004-2012 - TortoiseSVN
5 // Copyright (C) 2012-2013 - Sven Strickroth <email@cs-ware.de>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software Foundation,
19 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "TortoiseMerge.h"
23 #include "CustomMFCRibbonButton.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"
36 #include "SelectFileFilter.h"
37 #include "FormatMessageWrapper.h"
38 #include "TaskbarUUID.h"
45 CCustomMFCRibbonButton button1
;
48 const UINT TaskBarButtonCreated
= RegisterWindowMessage(L
"TaskbarButtonCreated");
50 IMPLEMENT_DYNCREATE(CMainFrame
, CFrameWndEx
)
52 BEGIN_MESSAGE_MAP(CMainFrame
, CFrameWndEx
)
54 ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN7
, ID_VIEW_APPLOOK_OFF_2007_AQUA
, &CMainFrame::OnApplicationLook
)
55 ON_UPDATE_COMMAND_UI_RANGE(IDC_STYLEBUTTON
, ID_VIEW_APPLOOK_OFF_2007_AQUA
, &CMainFrame::OnUpdateApplicationLook
)
56 // Global help commands
57 ON_COMMAND(ID_HELP_FINDER
, CFrameWndEx::OnHelpFinder
)
58 ON_COMMAND(ID_HELP
, CFrameWndEx::OnHelp
)
59 ON_COMMAND(ID_CONTEXT_HELP
, CFrameWndEx::OnContextHelp
)
60 ON_COMMAND(ID_DEFAULT_HELP
, CFrameWndEx::OnHelpFinder
)
61 ON_COMMAND(ID_FILE_OPEN
, OnFileOpen
)
62 ON_COMMAND(ID_VIEW_WHITESPACES
, OnViewWhitespaces
)
64 ON_COMMAND(ID_FILE_SAVE
, OnFileSave
)
65 ON_COMMAND(ID_FILE_SAVE_AS
, OnFileSaveAs
)
66 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE
, OnUpdateFileSave
)
67 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS
, OnUpdateFileSaveAs
)
68 ON_COMMAND(ID_VIEW_ONEWAYDIFF
, OnViewOnewaydiff
)
69 ON_UPDATE_COMMAND_UI(ID_VIEW_ONEWAYDIFF
, OnUpdateViewOnewaydiff
)
70 ON_UPDATE_COMMAND_UI(ID_VIEW_WHITESPACES
, OnUpdateViewWhitespaces
)
71 ON_COMMAND(ID_VIEW_OPTIONS
, OnViewOptions
)
74 ON_COMMAND(ID_FILE_RELOAD
, OnFileReload
)
75 ON_COMMAND(ID_VIEW_LINEDOWN
, OnViewLinedown
)
76 ON_COMMAND(ID_VIEW_LINEUP
, OnViewLineup
)
77 ON_COMMAND(ID_VIEW_MOVEDBLOCKS
, OnViewMovedBlocks
)
78 ON_UPDATE_COMMAND_UI(ID_VIEW_MOVEDBLOCKS
, OnUpdateViewMovedBlocks
)
79 ON_UPDATE_COMMAND_UI(ID_EDIT_MARKASRESOLVED
, OnUpdateMergeMarkasresolved
)
80 ON_COMMAND(ID_EDIT_MARKASRESOLVED
, OnMergeMarkasresolved
)
81 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTCONFLICT
, OnUpdateMergeNextconflict
)
82 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSCONFLICT
, OnUpdateMergePreviousconflict
)
85 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY
, OnUpdateEditCopy
)
86 ON_COMMAND(ID_VIEW_SWITCHLEFT
, OnViewSwitchleft
)
87 ON_UPDATE_COMMAND_UI(ID_VIEW_SWITCHLEFT
, OnUpdateViewSwitchleft
)
88 ON_COMMAND(ID_VIEW_LINELEFT
, &CMainFrame::OnViewLineleft
)
89 ON_COMMAND(ID_VIEW_LINERIGHT
, &CMainFrame::OnViewLineright
)
90 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILELIST
, &CMainFrame::OnUpdateViewShowfilelist
)
91 ON_COMMAND(ID_VIEW_SHOWFILELIST
, &CMainFrame::OnViewShowfilelist
)
92 ON_COMMAND(ID_EDIT_USETHEIRBLOCK
, &CMainFrame::OnEditUseTheirs
)
93 ON_COMMAND(ID_EDIT_USEMYBLOCK
, &CMainFrame::OnEditUseMine
)
94 ON_COMMAND(ID_EDIT_USETHEIRTHENMYBLOCK
, &CMainFrame::OnEditUseTheirsThenMine
)
95 ON_COMMAND(ID_EDIT_USEMINETHENTHEIRBLOCK
, &CMainFrame::OnEditUseMineThenTheirs
)
96 ON_COMMAND(ID_EDIT_UNDO
, &CMainFrame::OnEditUndo
)
97 ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO
, &CMainFrame::OnUpdateEditUndo
)
98 ON_COMMAND(ID_EDIT_ENABLE
, &CMainFrame::OnEditEnable
)
99 ON_UPDATE_COMMAND_UI(ID_EDIT_ENABLE
, &CMainFrame::OnUpdateEditEnable
)
100 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMINETHENTHEIRBLOCK
, &CMainFrame::OnUpdateEditUseminethentheirblock
)
101 ON_UPDATE_COMMAND_UI(ID_EDIT_USEMYBLOCK
, &CMainFrame::OnUpdateEditUsemyblock
)
102 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRBLOCK
, &CMainFrame::OnUpdateEditUsetheirblock
)
103 ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRTHENMYBLOCK
, &CMainFrame::OnUpdateEditUsetheirthenmyblock
)
104 ON_COMMAND(ID_VIEW_INLINEDIFFWORD
, &CMainFrame::OnViewInlinediffword
)
105 ON_UPDATE_COMMAND_UI(ID_VIEW_INLINEDIFFWORD
, &CMainFrame::OnUpdateViewInlinediffword
)
106 ON_COMMAND(ID_VIEW_INLINEDIFF
, &CMainFrame::OnViewInlinediff
)
107 ON_UPDATE_COMMAND_UI(ID_VIEW_INLINEDIFF
, &CMainFrame::OnUpdateViewInlinediff
)
108 ON_UPDATE_COMMAND_UI(ID_EDIT_CREATEUNIFIEDDIFFFILE
, &CMainFrame::OnUpdateEditCreateunifieddifffile
)
109 ON_COMMAND(ID_EDIT_CREATEUNIFIEDDIFFFILE
, &CMainFrame::OnEditCreateunifieddifffile
)
110 ON_UPDATE_COMMAND_UI(ID_VIEW_LINEDIFFBAR
, &CMainFrame::OnUpdateViewLinediffbar
)
111 ON_COMMAND(ID_VIEW_LINEDIFFBAR
, &CMainFrame::OnViewLinediffbar
)
112 ON_UPDATE_COMMAND_UI(ID_VIEW_LOCATORBAR
, &CMainFrame::OnUpdateViewLocatorbar
)
113 ON_COMMAND(ID_VIEW_LOCATORBAR
, &CMainFrame::OnViewLocatorbar
)
114 ON_COMMAND(ID_EDIT_USELEFTBLOCK
, &CMainFrame::OnEditUseleftblock
)
115 ON_UPDATE_COMMAND_UI(ID_USEBLOCKS
, &CMainFrame::OnUpdateUseBlock
)
116 ON_UPDATE_COMMAND_UI(ID_EDIT_USELEFTBLOCK
, &CMainFrame::OnUpdateEditUseleftblock
)
117 ON_COMMAND(ID_EDIT_USELEFTFILE
, &CMainFrame::OnEditUseleftfile
)
118 ON_UPDATE_COMMAND_UI(ID_EDIT_USELEFTFILE
, &CMainFrame::OnUpdateEditUseleftfile
)
119 ON_COMMAND(ID_EDIT_USEBLOCKFROMLEFTBEFORERIGHT
, &CMainFrame::OnEditUseblockfromleftbeforeright
)
120 ON_UPDATE_COMMAND_UI(ID_EDIT_USEBLOCKFROMLEFTBEFORERIGHT
, &CMainFrame::OnUpdateEditUseblockfromleftbeforeright
)
121 ON_COMMAND(ID_EDIT_USEBLOCKFROMRIGHTBEFORELEFT
, &CMainFrame::OnEditUseblockfromrightbeforeleft
)
122 ON_UPDATE_COMMAND_UI(ID_EDIT_USEBLOCKFROMRIGHTBEFORELEFT
, &CMainFrame::OnUpdateEditUseblockfromrightbeforeleft
)
123 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTDIFFERENCE
, &CMainFrame::OnUpdateNavigateNextdifference
)
124 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSDIFFERENCE
, &CMainFrame::OnUpdateNavigatePreviousdifference
)
125 ON_COMMAND(ID_VIEW_COLLAPSED
, &CMainFrame::OnViewCollapsed
)
126 ON_UPDATE_COMMAND_UI(ID_VIEW_COLLAPSED
, &CMainFrame::OnUpdateViewCollapsed
)
127 ON_COMMAND(ID_VIEW_COMPAREWHITESPACES
, &CMainFrame::OnViewComparewhitespaces
)
128 ON_UPDATE_COMMAND_UI(ID_VIEW_COMPAREWHITESPACES
, &CMainFrame::OnUpdateViewComparewhitespaces
)
129 ON_COMMAND(ID_VIEW_IGNOREWHITESPACECHANGES
, &CMainFrame::OnViewIgnorewhitespacechanges
)
130 ON_UPDATE_COMMAND_UI(ID_VIEW_IGNOREWHITESPACECHANGES
, &CMainFrame::OnUpdateViewIgnorewhitespacechanges
)
131 ON_COMMAND(ID_VIEW_IGNOREALLWHITESPACECHANGES
, &CMainFrame::OnViewIgnoreallwhitespacechanges
)
132 ON_UPDATE_COMMAND_UI(ID_VIEW_IGNOREALLWHITESPACECHANGES
, &CMainFrame::OnUpdateViewIgnoreallwhitespacechanges
)
133 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTINLINEDIFF
, &CMainFrame::OnUpdateNavigateNextinlinediff
)
134 ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVINLINEDIFF
, &CMainFrame::OnUpdateNavigatePrevinlinediff
)
135 ON_COMMAND(ID_VIEW_WRAPLONGLINES
, &CMainFrame::OnViewWraplonglines
)
136 ON_UPDATE_COMMAND_UI(ID_VIEW_WRAPLONGLINES
, &CMainFrame::OnUpdateViewWraplonglines
)
137 ON_REGISTERED_MESSAGE( TaskBarButtonCreated
, CMainFrame::OnTaskbarButtonCreated
)
138 ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE
, &CMainFrame::OnUpdateEditPaste
)
141 static UINT indicators
[] =
143 ID_SEPARATOR
, // status line indicator
144 ID_INDICATOR_LEFTVIEW
,
145 ID_INDICATOR_RIGHTVIEW
,
146 ID_INDICATOR_BOTTOMVIEW
,
152 // CMainFrame construction/destruction
154 CMainFrame::CMainFrame()
155 : m_bInitSplitter(FALSE
)
156 , m_bReversedPatch(FALSE
)
157 , m_bHasConflicts(false)
158 , m_bInlineWordDiff(true)
160 , m_bLocatorBar(true)
161 , m_nMoveMovesToIgnore(0)
162 , m_pwndLeftView(NULL
)
163 , m_pwndRightView(NULL
)
164 , m_pwndBottomView(NULL
)
167 , m_bCheckReload(false)
168 , m_bSaveRequired(false)
170 , resolveMsgWParam(0)
171 , resolveMsgLParam(0)
172 , m_regWrapLines(L
"Software\\TortoiseGitMerge\\WrapLines", 0)
173 , m_regViewModedBlocks(L
"Software\\TortoiseGitMerge\\ViewMovedBlocks", TRUE
)
174 , m_regOneWay(L
"Software\\TortoiseGitMerge\\OnePane")
175 , m_regCollapsed(L
"Software\\TortoiseGitMerge\\Collapsed", 0)
176 , m_regInlineDiff(L
"Software\\TortoiseGitMerge\\DisplayBinDiff", TRUE
)
177 , m_regUseRibbons(L
"Software\\TortoiseGitMerge\\UseRibbons", TRUE
)
179 m_bOneWay
= (0 != ((DWORD
)m_regOneWay
));
180 theApp
.m_nAppLook
= theApp
.GetInt(_T("ApplicationLook"), ID_VIEW_APPLOOK_VS_2005
);
181 m_bCollapsed
= !!(DWORD
)m_regCollapsed
;
182 m_bViewMovedBlocks
= !!(DWORD
)m_regViewModedBlocks
;
183 m_bWrapLines
= !!(DWORD
)m_regWrapLines
;
184 m_bInlineDiff
= !!m_regInlineDiff
;
185 m_bUseRibbons
= !!m_regUseRibbons
;
186 CMFCVisualManagerWindows::m_b3DTabsXPTheme
= TRUE
;
189 CMainFrame::~CMainFrame()
193 LRESULT
CMainFrame::OnTaskbarButtonCreated(WPARAM
/*wParam*/, LPARAM
/*lParam*/)
195 SetUUIDOverlayIcon(m_hWnd
);
200 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct
)
202 if (CFrameWndEx::OnCreate(lpCreateStruct
) == -1)
205 OnApplicationLook(theApp
.m_nAppLook
);
209 m_wndRibbonBar
.Create(this);
210 m_wndRibbonBar
.LoadFromResource(IDR_RIBBON
);
212 // enable the dialog launch button on the view panel
213 CMFCRibbonCategory
* pMainCat
= m_wndRibbonBar
.GetCategory(1);
216 CMFCRibbonPanel
* pPanel
= pMainCat
->GetPanel(3);
218 pPanel
->EnableLaunchButton(ID_VIEW_OPTIONS
);
220 // now replace all buttons with our custom button class
221 for (int i
= 0; i
< m_wndRibbonBar
.GetCategoryCount(); ++i
)
223 CMFCRibbonCategory
* pCat
= m_wndRibbonBar
.GetCategory(i
);
224 for (int j
= 0; j
< pCat
->GetPanelCount(); ++j
)
226 CMFCRibbonPanel
* pPanel
= pCat
->GetPanel(j
);
227 CList
<UINT
, UINT
> lstItems
;
228 pPanel
->GetItemIDsList(lstItems
);
229 while (!lstItems
.IsEmpty())
231 UINT id
= lstItems
.GetHead();
232 lstItems
.RemoveHead();
233 CMFCRibbonButton
* pButton
= dynamic_cast<CMFCRibbonButton
*>(pPanel
->FindByID(id
));
236 CCustomMFCRibbonButton
* c
= new CCustomMFCRibbonButton(id
, pButton
->GetText());
237 pPanel
->ReplaceByID(id
, c
);
245 if (!m_wndMenuBar
.Create(this))
247 TRACE0("Failed to create menubar\n");
248 return -1; // fail to create
250 m_wndMenuBar
.SetPaneStyle(m_wndMenuBar
.GetPaneStyle() | CBRS_SIZE_DYNAMIC
| CBRS_TOOLTIPS
| CBRS_FLYBY
);
252 // prevent the menu bar from taking the focus on activation
253 CMFCPopupMenu::SetForceMenuFocus(FALSE
);
254 if (!m_wndToolBar
.CreateEx(this, TBSTYLE_FLAT
, WS_CHILD
| WS_VISIBLE
| CBRS_ALIGN_TOP
| CBRS_GRIPPER
| CBRS_TOOLTIPS
| CBRS_FLYBY
) || !m_wndToolBar
.LoadToolBar(IDR_MAINFRAME
))
256 TRACE0("Failed to create toolbar\n");
257 return -1; // fail to create
259 m_wndToolBar
.SetWindowText(_T("Main"));
261 if (!m_wndStatusBar
.Create(this) ||
262 !m_wndStatusBar
.SetIndicators(indicators
,
263 _countof(indicators
)))
265 TRACE0("Failed to create status bar\n");
266 return -1; // fail to create
269 if (!m_wndLocatorBar
.Create(this, IDD_DIFFLOCATOR
,
270 CBRS_ALIGN_LEFT
| CBRS_SIZE_FIXED
, ID_VIEW_LOCATORBAR
))
272 TRACE0("Failed to create dialogbar\n");
273 return -1; // fail to create
275 if (!m_wndLineDiffBar
.Create(this, IDD_LINEDIFF
,
276 CBRS_ALIGN_BOTTOM
| CBRS_SIZE_FIXED
, ID_VIEW_LINEDIFFBAR
))
278 TRACE0("Failed to create dialogbar\n");
279 return -1; // fail to create
281 m_wndLocatorBar
.m_pMainFrm
= this;
282 m_wndLineDiffBar
.m_pMainFrm
= this;
284 EnableDocking(CBRS_ALIGN_ANY
);
287 m_wndMenuBar
.EnableDocking(CBRS_ALIGN_TOP
);
288 m_wndToolBar
.EnableDocking(CBRS_ALIGN_TOP
);
289 DockPane(&m_wndMenuBar
);
290 DockPane(&m_wndToolBar
);
292 DockPane(&m_wndLocatorBar
);
293 DockPane(&m_wndLineDiffBar
);
294 ShowPane(&m_wndLocatorBar
, true, false, true);
295 ShowPane(&m_wndLineDiffBar
, true, false, true);
297 m_wndLocatorBar
.EnableGripper(FALSE
);
298 m_wndLineDiffBar
.EnableGripper(FALSE
);
303 BOOL
CMainFrame::PreCreateWindow(CREATESTRUCT
& cs
)
305 if( !CFrameWndEx::PreCreateWindow(cs
) )
310 void CMainFrame::OnApplicationLook(UINT id
)
314 theApp
.m_nAppLook
= id
;
316 switch (theApp
.m_nAppLook
)
318 case ID_VIEW_APPLOOK_WIN_2000
:
319 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager
));
320 m_wndRibbonBar
.SetWindows7Look(FALSE
);
323 case ID_VIEW_APPLOOK_OFF_XP
:
324 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP
));
325 m_wndRibbonBar
.SetWindows7Look(FALSE
);
328 case ID_VIEW_APPLOOK_WIN_XP
:
329 CMFCVisualManagerWindows::m_b3DTabsXPTheme
= TRUE
;
330 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows
));
331 m_wndRibbonBar
.SetWindows7Look(FALSE
);
334 case ID_VIEW_APPLOOK_OFF_2003
:
335 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003
));
336 CDockingManager::SetDockingMode(DT_SMART
);
337 m_wndRibbonBar
.SetWindows7Look(FALSE
);
340 case ID_VIEW_APPLOOK_VS_2005
:
341 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005
));
342 CDockingManager::SetDockingMode(DT_SMART
);
343 m_wndRibbonBar
.SetWindows7Look(FALSE
);
346 case ID_VIEW_APPLOOK_VS_2008
:
347 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2008
));
348 CDockingManager::SetDockingMode(DT_SMART
);
349 m_wndRibbonBar
.SetWindows7Look(FALSE
);
352 case ID_VIEW_APPLOOK_WIN7
:
353 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows7
));
354 CDockingManager::SetDockingMode(DT_SMART
);
355 m_wndRibbonBar
.SetWindows7Look(TRUE
);
359 switch (theApp
.m_nAppLook
)
361 case ID_VIEW_APPLOOK_OFF_2007_BLUE
:
362 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue
);
365 case ID_VIEW_APPLOOK_OFF_2007_BLACK
:
366 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack
);
369 case ID_VIEW_APPLOOK_OFF_2007_SILVER
:
370 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver
);
373 case ID_VIEW_APPLOOK_OFF_2007_AQUA
:
374 CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua
);
378 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007
));
379 CDockingManager::SetDockingMode(DT_SMART
);
380 m_wndRibbonBar
.SetWindows7Look(FALSE
);
383 RedrawWindow(NULL
, NULL
, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_FRAME
| RDW_ERASE
);
385 theApp
.WriteInt(_T("ApplicationLook"), theApp
.m_nAppLook
);
388 void CMainFrame::OnUpdateApplicationLook(CCmdUI
* pCmdUI
)
391 pCmdUI
->SetRadio(theApp
.m_nAppLook
== pCmdUI
->m_nID
);
395 // CMainFrame diagnostics
398 void CMainFrame::AssertValid() const
400 CFrameWndEx::AssertValid();
403 void CMainFrame::Dump(CDumpContext
& dc
) const
405 CFrameWndEx::Dump(dc
);
411 // CMainFrame message handlers
414 BOOL
CMainFrame::OnCreateClient(LPCREATESTRUCT
/*lpcs*/, CCreateContext
* pContext
)
420 // split into three panes:
429 // create a splitter with 2 rows, 1 column
430 if (!m_wndSplitter
.CreateStatic(this, 2, 1))
432 TRACE0("Failed to CreateStaticSplitter\n");
436 // add the second splitter pane - which is a nested splitter with 2 columns
437 if (!m_wndSplitter2
.CreateStatic(
438 &m_wndSplitter
, // our parent window is the first splitter
439 1, 2, // the new splitter is 1 row, 2 columns
440 WS_CHILD
| WS_VISIBLE
| WS_BORDER
, // style, WS_BORDER is needed
441 m_wndSplitter
.IdFromRowCol(0, 0)
442 // new splitter is in the first row, 1st column of first splitter
445 TRACE0("Failed to create nested splitter\n");
448 // add the first splitter pane - the default view in row 0
449 if (!m_wndSplitter
.CreateView(1, 0,
450 RUNTIME_CLASS(CBottomView
), CSize(cr
.Width(), cr
.Height()), pContext
))
452 TRACE0("Failed to create first pane\n");
455 m_pwndBottomView
= (CBottomView
*)m_wndSplitter
.GetPane(1,0);
456 m_pwndBottomView
->m_pwndLocator
= &m_wndLocatorBar
;
457 m_pwndBottomView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
458 m_pwndBottomView
->m_pwndStatusBar
= &m_wndStatusBar
;
459 m_pwndBottomView
->m_pMainFrame
= this;
461 // now create the two views inside the nested splitter
463 if (!m_wndSplitter2
.CreateView(0, 0,
464 RUNTIME_CLASS(CLeftView
), CSize(cr
.Width()/2, cr
.Height()/2), pContext
))
466 TRACE0("Failed to create second pane\n");
469 m_pwndLeftView
= (CLeftView
*)m_wndSplitter2
.GetPane(0,0);
470 m_pwndLeftView
->m_pwndLocator
= &m_wndLocatorBar
;
471 m_pwndLeftView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
472 m_pwndLeftView
->m_pwndStatusBar
= &m_wndStatusBar
;
473 m_pwndLeftView
->m_pMainFrame
= this;
475 if (!m_wndSplitter2
.CreateView(0, 1,
476 RUNTIME_CLASS(CRightView
), CSize(cr
.Width()/2, cr
.Height()/2), pContext
))
478 TRACE0("Failed to create third pane\n");
481 m_pwndRightView
= (CRightView
*)m_wndSplitter2
.GetPane(0,1);
482 m_pwndRightView
->m_pwndLocator
= &m_wndLocatorBar
;
483 m_pwndRightView
->m_pwndLineDiffBar
= &m_wndLineDiffBar
;
484 m_pwndRightView
->m_pwndStatusBar
= &m_wndStatusBar
;
485 m_pwndRightView
->m_pMainFrame
= this;
486 m_bInitSplitter
= TRUE
;
488 m_dlgFilePatches
.Create(IDD_FILEPATCHES
, this);
494 BOOL
CMainFrame::PatchFile(CString sFilePath
, bool /*bContentMods*/, bool bPropMods
, CString sVersion
, BOOL bAutoPatch
)
497 //"dry run" was successful, so save the patched file somewhere...
498 CString sTempFile
= CTempFiles::Instance().GetTempFilePathString();
499 CString sRejectedFile
;
500 if (m_Patch
.GetPatchResult(sFilePath
, sTempFile
, sRejectedFile
) < 0)
502 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
505 sFilePath
= m_Patch
.GetTargetPath() + _T("\\") + sFilePath
;
506 sFilePath
.Replace('/', '\\');
507 if (m_bReversedPatch
)
509 m_Data
.m_baseFile
.SetFileName(sTempFile
);
511 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
512 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
513 m_Data
.m_yourFile
.SetFileName(sFilePath
);
514 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchOriginal
);
515 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
516 m_Data
.m_theirFile
.SetOutOfUse();
517 m_Data
.m_mergedFile
.SetOutOfUse();
521 if ((!PathFileExists(sFilePath
))||(PathIsDirectory(sFilePath
)))
523 m_Data
.m_baseFile
.SetFileName(CTempFiles::Instance().GetTempFilePathString());
524 m_Data
.m_baseFile
.CreateEmptyFile();
528 m_Data
.m_baseFile
.SetFileName(sFilePath
);
530 CString sDescription
;
531 sDescription
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchOriginal
);
532 m_Data
.m_baseFile
.SetDescriptiveName(sDescription
);
533 m_Data
.m_yourFile
.SetFileName(sTempFile
);
535 temp
.Format(_T("%s %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
), (LPCTSTR
)m_Data
.m_sPatchPatched
);
536 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
537 m_Data
.m_theirFile
.SetOutOfUse();
538 m_Data
.m_mergedFile
.SetFileName(sFilePath
);
539 m_Data
.m_bPatchRequired
= bPropMods
;
541 TRACE(_T("comparing %s\nwith the patched result %s\n"), (LPCTSTR
)sFilePath
, (LPCTSTR
)sTempFile
);
544 if (!sRejectedFile
.IsEmpty())
547 // start TortoiseUDiff with the rejected hunks
549 sTitle
.Format(IDS_TITLE_REJECTEDHUNKS
, (LPCTSTR
)CPathUtils::GetFileNameFromPath(sFilePath
));
550 CAppUtils::StartUnifiedDiffViewer(sRejectedFile
, sTitle
);
561 BOOL
CMainFrame::DiffFiles(CString sURL1
, CString sRev1
, CString sURL2
, CString sRev2
)
563 CString tempfile1
= CTempFiles::Instance().GetTempFilePathString();
564 CString tempfile2
= CTempFiles::Instance().GetTempFilePathString();
566 ASSERT(tempfile1
.Compare(tempfile2
));
569 CSysProgressDlg progDlg
;
570 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sRev1
);
571 progDlg
.SetLine(1, sTemp
, true);
572 progDlg
.SetLine(2, sURL1
, true);
573 sTemp
.LoadString(IDS_GETVERSIONOFFILETITLE
);
574 progDlg
.SetTitle(sTemp
);
575 progDlg
.SetShowProgressBar(true);
576 progDlg
.SetAnimation(IDR_DOWNLOAD
);
577 progDlg
.SetTime(FALSE
);
578 progDlg
.SetProgress(1,100);
579 progDlg
.ShowModeless(this);
580 if (!CAppUtils::GetVersionedFile(sURL1
, sRev1
, tempfile1
, &progDlg
, m_hWnd
))
584 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sRev1
, (LPCTSTR
)sURL1
);
585 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
588 sTemp
.Format(IDS_GETVERSIONOFFILE
, (LPCTSTR
)sRev2
);
589 progDlg
.SetLine(1, sTemp
, true);
590 progDlg
.SetLine(2, sURL2
, true);
591 progDlg
.SetProgress(50, 100);
592 if (!CAppUtils::GetVersionedFile(sURL2
, sRev2
, tempfile2
, &progDlg
, m_hWnd
))
596 sErrMsg
.Format(IDS_ERR_MAINFRAME_FILEVERSIONNOTFOUND
, (LPCTSTR
)sRev2
, (LPCTSTR
)sURL2
);
597 MessageBox(sErrMsg
, NULL
, MB_ICONERROR
);
600 progDlg
.SetProgress(100,100);
603 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sURL1
), (LPCTSTR
)sRev1
);
604 m_Data
.m_baseFile
.SetFileName(tempfile1
);
605 m_Data
.m_baseFile
.SetDescriptiveName(temp
);
606 temp
.Format(_T("%s Revision %s"), (LPCTSTR
)CPathUtils::GetFileNameFromPath(sURL2
), (LPCTSTR
)sRev2
);
607 m_Data
.m_yourFile
.SetFileName(tempfile2
);
608 m_Data
.m_yourFile
.SetDescriptiveName(temp
);
615 void CMainFrame::OnFileOpen()
617 if (CheckForSave(CHFSR_OPEN
)==IDCANCEL
)
620 if (dlg
.DoModal()!=IDOK
)
624 m_dlgFilePatches
.ShowWindow(SW_HIDE
);
625 m_dlgFilePatches
.Init(NULL
, NULL
, CString(), NULL
);
626 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
,
627 (LPCTSTR
)dlg
.m_sUnifiedDiffFile
, (LPCTSTR
)dlg
.m_sPatchDirectory
);
628 m_Data
.m_baseFile
.SetFileName(dlg
.m_sBaseFile
);
629 m_Data
.m_theirFile
.SetFileName(dlg
.m_sTheirFile
);
630 m_Data
.m_yourFile
.SetFileName(dlg
.m_sYourFile
);
631 m_Data
.m_sDiffFile
= dlg
.m_sUnifiedDiffFile
;
632 m_Data
.m_sPatchPath
= dlg
.m_sPatchDirectory
;
633 m_Data
.m_mergedFile
.SetOutOfUse();
634 CCrashReport::Instance().AddFile2(dlg
.m_sBaseFile
, NULL
, _T("Basefile"), CR_AF_MAKE_FILE_COPY
);
635 CCrashReport::Instance().AddFile2(dlg
.m_sTheirFile
, NULL
, _T("Theirfile"), CR_AF_MAKE_FILE_COPY
);
636 CCrashReport::Instance().AddFile2(dlg
.m_sYourFile
, NULL
, _T("Yourfile"), CR_AF_MAKE_FILE_COPY
);
637 CCrashReport::Instance().AddFile2(dlg
.m_sUnifiedDiffFile
, NULL
, _T("Difffile"), CR_AF_MAKE_FILE_COPY
);
639 if (!m_Data
.IsBaseFileInUse() && m_Data
.IsTheirFileInUse() && m_Data
.IsYourFileInUse())
641 // a diff between two files means "Yours" against "Base", not "Theirs" against "Yours"
642 m_Data
.m_baseFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
644 if (m_Data
.IsBaseFileInUse() && m_Data
.IsTheirFileInUse() && !m_Data
.IsYourFileInUse())
646 // a diff between two files means "Yours" against "Base", not "Theirs" against "Base"
647 m_Data
.m_yourFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
649 m_bSaveRequired
= false;
654 void CMainFrame::ClearViewNamesAndPaths()
656 m_pwndLeftView
->m_sWindowName
.Empty();
657 m_pwndLeftView
->m_sFullFilePath
.Empty();
658 m_pwndRightView
->m_sWindowName
.Empty();
659 m_pwndRightView
->m_sFullFilePath
.Empty();
660 m_pwndBottomView
->m_sWindowName
.Empty();
661 m_pwndBottomView
->m_sFullFilePath
.Empty();
664 bool CMainFrame::LoadViews(int line
)
666 m_Data
.SetBlame(m_bBlame
);
667 m_Data
.SetMovedBlocks(m_bViewMovedBlocks
);
668 m_bHasConflicts
= false;
669 CBaseView
* pwndActiveView
= m_pwndLeftView
;
670 int nOldLine
= m_pwndRightView
? m_pwndRightView
->m_nTopLine
: -1;
672 m_pwndRightView
&& m_pwndRightView
->m_pViewData
?
673 m_pwndRightView
->m_pViewData
->GetLineNumber(m_pwndRightView
->m_nTopLine
) : -1;
674 POINT ptOldCaretPos
= {-1, -1};
675 if (m_pwndRightView
&& m_pwndRightView
->IsTarget())
676 ptOldCaretPos
= m_pwndRightView
->GetCaretPosition();
677 if (m_pwndBottomView
&& m_pwndBottomView
->IsTarget())
678 ptOldCaretPos
= m_pwndBottomView
->GetCaretPosition();
681 m_pwndLeftView
->BuildAllScreen2ViewVector();
682 m_pwndLeftView
->DocumentUpdated();
683 m_pwndRightView
->DocumentUpdated();
684 m_pwndBottomView
->DocumentUpdated();
685 m_wndLocatorBar
.DocumentUpdated();
686 m_wndLineDiffBar
.DocumentUpdated();
687 ::MessageBox(m_hWnd
, m_Data
.GetError(), _T("TortoiseGitMerge"), MB_ICONERROR
);
688 m_Data
.m_mergedFile
.SetOutOfUse();
689 m_bSaveRequired
= false;
693 m_pwndLeftView
->BuildAllScreen2ViewVector();
694 m_pwndLeftView
->DocumentUpdated();
695 m_pwndRightView
->DocumentUpdated();
696 m_pwndBottomView
->DocumentUpdated();
697 m_wndLocatorBar
.DocumentUpdated();
698 m_wndLineDiffBar
.DocumentUpdated();
700 m_pwndLeftView
->SetWritable(false);
701 m_pwndLeftView
->SetWritableIsChangable(false);
702 m_pwndLeftView
->SetTarget(false);
703 m_pwndRightView
->SetWritable(false);
704 m_pwndRightView
->SetWritableIsChangable(false);
705 m_pwndRightView
->SetTarget(false);
706 m_pwndBottomView
->SetWritable(false);
707 m_pwndBottomView
->SetWritableIsChangable(false);
708 m_pwndBottomView
->SetTarget(false);
710 if (!m_Data
.IsBaseFileInUse())
712 CSysProgressDlg progDlg
;
713 if (m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
715 m_Data
.m_baseFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
717 else if ((!m_Data
.m_sDiffFile
.IsEmpty())&&(!m_Patch
.Init(m_Data
.m_sDiffFile
, m_Data
.m_sPatchPath
, &progDlg
)))
720 ClearViewNamesAndPaths();
721 MessageBox(m_Patch
.GetErrorMessage(), NULL
, MB_ICONERROR
);
722 m_bSaveRequired
= false;
726 if (m_Patch
.GetNumberOfFiles() > 0)
728 CString betterpatchpath
= m_Patch
.CheckPatchPath(m_Data
.m_sPatchPath
);
729 if (betterpatchpath
.CompareNoCase(m_Data
.m_sPatchPath
)!=0)
732 msg
.Format(IDS_WARNBETTERPATCHPATHFOUND
, (LPCTSTR
)m_Data
.m_sPatchPath
, (LPCTSTR
)betterpatchpath
);
733 if (CMessageBox::Show(m_hWnd
, msg
, _T("TortoiseGitMerge"), MB_ICONQUESTION
| MB_YESNO
)==IDYES
)
735 m_Data
.m_sPatchPath
= betterpatchpath
;
736 m_Patch
.Init(m_Data
.m_sDiffFile
, m_Data
.m_sPatchPath
, &progDlg
);
739 m_dlgFilePatches
.Init(&m_Patch
, this, m_Data
.m_sPatchPath
, this);
740 m_dlgFilePatches
.ShowWindow(SW_SHOW
);
741 ClearViewNamesAndPaths();
742 if (!m_wndSplitter
.IsRowHidden(1))
743 m_wndSplitter
.HideRow(1);
744 m_pwndLeftView
->SetHidden(FALSE
);
745 m_pwndRightView
->SetHidden(FALSE
);
746 m_pwndBottomView
->SetHidden(TRUE
);
749 if (m_Data
.IsBaseFileInUse() && !m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
751 m_Data
.m_yourFile
.TransferDetailsFrom(m_Data
.m_theirFile
);
753 if (m_Data
.IsBaseFileInUse() && m_Data
.IsYourFileInUse() && !m_Data
.IsTheirFileInUse())
755 //diff between YOUR and BASE
758 if (!m_wndSplitter2
.IsColumnHidden(1))
759 m_wndSplitter2
.HideColumn(1);
761 m_pwndLeftView
->m_pViewData
= &m_Data
.m_YourBaseBoth
;
762 m_pwndLeftView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
763 m_pwndLeftView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
764 m_pwndLeftView
->m_sWindowName
= m_Data
.m_baseFile
.GetWindowName() + _T(" - ") + m_Data
.m_yourFile
.GetWindowName();
765 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_baseFile
.GetFilename() + _T(" - ") + m_Data
.m_yourFile
.GetFilename();
766 m_pwndLeftView
->m_pWorkingFile
= &m_Data
.m_yourFile
;
767 m_pwndLeftView
->SetTarget();
768 m_pwndLeftView
->SetWritableIsChangable(true);
770 m_pwndRightView
->m_pViewData
= NULL
;
771 m_pwndRightView
->m_pWorkingFile
= NULL
;
772 m_pwndBottomView
->m_pViewData
= NULL
;
773 m_pwndBottomView
->m_pWorkingFile
= NULL
;
775 if (!m_wndSplitter
.IsRowHidden(1))
776 m_wndSplitter
.HideRow(1);
777 m_pwndLeftView
->SetHidden(FALSE
);
778 m_pwndRightView
->SetHidden(TRUE
);
779 m_pwndBottomView
->SetHidden(TRUE
);
780 ::SetWindowPos(m_pwndLeftView
->m_hWnd
, NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
784 pwndActiveView
= m_pwndRightView
;
785 if (m_wndSplitter2
.IsColumnHidden(1))
786 m_wndSplitter2
.ShowColumn();
788 m_pwndLeftView
->m_pViewData
= &m_Data
.m_YourBaseLeft
;
789 m_pwndLeftView
->texttype
= m_Data
.m_arBaseFile
.GetUnicodeType();
790 m_pwndLeftView
->lineendings
= m_Data
.m_arBaseFile
.GetLineEndings();
791 m_pwndLeftView
->m_sWindowName
= m_Data
.m_baseFile
.GetWindowName();
792 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_baseFile
.GetFilename();
793 m_pwndLeftView
->m_sConvertedFilePath
= m_Data
.m_baseFile
.GetConvertedFileName();
794 m_pwndLeftView
->m_pWorkingFile
= &m_Data
.m_baseFile
;
795 m_pwndLeftView
->SetWritableIsChangable(true);
797 m_pwndRightView
->m_pViewData
= &m_Data
.m_YourBaseRight
;
798 m_pwndRightView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
799 m_pwndRightView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
800 m_pwndRightView
->m_sWindowName
= m_Data
.m_yourFile
.GetWindowName();
801 m_pwndRightView
->m_sFullFilePath
= m_Data
.m_yourFile
.GetFilename();
802 m_pwndRightView
->m_sConvertedFilePath
= m_Data
.m_yourFile
.GetConvertedFileName();
803 m_pwndRightView
->m_pWorkingFile
= &m_Data
.m_yourFile
;
804 m_pwndRightView
->SetWritable();
805 m_pwndRightView
->SetTarget();
807 m_pwndBottomView
->m_pViewData
= NULL
;
808 m_pwndBottomView
->m_pWorkingFile
= NULL
;
810 if (!m_wndSplitter
.IsRowHidden(1))
811 m_wndSplitter
.HideRow(1);
812 m_pwndLeftView
->SetHidden(FALSE
);
813 m_pwndRightView
->SetHidden(FALSE
);
814 m_pwndBottomView
->SetHidden(TRUE
);
817 else if (m_Data
.IsBaseFileInUse() && m_Data
.IsYourFileInUse() && m_Data
.IsTheirFileInUse())
819 //diff between THEIR, YOUR and BASE
820 m_pwndBottomView
->SetWritable();
821 m_pwndBottomView
->SetTarget();
822 pwndActiveView
= m_pwndBottomView
;
824 m_pwndLeftView
->m_pViewData
= &m_Data
.m_TheirBaseBoth
;
825 m_pwndLeftView
->texttype
= m_Data
.m_arTheirFile
.GetUnicodeType();
826 m_pwndLeftView
->lineendings
= m_Data
.m_arTheirFile
.GetLineEndings();
827 m_pwndLeftView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_THEIRS
);
828 m_pwndLeftView
->m_sWindowName
+= _T(" - ") + m_Data
.m_theirFile
.GetWindowName();
829 m_pwndLeftView
->m_sFullFilePath
= m_Data
.m_theirFile
.GetFilename();
830 m_pwndLeftView
->m_sConvertedFilePath
= m_Data
.m_theirFile
.GetConvertedFileName();
831 m_pwndLeftView
->m_pWorkingFile
= &m_Data
.m_theirFile
;
833 m_pwndRightView
->m_pViewData
= &m_Data
.m_YourBaseBoth
;
834 m_pwndRightView
->texttype
= m_Data
.m_arYourFile
.GetUnicodeType();
835 m_pwndRightView
->lineendings
= m_Data
.m_arYourFile
.GetLineEndings();
836 m_pwndRightView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_MINE
);
837 m_pwndRightView
->m_sWindowName
+= _T(" - ") + m_Data
.m_yourFile
.GetWindowName();
838 m_pwndRightView
->m_sFullFilePath
= m_Data
.m_yourFile
.GetFilename();
839 m_pwndRightView
->m_sConvertedFilePath
= m_Data
.m_yourFile
.GetConvertedFileName();
840 m_pwndRightView
->m_pWorkingFile
= &m_Data
.m_yourFile
;
842 m_pwndBottomView
->m_pViewData
= &m_Data
.m_Diff3
;
843 m_pwndBottomView
->texttype
= m_Data
.m_arTheirFile
.GetUnicodeType();
844 m_pwndBottomView
->lineendings
= m_Data
.m_arTheirFile
.GetLineEndings();
845 m_pwndBottomView
->m_sWindowName
.LoadString(IDS_VIEWTITLE_MERGED
);
846 m_pwndBottomView
->m_sWindowName
+= _T(" - ") + m_Data
.m_mergedFile
.GetWindowName();
847 m_pwndBottomView
->m_sFullFilePath
= m_Data
.m_mergedFile
.GetFilename();
848 m_pwndBottomView
->m_sConvertedFilePath
= m_Data
.m_mergedFile
.GetConvertedFileName();
849 m_pwndBottomView
->m_pWorkingFile
= &m_Data
.m_mergedFile
;
851 if (m_wndSplitter2
.IsColumnHidden(1))
852 m_wndSplitter2
.ShowColumn();
853 if (m_wndSplitter
.IsRowHidden(1))
854 m_wndSplitter
.ShowRow();
855 m_pwndLeftView
->SetHidden(FALSE
);
856 m_pwndRightView
->SetHidden(FALSE
);
857 m_pwndBottomView
->SetHidden(FALSE
);
858 // in three pane view, hide the line diff bar
859 m_wndLineDiffBar
.ShowPane(false, false, true);
860 m_wndLineDiffBar
.DocumentUpdated();
862 if (!m_Data
.m_mergedFile
.InUse())
864 m_Data
.m_mergedFile
.SetFileName(m_Data
.m_yourFile
.GetFilename());
866 m_pwndLeftView
->BuildAllScreen2ViewVector();
867 m_pwndLeftView
->DocumentUpdated();
868 m_pwndRightView
->DocumentUpdated();
869 m_pwndBottomView
->DocumentUpdated();
870 m_wndLocatorBar
.DocumentUpdated();
871 m_wndLineDiffBar
.DocumentUpdated();
873 SetActiveView(pwndActiveView
);
875 if ((line
>= -1) && m_pwndRightView
->m_pViewData
)
877 int n
= line
== -1 ? min( nOldLineNumber
, nOldLine
) : line
;
879 n
= m_pwndRightView
->m_pViewData
->FindLineNumber(n
);
883 m_pwndRightView
->ScrollAllToLine(n
);
887 if ((ptOldCaretPos
.x
>= 0) || (ptOldCaretPos
.y
>= 0))
889 m_pwndLeftView
->SetCaretPosition(p
);
890 m_pwndRightView
->SetCaretPosition(p
);
891 m_pwndBottomView
->SetCaretPosition(p
);
892 m_pwndBottomView
->ScrollToChar(0);
893 m_pwndLeftView
->ScrollToChar(0);
894 m_pwndRightView
->ScrollToChar(0);
898 CRegDWORD regFirstDiff
= CRegDWORD(_T("Software\\TortoiseGitMerge\\FirstDiffOnLoad"), TRUE
);
899 CRegDWORD regFirstConflict
= CRegDWORD(_T("Software\\TortoiseGitMerge\\FirstConflictOnLoad"), TRUE
);
900 bool bGoFirstDiff
= (0 != (DWORD
)regFirstDiff
);
901 bool bGoFirstConflict
= (0 != (DWORD
)regFirstConflict
);
902 if (bGoFirstConflict
&& (CheckResolved()>=0))
904 pwndActiveView
->GoToFirstConflict();
905 // Ignore the first few Mouse Move messages, so that the line diff stays on
906 // the first diff line until the user actually moves the mouse
907 m_nMoveMovesToIgnore
= MOVESTOIGNORE
;
909 else if (bGoFirstDiff
)
911 pwndActiveView
->GoToFirstDifference();
912 // Ignore the first few Mouse Move messages, so that the line diff stays on
913 // the first diff line until the user actually moves the mouse
914 m_nMoveMovesToIgnore
= MOVESTOIGNORE
;
918 // Avoid incorrect rendering of active pane.
919 m_pwndBottomView
->ScrollToChar(0);
920 m_pwndLeftView
->ScrollToChar(0);
921 m_pwndRightView
->ScrollToChar(0);
926 m_bSaveRequired
= false;
927 CUndo::GetInstance().Clear();
931 void CMainFrame::UpdateLayout()
935 m_wndSplitter
.CenterSplitter();
936 m_wndSplitter2
.CenterSplitter();
940 void CMainFrame::OnSize(UINT nType
, int cx
, int cy
)
942 CFrameWndEx::OnSize(nType
, cx
, cy
);
943 if (m_bInitSplitter
&& nType
!= SIZE_MINIMIZED
)
945 if (m_wndSplitter
.GetSafeHwnd())
947 if (m_wndSplitter
.HasOldRowSize() && (m_wndSplitter
.GetOldRowCount() == 2))
949 int oldTotal
= m_wndSplitter
.GetOldRowSize(0) + m_wndSplitter
.GetOldRowSize(1);
952 int cxCur0
, cxCur1
, cxMin0
, cxMin1
;
953 m_wndSplitter
.GetRowInfo(0, cxCur0
, cxMin0
);
954 m_wndSplitter
.GetRowInfo(1, cxCur1
, cxMin1
);
955 cxCur0
= m_wndSplitter
.GetOldRowSize(0) * (cxCur0
+ cxCur1
) / oldTotal
;
956 cxCur1
= m_wndSplitter
.GetOldRowSize(1) * (cxCur0
+ cxCur1
) / oldTotal
;
957 m_wndSplitter
.SetRowInfo(0, cxCur0
, 0);
958 m_wndSplitter
.SetRowInfo(1, cxCur1
, 0);
959 m_wndSplitter
.RecalcLayout();
963 if (m_wndSplitter2
.HasOldColSize() && (m_wndSplitter2
.GetOldColCount() == 2))
965 int oldTotal
= m_wndSplitter2
.GetOldColSize(0) + m_wndSplitter2
.GetOldColSize(1);
968 int cyCur0
, cyCur1
, cyMin0
, cyMin1
;
969 m_wndSplitter2
.GetColumnInfo(0, cyCur0
, cyMin0
);
970 m_wndSplitter2
.GetColumnInfo(1, cyCur1
, cyMin1
);
971 cyCur0
= m_wndSplitter2
.GetOldColSize(0) * (cyCur0
+ cyCur1
) / oldTotal
;
972 cyCur1
= m_wndSplitter2
.GetOldColSize(1) * (cyCur0
+ cyCur1
) / oldTotal
;
973 m_wndSplitter2
.SetColumnInfo(0, cyCur0
, 0);
974 m_wndSplitter2
.SetColumnInfo(1, cyCur1
, 0);
975 m_wndSplitter2
.RecalcLayout();
980 if ((nType
== SIZE_RESTORED
)&&m_bCheckReload
)
982 m_bCheckReload
= false;
986 // workaround for ribbon interface when taskbar is on the left/top
987 if (nType
== SIZE_MAXIMIZED
)
990 GetWindowPlacement(&wp
);
991 wp
.ptMaxPosition
.x
= wp
.ptMaxPosition
.y
= 0;
992 SetWindowPlacement(&wp
);
996 void CMainFrame::OnViewWhitespaces()
998 CRegDWORD regViewWhitespaces
= CRegDWORD(_T("Software\\TortoiseGitMerge\\ViewWhitespaces"), 1);
999 BOOL bViewWhitespaces
= regViewWhitespaces
;
1001 bViewWhitespaces
= m_pwndLeftView
->m_bViewWhitespace
;
1003 bViewWhitespaces
= !bViewWhitespaces
;
1004 regViewWhitespaces
= bViewWhitespaces
;
1007 m_pwndLeftView
->m_bViewWhitespace
= bViewWhitespaces
;
1008 m_pwndLeftView
->Invalidate();
1010 if (m_pwndRightView
)
1012 m_pwndRightView
->m_bViewWhitespace
= bViewWhitespaces
;
1013 m_pwndRightView
->Invalidate();
1015 if (m_pwndBottomView
)
1017 m_pwndBottomView
->m_bViewWhitespace
= bViewWhitespaces
;
1018 m_pwndBottomView
->Invalidate();
1022 void CMainFrame::OnUpdateViewWhitespaces(CCmdUI
*pCmdUI
)
1025 pCmdUI
->SetCheck(m_pwndLeftView
->m_bViewWhitespace
);
1028 void CMainFrame::OnViewCollapsed()
1030 m_regCollapsed
= !(DWORD
)m_regCollapsed
;
1031 m_bCollapsed
= !!(DWORD
)m_regCollapsed
;
1033 OnViewTextFoldUnfold();
1034 m_wndLocatorBar
.Invalidate();
1037 void CMainFrame::OnUpdateViewCollapsed(CCmdUI
*pCmdUI
)
1039 pCmdUI
->SetCheck(m_bCollapsed
);
1042 void CMainFrame::OnViewWraplonglines()
1044 m_bWrapLines
= !(DWORD
)m_regWrapLines
;
1045 m_regWrapLines
= m_bWrapLines
;
1047 if (m_pwndLeftView
) m_pwndLeftView
->WrapChanged();
1048 if (m_pwndRightView
) m_pwndRightView
->WrapChanged();
1049 if (m_pwndBottomView
) m_pwndBottomView
->WrapChanged();
1050 OnViewTextFoldUnfold();
1051 m_wndLocatorBar
.DocumentUpdated();
1054 void CMainFrame::OnViewTextFoldUnfold()
1056 OnViewTextFoldUnfold(m_pwndLeftView
);
1057 OnViewTextFoldUnfold(m_pwndRightView
);
1058 OnViewTextFoldUnfold(m_pwndBottomView
);
1061 void CMainFrame::OnViewTextFoldUnfold(CBaseView
* view
)
1065 view
->BuildAllScreen2ViewVector();
1066 view
->UpdateCaret();
1068 view
->EnsureCaretVisible();
1071 void CMainFrame::OnUpdateViewWraplonglines(CCmdUI
*pCmdUI
)
1073 pCmdUI
->SetCheck(m_bWrapLines
);
1076 void CMainFrame::OnViewOnewaydiff()
1078 if (CheckForSave(CHFSR_RELOAD
)==IDCANCEL
)
1080 m_bOneWay
= !m_bOneWay
;
1081 ShowDiffBar(!m_bOneWay
);
1085 void CMainFrame::ShowDiffBar(bool bShow
)
1089 // restore the line diff bar
1090 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
1091 m_wndLineDiffBar
.DocumentUpdated();
1092 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
1093 m_wndLocatorBar
.DocumentUpdated();
1097 // in one way view, hide the line diff bar
1098 m_wndLineDiffBar
.ShowPane(false, false, true);
1099 m_wndLineDiffBar
.DocumentUpdated();
1103 int CMainFrame::CheckResolved()
1105 //only in three way diffs can be conflicts!
1106 m_bHasConflicts
= true;
1107 if (m_pwndBottomView
->IsWindowVisible())
1109 CViewData
* viewdata
= m_pwndBottomView
->m_pViewData
;
1112 for (int i
=0; i
<viewdata
->GetCount(); i
++)
1114 const DiffStates state
= viewdata
->GetState(i
);
1115 if ((DIFFSTATE_CONFLICTED
== state
)||(DIFFSTATE_CONFLICTED_IGNORED
== state
))
1120 m_bHasConflicts
= false;
1124 int CMainFrame::SaveFile(const CString
& sFilePath
)
1126 CViewData
* pViewData
= NULL
;
1127 CFileTextLines
* pOriginFile
= &m_Data
.m_arBaseFile
;
1128 if (IsViewGood(m_pwndBottomView
))
1130 pViewData
= m_pwndBottomView
->m_pViewData
;
1132 else if (IsViewGood(m_pwndRightView
))
1134 pViewData
= m_pwndRightView
->m_pViewData
;
1135 if (m_Data
.IsYourFileInUse())
1136 pOriginFile
= &m_Data
.m_arYourFile
;
1137 else if (m_Data
.IsTheirFileInUse())
1138 pOriginFile
= &m_Data
.m_arTheirFile
;
1146 if ((pViewData
)&&(pOriginFile
))
1148 CFileTextLines file
;
1149 pOriginFile
->CopySettings(&file
);
1150 for (int i
=0; i
<pViewData
->GetCount(); i
++)
1152 //only copy non-removed lines
1153 DiffStates state
= pViewData
->GetState(i
);
1156 case DIFFSTATE_CONFLICTED
:
1157 case DIFFSTATE_CONFLICTED_IGNORED
:
1164 } while((last
<pViewData
->GetCount()) && ((pViewData
->GetState(last
)==DIFFSTATE_CONFLICTED
)||(pViewData
->GetState(last
)==DIFFSTATE_CONFLICTED_IGNORED
)));
1165 // TortoiseGitMerge changes here
1166 file
.Add(_T("<<<<<<< .mine"), m_pwndRightView
->lineendings
);
1167 for (int j
=first
; j
<last
; j
++)
1169 EOL lineending
= m_pwndRightView
->m_pViewData
->GetLineEnding(j
);
1170 if (lineending
== EOL_NOENDING
)
1171 lineending
= m_pwndRightView
->lineendings
;
1172 file
.Add(m_pwndRightView
->m_pViewData
->GetLine(j
), lineending
);
1174 file
.Add(_T("======="), m_pwndRightView
->lineendings
);
1175 for (int j
=first
; j
<last
; j
++)
1177 EOL lineending
= m_pwndLeftView
->m_pViewData
->GetLineEnding(j
);
1178 if (lineending
== EOL_NOENDING
)
1179 lineending
= m_pwndLeftView
->lineendings
;
1180 file
.Add(m_pwndLeftView
->m_pViewData
->GetLine(j
), lineending
);
1182 file
.Add(_T(">>>>>>> .theirs"), m_pwndRightView
->lineendings
);
1186 case DIFFSTATE_EMPTY
:
1187 case DIFFSTATE_CONFLICTEMPTY
:
1188 case DIFFSTATE_IDENTICALREMOVED
:
1189 case DIFFSTATE_REMOVED
:
1190 case DIFFSTATE_THEIRSREMOVED
:
1191 case DIFFSTATE_YOURSREMOVED
:
1192 case DIFFSTATE_CONFLICTRESOLVEDEMPTY
:
1193 // do not save removed lines
1196 file
.Add(pViewData
->GetLine(i
), pViewData
->GetLineEnding(i
));
1200 if (!file
.Save(sFilePath
, false, false))
1202 CMessageBox::Show(m_hWnd
, file
.GetErrorString(), _T("TortoiseGitMerge"), MB_ICONERROR
);
1205 if (sFilePath
== m_Data
.m_baseFile
.GetFilename())
1207 m_Data
.m_baseFile
.StoreFileAttributes();
1209 if (sFilePath
== m_Data
.m_theirFile
.GetFilename())
1211 m_Data
.m_theirFile
.StoreFileAttributes();
1213 if (sFilePath
== m_Data
.m_yourFile
.GetFilename())
1215 m_Data
.m_yourFile
.StoreFileAttributes();
1217 /*if (sFilePath == m_Data.m_mergedFile.GetFilename())
1219 m_Data.m_mergedFile.StoreFileAttributes();
1221 m_dlgFilePatches
.SetFileStatusAsPatched(sFilePath
);
1222 if (m_pwndBottomView
)
1223 m_pwndBottomView
->SetModified(FALSE
);
1224 if (m_pwndRightView
)
1225 m_pwndRightView
->SetModified(FALSE
);
1226 CUndo::GetInstance().MarkAsOriginalState();
1227 if (file
.GetCount() == 1 && file
.GetAt(0).IsEmpty() && file
.GetLineEnding(0) == EOL_NOENDING
)
1229 return file
.GetCount();
1234 void CMainFrame::OnFileSave()
1236 // when mutiple files are set as writable we have to ask what file to save
1237 int nEditableViewCount
=
1238 (CBaseView::IsViewGood(m_pwndLeftView
) && m_pwndLeftView
->IsWritable() ? 1 : 0)
1239 + (CBaseView::IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsWritable() ? 1 : 0)
1240 + (CBaseView::IsViewGood(m_pwndBottomView
) && m_pwndBottomView
->IsWritable() ? 1 : 0);
1241 bool bLeftIsModified
= CBaseView::IsViewGood(m_pwndLeftView
) && m_pwndLeftView
->IsModified();
1242 bool bRightIsModified
= CBaseView::IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsModified();
1243 bool bBottomIsModified
= CBaseView::IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsModified();
1244 int nModifiedViewCount
=
1245 (bLeftIsModified
? 1 : 0)
1246 + (bRightIsModified
? 1 : 0)
1247 + (bBottomIsModified
? 1 : 0);
1248 if (nEditableViewCount
>1)
1250 if (nModifiedViewCount
>0)
1254 CString
sSubTitle("Save");
1255 CString
sTitle("There are more views set editable.\nWhat view you want to save?");
1257 // show separate questions
1258 // first show question for left view
1259 ret
= MessageBox(sTitle
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
1262 m_pwndLeftView
->SaveFile(SAVE_REMOVED
);
1264 // right file is handled old way
1270 // only target view was modified
1275 void CMainFrame::PatchSave()
1277 bool bDoesNotExist
= !PathFileExists(m_Data
.m_mergedFile
.GetFilename());
1278 if (m_Data
.m_bPatchRequired
)
1280 m_Patch
.PatchPath(m_Data
.m_mergedFile
.GetFilename());
1282 if (!PathIsDirectory(m_Data
.m_mergedFile
.GetFilename()))
1284 int saveret
= SaveFile(m_Data
.m_mergedFile
.GetFilename());
1287 // file was saved with 0 lines, remove it.
1288 m_Patch
.RemoveFile(m_Data
.m_mergedFile
.GetFilename());
1290 DeleteFile(m_Data
.m_mergedFile
.GetFilename());
1292 m_Data
.m_mergedFile
.StoreFileAttributes();
1293 if (m_Data
.m_mergedFile
.GetFilename() == m_Data
.m_yourFile
.GetFilename())
1294 m_Data
.m_yourFile
.StoreFileAttributes();
1295 if ((bDoesNotExist
)&&(DWORD(CRegDWORD(_T("Software\\TortoiseGitMerge\\AutoAdd"), TRUE
))))
1297 // call TortoiseProc to add the new file to version control
1298 CString cmd
= _T("/command:add /noui /path:\"");
1299 cmd
+= m_Data
.m_mergedFile
.GetFilename() + _T("\"");
1300 CAppUtils::RunTortoiseGitProc(cmd
);
1305 bool CMainFrame::FileSave(bool bCheckResolved
/*=true*/)
1307 if (!m_Data
.m_mergedFile
.InUse())
1308 return FileSaveAs(bCheckResolved
);
1309 // check if the file has the readonly attribute set
1310 bool bDoesNotExist
= false;
1311 DWORD fAttribs
= GetFileAttributes(m_Data
.m_mergedFile
.GetFilename());
1312 if ((fAttribs
!= INVALID_FILE_ATTRIBUTES
)&&(fAttribs
& FILE_ATTRIBUTE_READONLY
))
1313 return FileSaveAs(bCheckResolved
);
1314 if (fAttribs
== INVALID_FILE_ATTRIBUTES
)
1316 bDoesNotExist
= (GetLastError() == ERROR_FILE_NOT_FOUND
);
1318 if (bCheckResolved
&& HasConflictsWontKeep())
1321 if (((DWORD
)CRegDWORD(_T("Software\\TortoiseGitMerge\\Backup"))) != 0)
1323 MoveFileEx(m_Data
.m_mergedFile
.GetFilename(), m_Data
.m_mergedFile
.GetFilename() + _T(".bak"), MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
| MOVEFILE_WRITE_THROUGH
);
1325 if (m_Data
.m_bPatchRequired
)
1327 m_Patch
.PatchPath(m_Data
.m_mergedFile
.GetFilename());
1329 int saveret
= SaveFile(m_Data
.m_mergedFile
.GetFilename());
1332 // file was saved with 0 lines!
1333 // ask the user if the file should be deleted
1335 sTemp
.Format(IDS_DELETEWHENEMPTY
, (LPCTSTR
)m_Data
.m_mergedFile
.GetFilename());
1336 if (CMessageBox::ShowCheck(m_hWnd
, sTemp
, _T("TortoiseGitMerge"), MB_YESNO
, _T("DeleteFileWhenEmpty")) == IDYES
)
1338 m_Patch
.RemoveFile(m_Data
.m_mergedFile
.GetFilename());
1339 DeleteFile(m_Data
.m_mergedFile
.GetFilename());
1342 else if (saveret
< 0)
1344 // error while saving the file
1348 // if we're in conflict resolve mode (three pane view), check if there are no more conflicts
1349 // and if there aren't, ask to mark the file as resolved
1350 if (IsViewGood(m_pwndBottomView
) && !m_bHasConflicts
)
1352 CString projectRoot
;
1353 if (g_GitAdminDir
.HasAdminDir(m_Data
.m_mergedFile
.GetFilename(), false, &projectRoot
))
1355 CString subpath
= m_Data
.m_mergedFile
.GetFilename();
1356 subpath
.Replace(_T('\\'), _T('/'));
1357 if (subpath
.GetLength() >= projectRoot
.GetLength())
1359 if (subpath
[projectRoot
.GetLength()] == _T('/'))
1360 subpath
= subpath
.Right(subpath
.GetLength() - projectRoot
.GetLength() - 1);
1362 subpath
= subpath
.Right(subpath
.GetLength() - projectRoot
.GetLength());
1365 CStringA gitdir
= CUnicodeUtils::GetMulti(projectRoot
, CP_UTF8
);
1366 git_repository
*repository
= NULL
;
1367 git_index
*index
= NULL
;
1368 bool hasConflictInIndex
= false;
1371 if (git_repository_open(&repository
, gitdir
.GetBuffer()))
1373 gitdir
.ReleaseBuffer();
1376 gitdir
.ReleaseBuffer();
1378 if (git_repository_index(&index
, repository
))
1381 CStringA path
= CUnicodeUtils::GetMulti(subpath
, CP_UTF8
);
1382 const git_index_entry
* entry
= git_index_get_bypath(index
, path
.GetBuffer(), 1);
1383 path
.ReleaseBuffer();
1384 hasConflictInIndex
= entry
!= nullptr;
1388 git_index_free(index
);
1391 git_repository_free(repository
);
1393 if (hasConflictInIndex
)
1396 sTemp
.Format(IDS_MARKASRESOLVED
, (LPCTSTR
)CPathUtils::GetFileNameFromPath(m_Data
.m_mergedFile
.GetFilename()));
1397 if (CMessageBox::Show(m_hWnd
, sTemp
, _T("TortoiseGitMerge"), MB_YESNO
| MB_ICONQUESTION
) == IDYES
)
1403 m_bSaveRequired
= false;
1404 m_Data
.m_mergedFile
.StoreFileAttributes();
1406 if ((bDoesNotExist
)&&(DWORD(CRegDWORD(_T("Software\\TortoiseGitMerge\\AutoAdd"), TRUE
))))
1408 // call TortoiseProc to add the new file to version control
1409 CString cmd
= _T("/command:add /noui /path:\"");
1410 cmd
+= m_Data
.m_mergedFile
.GetFilename() + _T("\"");
1411 if(!CAppUtils::RunTortoiseGitProc(cmd
))
1417 void CMainFrame::OnFileSaveAs()
1422 bool CMainFrame::FileSaveAs(bool bCheckResolved
/*=true*/)
1424 if (bCheckResolved
&& HasConflictsWontKeep())
1428 if(!TryGetFileName(fileName
))
1435 void CMainFrame::OnUpdateFileSave(CCmdUI
*pCmdUI
)
1437 BOOL bEnable
= FALSE
;
1438 if (m_Data
.m_mergedFile
.InUse())
1440 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1442 else if ( (IsViewGood(m_pwndRightView
)&&(m_pwndRightView
->m_pViewData
)) &&
1443 (m_pwndRightView
->IsModified() || (m_Data
.m_yourFile
.GetWindowName().Right(9).Compare(_T(": patched"))==0)) )
1446 pCmdUI
->Enable(bEnable
);
1449 void CMainFrame::OnUpdateFileSaveAs(CCmdUI
*pCmdUI
)
1451 BOOL bEnable
= FALSE
;
1452 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1454 else if (IsViewGood(m_pwndRightView
)&&(m_pwndRightView
->m_pViewData
))
1456 pCmdUI
->Enable(bEnable
);
1459 void CMainFrame::OnUpdateViewOnewaydiff(CCmdUI
*pCmdUI
)
1461 pCmdUI
->SetCheck(!m_bOneWay
);
1462 BOOL bEnable
= TRUE
;
1463 if (IsViewGood(m_pwndBottomView
))
1467 pCmdUI
->Enable(bEnable
);
1470 void CMainFrame::OnViewOptions()
1473 sTemp
.LoadString(IDS_SETTINGSTITLE
);
1474 CSettings
dlg(sTemp
);
1476 if (dlg
.IsReloadNeeded())
1478 if (CheckForSave(CHFSR_OPTIONS
)==IDCANCEL
)
1480 CDiffColors::GetInstance().LoadRegistry();
1484 CDiffColors::GetInstance().LoadRegistry();
1485 if (m_pwndBottomView
)
1486 m_pwndBottomView
->Invalidate();
1488 m_pwndLeftView
->Invalidate();
1489 if (m_pwndRightView
)
1490 m_pwndRightView
->Invalidate();
1493 void CMainFrame::OnClose()
1495 if (CheckForSave(CHFSR_CLOSE
)!=IDCANCEL
)
1499 // before it is destroyed, save the position of the window
1500 wp
.length
= sizeof wp
;
1502 if (GetWindowPlacement(&wp
))
1506 // never restore to Iconic state
1507 wp
.showCmd
= SW_SHOW
;
1509 if ((wp
.flags
& WPF_RESTORETOMAXIMIZED
) != 0)
1510 // if maximized and maybe iconic restore maximized state
1511 wp
.showCmd
= SW_SHOWMAXIMIZED
;
1514 WriteWindowPlacement(&wp
);
1520 void CMainFrame::OnActivate(UINT nValue
, CWnd
* /*pwnd*/, BOOL
/*bActivated?*/)
1522 if (nValue
!= 0) // activated
1526 m_bCheckReload
= TRUE
;
1533 void CMainFrame::OnViewLinedown()
1535 OnViewLineUpDown(1);
1538 void CMainFrame::OnViewLineup()
1540 OnViewLineUpDown(-1);
1543 void CMainFrame::OnViewLineUpDown(int direction
)
1546 m_pwndLeftView
->ScrollToLine(m_pwndLeftView
->m_nTopLine
+direction
);
1547 if (m_pwndRightView
)
1548 m_pwndRightView
->ScrollToLine(m_pwndRightView
->m_nTopLine
+direction
);
1549 if (m_pwndBottomView
)
1550 m_pwndBottomView
->ScrollToLine(m_pwndBottomView
->m_nTopLine
+direction
);
1551 m_wndLocatorBar
.Invalidate();
1552 m_nMoveMovesToIgnore
= MOVESTOIGNORE
;
1555 void CMainFrame::OnViewLineleft()
1557 OnViewLineLeftRight(-1);
1560 void CMainFrame::OnViewLineright()
1562 OnViewLineLeftRight(1);
1565 void CMainFrame::OnViewLineLeftRight(int direction
)
1568 m_pwndLeftView
->ScrollSide(direction
);
1569 if (m_pwndRightView
)
1570 m_pwndRightView
->ScrollSide(direction
);
1571 if (m_pwndBottomView
)
1572 m_pwndBottomView
->ScrollSide(direction
);
1575 void CMainFrame::OnEditUseTheirs()
1577 if (m_pwndBottomView
)
1578 m_pwndBottomView
->UseTheirTextBlock();
1580 void CMainFrame::OnUpdateEditUsetheirblock(CCmdUI
*pCmdUI
)
1582 pCmdUI
->Enable(m_pwndBottomView
&& m_pwndBottomView
->HasSelection());
1585 void CMainFrame::OnEditUseMine()
1587 if (m_pwndBottomView
)
1588 m_pwndBottomView
->UseMyTextBlock();
1590 void CMainFrame::OnUpdateEditUsemyblock(CCmdUI
*pCmdUI
)
1592 OnUpdateEditUsetheirblock(pCmdUI
);
1595 void CMainFrame::OnEditUseTheirsThenMine()
1597 if (m_pwndBottomView
)
1598 m_pwndBottomView
->UseTheirAndYourBlock();
1601 void CMainFrame::OnUpdateEditUsetheirthenmyblock(CCmdUI
*pCmdUI
)
1603 OnUpdateEditUsetheirblock(pCmdUI
);
1606 void CMainFrame::OnEditUseMineThenTheirs()
1608 if (m_pwndBottomView
)
1609 m_pwndBottomView
->UseYourAndTheirBlock();
1612 void CMainFrame::OnUpdateEditUseminethentheirblock(CCmdUI
*pCmdUI
)
1614 OnUpdateEditUsetheirblock(pCmdUI
);
1617 void CMainFrame::OnEditUseleftblock()
1619 if (m_pwndBottomView
->IsWindowVisible())
1620 m_pwndBottomView
->UseRightBlock();
1622 m_pwndRightView
->UseLeftBlock();
1625 void CMainFrame::OnUpdateEditUseleftblock(CCmdUI
*pCmdUI
)
1627 pCmdUI
->Enable(IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsTarget() && m_pwndRightView
->HasSelection());
1630 void CMainFrame::OnUpdateUseBlock(CCmdUI
*pCmdUI
)
1632 pCmdUI
->Enable(TRUE
);
1635 void CMainFrame::OnEditUseleftfile()
1637 if (m_pwndBottomView
->IsWindowVisible())
1638 m_pwndBottomView
->UseRightFile();
1640 m_pwndRightView
->UseLeftFile();
1643 void CMainFrame::OnUpdateEditUseleftfile(CCmdUI
*pCmdUI
)
1645 pCmdUI
->Enable(IsViewGood(m_pwndRightView
) && m_pwndRightView
->IsTarget());
1648 void CMainFrame::OnEditUseblockfromleftbeforeright()
1650 if (m_pwndRightView
)
1651 m_pwndRightView
->UseBothLeftFirst();
1654 void CMainFrame::OnUpdateEditUseblockfromleftbeforeright(CCmdUI
*pCmdUI
)
1656 OnUpdateEditUseleftblock(pCmdUI
);
1659 void CMainFrame::OnEditUseblockfromrightbeforeleft()
1661 if (m_pwndRightView
)
1662 m_pwndRightView
->UseBothRightFirst();
1665 void CMainFrame::OnUpdateEditUseblockfromrightbeforeleft(CCmdUI
*pCmdUI
)
1667 OnUpdateEditUseleftblock(pCmdUI
);
1670 void CMainFrame::OnFileReload()
1672 if (CheckForSave(CHFSR_RELOAD
)==IDCANCEL
)
1674 CDiffColors::GetInstance().LoadRegistry();
1678 void CMainFrame::ActivateFrame(int nCmdShow
)
1680 // nCmdShow is the normal show mode this frame should be in
1681 // translate default nCmdShow (-1)
1684 if (!IsWindowVisible())
1685 nCmdShow
= SW_SHOWNORMAL
;
1686 else if (IsIconic())
1687 nCmdShow
= SW_RESTORE
;
1690 // bring to top before showing
1691 BringToTop(nCmdShow
);
1695 // show the window as specified
1698 if ( !ReadWindowPlacement(&wp
) )
1700 ShowWindow(nCmdShow
);
1704 if ( nCmdShow
!= SW_SHOWNORMAL
)
1705 wp
.showCmd
= nCmdShow
;
1707 SetWindowPlacement(&wp
);
1710 // and finally, bring to top after showing
1711 BringToTop(nCmdShow
);
1715 BOOL
CMainFrame::ReadWindowPlacement(WINDOWPLACEMENT
* pwp
)
1717 CRegString placement
= CRegString(_T("Software\\TortoiseGitMerge\\WindowPos"));
1718 CString sPlacement
= placement
;
1719 if (sPlacement
.IsEmpty())
1721 int nRead
= _stscanf_s(sPlacement
, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
1722 &pwp
->flags
, &pwp
->showCmd
,
1723 &pwp
->ptMinPosition
.x
, &pwp
->ptMinPosition
.y
,
1724 &pwp
->ptMaxPosition
.x
, &pwp
->ptMaxPosition
.y
,
1725 &pwp
->rcNormalPosition
.left
, &pwp
->rcNormalPosition
.top
,
1726 &pwp
->rcNormalPosition
.right
, &pwp
->rcNormalPosition
.bottom
);
1729 pwp
->length
= sizeof(WINDOWPLACEMENT
);
1734 void CMainFrame::WriteWindowPlacement(WINDOWPLACEMENT
* pwp
)
1736 CRegString placement
= CRegString(_T("Software\\TortoiseGitMerge\\WindowPos"));
1737 TCHAR szBuffer
[_countof("-32767")*8 + sizeof("65535")*2];
1739 _stprintf_s(szBuffer
, _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d"),
1740 pwp
->flags
, pwp
->showCmd
,
1741 pwp
->ptMinPosition
.x
, pwp
->ptMinPosition
.y
,
1742 pwp
->ptMaxPosition
.x
, pwp
->ptMaxPosition
.y
,
1743 pwp
->rcNormalPosition
.left
, pwp
->rcNormalPosition
.top
,
1744 pwp
->rcNormalPosition
.right
, pwp
->rcNormalPosition
.bottom
);
1745 placement
= szBuffer
;
1748 void CMainFrame::OnUpdateMergeMarkasresolved(CCmdUI
*pCmdUI
)
1752 BOOL bEnable
= FALSE
;
1753 if ((!m_bReadOnly
)&&(m_Data
.m_mergedFile
.InUse()))
1755 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1760 pCmdUI
->Enable(bEnable
);
1763 void CMainFrame::OnMergeMarkasresolved()
1765 if(HasConflictsWontKeep())
1768 // now check if the file has already been saved and if not, save it.
1769 if (m_Data
.m_mergedFile
.InUse())
1771 if (IsViewGood(m_pwndBottomView
)&&(m_pwndBottomView
->m_pViewData
))
1774 m_bSaveRequired
= false;
1780 BOOL
CMainFrame::MarkAsResolved()
1784 if (!IsViewGood(m_pwndBottomView
))
1787 CString cmd
= _T("/command:resolve /path:\"");
1788 cmd
+= m_Data
.m_mergedFile
.GetFilename();
1789 cmd
+= _T("\" /closeonend:1 /noquestion /skipcheck /silent");
1793 s
.Format(L
" /resolvemsghwnd:%I64d /resolvemsgwparam:%I64d /resolvemsglparam:%I64d", (__int64
)resolveMsgWnd
, (__int64
)resolveMsgWParam
, (__int64
)resolveMsgLParam
);
1796 if(!CAppUtils::RunTortoiseGitProc(cmd
))
1798 m_bSaveRequired
= false;
1802 void CMainFrame::OnUpdateMergeNextconflict(CCmdUI
*pCmdUI
)
1805 if (HasNextConflict(m_pwndBottomView
))
1807 else if (HasNextConflict(m_pwndRightView
))
1809 else if (HasNextConflict(m_pwndLeftView
))
1811 pCmdUI
->Enable(bShow
);
1814 bool CMainFrame::HasNextConflict(CBaseView
* view
)
1818 if (!view
->IsTarget())
1820 return view
->HasNextConflict();
1823 void CMainFrame::OnUpdateMergePreviousconflict(CCmdUI
*pCmdUI
)
1826 if (HasPrevConflict(m_pwndBottomView
))
1828 else if (HasPrevConflict(m_pwndRightView
))
1830 else if (HasPrevConflict(m_pwndLeftView
))
1832 pCmdUI
->Enable(bShow
);
1835 bool CMainFrame::HasPrevConflict(CBaseView
* view
)
1839 if (!view
->IsTarget())
1841 return view
->HasPrevConflict();
1844 void CMainFrame::OnUpdateNavigateNextdifference(CCmdUI
*pCmdUI
)
1846 CBaseView
* baseView
= GetActiveBaseView();
1849 bShow
= baseView
->HasNextDiff();
1850 pCmdUI
->Enable(bShow
);
1853 void CMainFrame::OnUpdateNavigatePreviousdifference(CCmdUI
*pCmdUI
)
1855 CBaseView
* baseView
= GetActiveBaseView();
1858 bShow
= baseView
->HasPrevDiff();
1859 pCmdUI
->Enable(bShow
);
1862 void CMainFrame::OnUpdateNavigateNextinlinediff(CCmdUI
*pCmdUI
)
1865 if (HasNextInlineDiff(m_pwndBottomView
))
1867 else if (HasNextInlineDiff(m_pwndRightView
))
1869 else if (HasNextInlineDiff(m_pwndLeftView
))
1871 pCmdUI
->Enable(bShow
);
1874 bool CMainFrame::HasNextInlineDiff(CBaseView
* view
)
1878 if (!view
->IsTarget())
1880 return view
->HasNextInlineDiff();
1883 void CMainFrame::OnUpdateNavigatePrevinlinediff(CCmdUI
*pCmdUI
)
1886 if (HasPrevInlineDiff(m_pwndBottomView
))
1888 else if (HasPrevInlineDiff(m_pwndRightView
))
1890 else if (HasPrevInlineDiff(m_pwndLeftView
))
1892 pCmdUI
->Enable(bShow
);
1895 bool CMainFrame::HasPrevInlineDiff(CBaseView
* view
)
1899 if (!view
->IsTarget())
1901 return view
->HasPrevInlineDiff();
1904 void CMainFrame::OnMoving(UINT fwSide
, LPRECT pRect
)
1906 // if the pathfilelist dialog is attached to the mainframe,
1907 // move it along with the mainframe
1908 if (::IsWindow(m_dlgFilePatches
.m_hWnd
))
1911 m_dlgFilePatches
.GetWindowRect(&patchrect
);
1912 if (::IsWindow(m_hWnd
))
1915 GetWindowRect(&thisrect
);
1916 if (patchrect
.right
== thisrect
.left
)
1918 m_dlgFilePatches
.SetWindowPos(NULL
, patchrect
.left
- (thisrect
.left
- pRect
->left
), patchrect
.top
- (thisrect
.top
- pRect
->top
),
1919 0, 0, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
| SWP_NOSIZE
| SWP_NOZORDER
);
1923 __super::OnMoving(fwSide
, pRect
);
1926 void CMainFrame::OnUpdateEditCopy(CCmdUI
*pCmdUI
)
1929 if ((m_pwndBottomView
)&&(m_pwndBottomView
->HasSelection()))
1931 else if ((m_pwndRightView
)&&(m_pwndRightView
->HasSelection()))
1933 else if ((m_pwndLeftView
)&&(m_pwndLeftView
->HasSelection()))
1935 pCmdUI
->Enable(bShow
);
1938 void CMainFrame::OnUpdateEditPaste(CCmdUI
*pCmdUI
)
1940 BOOL bWritable
= FALSE
;
1941 if ((m_pwndBottomView
)&&(m_pwndBottomView
->IsWritable()))
1943 else if ((m_pwndRightView
)&&(m_pwndRightView
->IsWritable()))
1945 else if ((m_pwndLeftView
)&&(m_pwndLeftView
->IsWritable()))
1947 pCmdUI
->Enable(bWritable
&& ::IsClipboardFormatAvailable(CF_TEXT
));
1950 void CMainFrame::OnViewSwitchleft()
1952 if (CheckForSave(CHFSR_SWITCH
)!=IDCANCEL
)
1954 CWorkingFile file
= m_Data
.m_baseFile
;
1955 m_Data
.m_baseFile
= m_Data
.m_yourFile
;
1956 m_Data
.m_yourFile
= file
;
1957 if (m_Data
.m_mergedFile
.GetFilename().CompareNoCase(m_Data
.m_yourFile
.GetFilename())==0)
1959 m_Data
.m_mergedFile
= m_Data
.m_baseFile
;
1961 else if (m_Data
.m_mergedFile
.GetFilename().CompareNoCase(m_Data
.m_baseFile
.GetFilename())==0)
1963 m_Data
.m_mergedFile
= m_Data
.m_yourFile
;
1969 void CMainFrame::OnUpdateViewSwitchleft(CCmdUI
*pCmdUI
)
1971 BOOL bEnable
= !IsViewGood(m_pwndBottomView
);
1972 pCmdUI
->Enable(bEnable
);
1975 void CMainFrame::OnUpdateViewShowfilelist(CCmdUI
*pCmdUI
)
1977 BOOL bEnable
= m_dlgFilePatches
.HasFiles();
1978 pCmdUI
->Enable(bEnable
);
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
);
1995 void CMainFrame::OnUpdateEditUndo(CCmdUI
*pCmdUI
)
1997 pCmdUI
->Enable(CUndo::GetInstance().CanUndo());
2000 void CMainFrame::OnEditEnable()
2002 CBaseView
* pView
= GetActiveBaseView();
2003 if (pView
&& pView
->IsReadonlyChangable())
2005 bool isReadOnly
= pView
->IsReadonly();
2006 pView
->SetReadonly(!isReadOnly
);
2010 void CMainFrame::OnUpdateEditEnable(CCmdUI
*pCmdUI
)
2012 CBaseView
* pView
= GetActiveBaseView();
2015 pCmdUI
->Enable(pView
->IsReadonlyChangable() || !pView
->IsReadonly());
2016 pCmdUI
->SetCheck(!pView
->IsReadonly());
2020 pCmdUI
->Enable(FALSE
);
2024 int CMainFrame::CheckForReload()
2026 static bool bLock
= false; //we don't want to check when activated after MessageBox we just created ... this is simple, but we don't need multithread lock
2032 bool bSourceChanged
=
2033 m_Data
.m_baseFile
.HasSourceFileChanged()
2034 || m_Data
.m_yourFile
.HasSourceFileChanged()
2035 || m_Data
.m_theirFile
.HasSourceFileChanged()
2036 /*|| m_Data.m_mergedFile.HasSourceFileChanged()*/;
2037 if (!bSourceChanged
)
2043 int idsMessage
= HasUnsavedEdits() ? IDS_WARNMODIFIEDOUTSIDELOOSECHANGES
: IDS_WARNMODIFIEDOUTSIDE
;
2044 UINT ret
= CMessageBox::Show(m_hWnd
, idsMessage
, IDS_APPNAME
, MB_YESNO
| MB_ICONQUESTION
);
2048 CDiffColors::GetInstance().LoadRegistry();
2053 if (IsViewGood(m_pwndBottomView
)) // three pane view
2055 /*if (m_Data.m_sourceFile.HasSourceFileChanged())
2056 m_pwndBottomView->SetModified();
2057 if (m_Data.m_mergedFile.HasSourceFileChanged())
2058 m_pwndBottomView->SetModified();//*/
2059 if (m_Data
.m_yourFile
.HasSourceFileChanged())
2060 m_pwndRightView
->SetModified();
2061 if (m_Data
.m_theirFile
.HasSourceFileChanged())
2062 m_pwndLeftView
->SetModified();
2064 else if (IsViewGood(m_pwndRightView
)) // two pane view
2066 if (m_Data
.m_baseFile
.HasSourceFileChanged())
2067 m_pwndLeftView
->SetModified();
2068 if (m_Data
.m_yourFile
.HasSourceFileChanged())
2069 m_pwndRightView
->SetModified();
2073 if (m_Data
.m_yourFile
.HasSourceFileChanged())
2074 m_pwndLeftView
->SetModified();
2077 // no reload just store updated file time
2078 m_Data
.m_baseFile
.StoreFileAttributes();
2079 m_Data
.m_theirFile
.StoreFileAttributes();
2080 m_Data
.m_yourFile
.StoreFileAttributes();
2081 //m_Data.m_mergedFile.StoreFileAttributes();
2087 int CMainFrame::CheckForSave(ECheckForSaveReason eReason
)
2089 CString
sTitle(MAKEINTRESOURCE(IDS_WARNMODIFIEDLOOSECHANGES
));
2090 // todo use resources instead of constants; we may hold resource id instaed of string
2094 sTitle
= CString(MAKEINTRESOURCE(IDS_ASKFORSAVE
)); // use more descriptive IDS_WARNMODIFIEDLOOSECHANGES instead?
2097 sTitle
= CString(MAKEINTRESOURCE(IDS_WARNMODIFIEDLOOSECHANGES
));
2100 sTitle
= CString(MAKEINTRESOURCE(IDS_WARNMODIFIEDLOOSECHANGES
));
2103 sTitle
= CString(MAKEINTRESOURCE(IDS_WARNMODIFIEDLOOSECHANGESOPTIONS
));
2106 sTitle
= CString(MAKEINTRESOURCE(IDS_WARNMODIFIEDLOOSECHANGES
));
2110 // TODO simplify logic, reduce code duplication
2111 if (CBaseView::IsViewGood(m_pwndBottomView
))
2113 // three-way diff - by design only bottom can be changed
2115 else if (CBaseView::IsViewGood(m_pwndRightView
))
2118 // in 1.7 version only right was saved, now left and/or right can be save, so we need to indicate what we are asking to save
2119 if (HasUnsavedEdits(m_pwndLeftView
))
2124 // show separate questions
2125 // first show question for left view
2126 ret
= MessageBox(sTitle
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
2127 if (ret
== IDCANCEL
)
2133 if (m_pwndLeftView
->SaveFile(SAVE_REMOVED
)<0)
2138 // right file is handled old way
2143 // only secondary (left) view
2145 // otherwise 1.7 behaviour is used
2147 else if (CBaseView::IsViewGood(m_pwndLeftView
))
2149 // only one view - only one to save
2150 // 1.7 FileSave don't support this mode
2151 if (HasUnsavedEdits(m_pwndLeftView
))
2155 ret
= MessageBox(sTitle
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
2160 if (m_pwndLeftView
->SaveFile(SAVE_REMOVED
)<0)
2168 return IDNO
; // nothing to save
2172 if (HasUnsavedEdits())
2174 ret
= MessageBox(sTitle
, 0, MB_YESNOCANCEL
| MB_ICONQUESTION
);
2185 bool CMainFrame::HasUnsavedEdits() const
2187 return HasUnsavedEdits(m_pwndBottomView
) || HasUnsavedEdits(m_pwndRightView
) || m_bSaveRequired
;
2190 bool CMainFrame::HasUnsavedEdits(const CBaseView
* view
)
2194 return view
->IsModified();
2197 bool CMainFrame::IsViewGood(const CBaseView
* view
)
2199 return CBaseView::IsViewGood(view
);
2202 void CMainFrame::OnViewInlinediffword()
2204 m_bInlineWordDiff
= !m_bInlineWordDiff
;
2207 m_pwndLeftView
->SetInlineWordDiff(m_bInlineWordDiff
);
2208 m_pwndLeftView
->BuildAllScreen2ViewVector();
2209 m_pwndLeftView
->DocumentUpdated();
2211 if (m_pwndRightView
)
2213 m_pwndRightView
->SetInlineWordDiff(m_bInlineWordDiff
);
2214 m_pwndRightView
->BuildAllScreen2ViewVector();
2215 m_pwndRightView
->DocumentUpdated();
2217 if (m_pwndBottomView
)
2219 m_pwndBottomView
->SetInlineWordDiff(m_bInlineWordDiff
);
2220 m_pwndBottomView
->BuildAllScreen2ViewVector();
2221 m_pwndBottomView
->DocumentUpdated();
2223 m_wndLineDiffBar
.DocumentUpdated();
2226 void CMainFrame::OnUpdateViewInlinediffword(CCmdUI
*pCmdUI
)
2228 pCmdUI
->Enable(m_bInlineDiff
&& IsViewGood(m_pwndLeftView
) && IsViewGood(m_pwndRightView
));
2229 pCmdUI
->SetCheck(m_bInlineWordDiff
);
2232 void CMainFrame::OnViewInlinediff()
2234 m_bInlineDiff
= !m_bInlineDiff
;
2237 m_pwndLeftView
->SetInlineDiff(m_bInlineDiff
);
2238 m_pwndLeftView
->BuildAllScreen2ViewVector();
2239 m_pwndLeftView
->DocumentUpdated();
2241 if (m_pwndRightView
)
2243 m_pwndRightView
->SetInlineDiff(m_bInlineDiff
);
2244 m_pwndRightView
->BuildAllScreen2ViewVector();
2245 m_pwndRightView
->DocumentUpdated();
2247 if (m_pwndBottomView
)
2249 m_pwndBottomView
->SetInlineDiff(m_bInlineDiff
);
2250 m_pwndBottomView
->BuildAllScreen2ViewVector();
2251 m_pwndBottomView
->DocumentUpdated();
2253 m_wndLineDiffBar
.DocumentUpdated();
2256 void CMainFrame::OnUpdateViewInlinediff(CCmdUI
*pCmdUI
)
2258 pCmdUI
->Enable(IsViewGood(m_pwndLeftView
) && IsViewGood(m_pwndRightView
));
2259 pCmdUI
->SetCheck(m_bInlineDiff
);
2262 void CMainFrame::OnUpdateEditCreateunifieddifffile(CCmdUI
*pCmdUI
)
2264 // "create unified diff file" is only available if two files
2265 // are diffed, not three.
2266 bool bEnabled
= true;
2267 if (!IsViewGood(m_pwndLeftView
))
2269 else if (!IsViewGood(m_pwndRightView
))
2271 else if (IsViewGood(m_pwndBottomView
)) //no negation here
2273 pCmdUI
->Enable(bEnabled
);
2276 void CMainFrame::OnEditCreateunifieddifffile()
2278 CString origFile
, modifiedFile
;
2279 // the original file is the one on the left
2281 origFile
= m_pwndLeftView
->m_sFullFilePath
;
2282 if (m_pwndRightView
)
2283 modifiedFile
= m_pwndRightView
->m_sFullFilePath
;
2284 if (origFile
.IsEmpty() || modifiedFile
.IsEmpty())
2288 if(!TryGetFileName(outputFile
))
2291 CAppUtils::CreateUnifiedDiff(origFile
, modifiedFile
, outputFile
, true);
2294 void CMainFrame::OnUpdateViewLinediffbar(CCmdUI
*pCmdUI
)
2296 pCmdUI
->SetCheck(m_bLineDiff
);
2300 void CMainFrame::OnViewLinediffbar()
2302 m_bLineDiff
= !m_bLineDiff
;
2303 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
2304 m_wndLineDiffBar
.DocumentUpdated();
2305 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
2306 m_wndLocatorBar
.DocumentUpdated();
2309 void CMainFrame::OnUpdateViewLocatorbar(CCmdUI
*pCmdUI
)
2311 pCmdUI
->SetCheck(m_bLocatorBar
);
2315 void CMainFrame::OnViewLocatorbar()
2317 m_bLocatorBar
= !m_bLocatorBar
;
2318 m_wndLocatorBar
.ShowPane(m_bLocatorBar
, false, true);
2319 m_wndLocatorBar
.DocumentUpdated();
2320 m_wndLineDiffBar
.ShowPane(m_bLineDiff
, false, true);
2321 m_wndLineDiffBar
.DocumentUpdated();
2324 void CMainFrame::OnViewComparewhitespaces()
2326 if (CheckForSave(CHFSR_OPTIONS
)==IDCANCEL
)
2328 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2333 void CMainFrame::OnUpdateViewComparewhitespaces(CCmdUI
*pCmdUI
)
2335 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2336 DWORD dwIgnoreWS
= regIgnoreWS
;
2337 pCmdUI
->SetCheck(dwIgnoreWS
== 0);
2340 void CMainFrame::OnViewIgnorewhitespacechanges()
2342 if (CheckForSave(CHFSR_OPTIONS
)==IDCANCEL
)
2344 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2349 void CMainFrame::OnUpdateViewIgnorewhitespacechanges(CCmdUI
*pCmdUI
)
2351 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2352 DWORD dwIgnoreWS
= regIgnoreWS
;
2353 pCmdUI
->SetCheck(dwIgnoreWS
== 2);
2356 void CMainFrame::OnViewIgnoreallwhitespacechanges()
2358 if (CheckForSave(CHFSR_OPTIONS
)==IDCANCEL
)
2360 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2365 void CMainFrame::OnUpdateViewIgnoreallwhitespacechanges(CCmdUI
*pCmdUI
)
2367 CRegDWORD regIgnoreWS
= CRegDWORD(_T("Software\\TortoiseGitMerge\\IgnoreWS"));
2368 DWORD dwIgnoreWS
= regIgnoreWS
;
2369 pCmdUI
->SetCheck(dwIgnoreWS
== 1);
2372 void CMainFrame::OnViewMovedBlocks()
2374 m_bViewMovedBlocks
= !(DWORD
)m_regViewModedBlocks
;
2375 m_regViewModedBlocks
= m_bViewMovedBlocks
;
2379 void CMainFrame::OnUpdateViewMovedBlocks(CCmdUI
*pCmdUI
)
2381 pCmdUI
->SetCheck(m_bViewMovedBlocks
);
2382 BOOL bEnable
= TRUE
;
2383 if (IsViewGood(m_pwndBottomView
))
2387 pCmdUI
->Enable(bEnable
);
2390 bool CMainFrame::HasConflictsWontKeep()
2392 const int nConflictLine
= CheckResolved();
2393 if (nConflictLine
< 0)
2397 sTemp
.Format(IDS_ERR_MAINFRAME_FILEHASCONFLICTS
, m_pwndBottomView
->m_pViewData
->GetLineNumber(nConflictLine
)+1);
2398 if (MessageBox(sTemp
, 0, MB_ICONERROR
| MB_YESNO
)==IDYES
)
2401 if (m_pwndBottomView
)
2402 m_pwndBottomView
->GoToLine(nConflictLine
);
2406 bool CMainFrame::TryGetFileName(CString
& result
)
2408 return CCommonAppUtils::FileOpenSave(result
, NULL
, IDS_SAVEASTITLE
, IDS_COMMONFILEFILTER
, false, m_hWnd
);
2411 CBaseView
* CMainFrame::GetActiveBaseView() const
2413 CView
* activeView
= GetActiveView();
2414 CBaseView
* activeBase
= dynamic_cast<CBaseView
*>( activeView
);
2418 void CMainFrame::SetWindowTitle()
2420 // try to find a suitable window title
2421 CString sYour
= m_Data
.m_yourFile
.GetDescriptiveName();
2422 if (sYour
.Find(_T(" - "))>=0)
2423 sYour
= sYour
.Left(sYour
.Find(_T(" - ")));
2424 if (sYour
.Find(_T(" : "))>=0)
2425 sYour
= sYour
.Left(sYour
.Find(_T(" : ")));
2426 CString sTheir
= m_Data
.m_theirFile
.GetDescriptiveName();
2427 if (sTheir
.IsEmpty())
2428 sTheir
= m_Data
.m_baseFile
.GetDescriptiveName();
2429 if (sTheir
.Find(_T(" - "))>=0)
2430 sTheir
= sTheir
.Left(sTheir
.Find(_T(" - ")));
2431 if (sTheir
.Find(_T(" : "))>=0)
2432 sTheir
= sTheir
.Left(sTheir
.Find(_T(" : ")));
2434 if (!sYour
.IsEmpty() && !sTheir
.IsEmpty())
2436 if (sYour
.CompareNoCase(sTheir
)==0)
2437 SetWindowText(sYour
+ _T(" - TortoiseGitMerge"));
2438 else if ((sYour
.GetLength() < 10) &&
2439 (sTheir
.GetLength() < 10))
2440 SetWindowText(sYour
+ _T(" - ") + sTheir
+ _T(" - TortoiseGitMerge"));
2443 // we have two very long descriptive texts here, which
2444 // means we have to find a way to use them as a window
2445 // title in a shorter way.
2446 // for simplicity, we just use the one from "yourfile"
2447 SetWindowText(sYour
+ _T(" - TortoiseGitMerge"));
2450 else if (!sYour
.IsEmpty())
2451 SetWindowText(sYour
+ _T(" - TortoiseGitMerge"));
2452 else if (!sTheir
.IsEmpty())
2453 SetWindowText(sTheir
+ _T(" - TortoiseGitMerge"));
2455 SetWindowText(L
"TortoiseGitMerge");