If CTGitPathList::ParserFromLsFile() fails, write the output to temp file for inspection
[TortoiseGit.git] / src / TortoiseMerge / OpenDlg.cpp
blob8dbe5897e520d9512824a33f244e8e9a768d40e4
1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2012 - TortoiseGit
4 // Copyright (C) 2006-2010, 2012 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "TortoiseMerge.h"
22 #include "BrowseFolder.h"
23 #include "opendlg.h"
24 #include "CommonAppUtils.h"
25 #include "registry.h"
27 // COpenDlg dialog
29 IMPLEMENT_DYNAMIC(COpenDlg, CStandAloneDialog)
30 COpenDlg::COpenDlg(CWnd* pParent /*=NULL*/)
31 : CStandAloneDialog(COpenDlg::IDD, pParent)
32 , m_sBaseFile(_T(""))
33 , m_sTheirFile(_T(""))
34 , m_sYourFile(_T(""))
35 , m_sUnifiedDiffFile(_T(""))
36 , m_sPatchDirectory(_T(""))
37 , m_bFromClipboard(FALSE)
38 , m_cFormat(0)
39 , m_nextViewer(NULL)
43 COpenDlg::~COpenDlg()
47 void COpenDlg::DoDataExchange(CDataExchange* pDX)
49 CStandAloneDialog::DoDataExchange(pDX);
50 DDX_Text(pDX, IDC_BASEFILEEDIT, m_sBaseFile);
51 DDX_Text(pDX, IDC_THEIRFILEEDIT, m_sTheirFile);
52 DDX_Text(pDX, IDC_YOURFILEEDIT, m_sYourFile);
53 DDX_Text(pDX, IDC_DIFFFILEEDIT, m_sUnifiedDiffFile);
54 DDX_Text(pDX, IDC_DIRECTORYEDIT, m_sPatchDirectory);
55 DDX_Control(pDX, IDC_BASEFILEEDIT, m_cBaseFileEdit);
56 DDX_Control(pDX, IDC_THEIRFILEEDIT, m_cTheirFileEdit);
57 DDX_Control(pDX, IDC_YOURFILEEDIT, m_cYourFileEdit);
58 DDX_Control(pDX, IDC_DIFFFILEEDIT, m_cDiffFileEdit);
59 DDX_Control(pDX, IDC_DIRECTORYEDIT, m_cDirEdit);
60 DDX_Check(pDX, IDC_PATCHFROMCLIPBOARD, m_bFromClipboard);
63 BEGIN_MESSAGE_MAP(COpenDlg, CStandAloneDialog)
64 ON_BN_CLICKED(IDC_BASEFILEBROWSE, OnBnClickedBasefilebrowse)
65 ON_BN_CLICKED(IDC_THEIRFILEBROWSE, OnBnClickedTheirfilebrowse)
66 ON_BN_CLICKED(IDC_YOURFILEBROWSE, OnBnClickedYourfilebrowse)
67 ON_BN_CLICKED(IDHELP, OnBnClickedHelp)
68 ON_BN_CLICKED(IDC_DIFFFILEBROWSE, OnBnClickedDifffilebrowse)
69 ON_BN_CLICKED(IDC_DIRECTORYBROWSE, OnBnClickedDirectorybrowse)
70 ON_BN_CLICKED(IDC_MERGERADIO, OnBnClickedMergeradio)
71 ON_BN_CLICKED(IDC_APPLYRADIO, OnBnClickedApplyradio)
72 ON_WM_CHANGECBCHAIN()
73 ON_WM_DRAWCLIPBOARD()
74 ON_WM_DESTROY()
75 ON_BN_CLICKED(IDC_PATCHFROMCLIPBOARD, &COpenDlg::OnBnClickedPatchfromclipboard)
76 END_MESSAGE_MAP()
78 BOOL COpenDlg::OnInitDialog()
80 CStandAloneDialog::OnInitDialog();
82 CRegDWORD lastRadioButton(_T("Software\\TortoiseGitMerge\\OpenRadio"), IDC_MERGERADIO);
83 if (((DWORD)lastRadioButton != IDC_MERGERADIO)&&((DWORD)lastRadioButton != IDC_APPLYRADIO))
84 lastRadioButton = IDC_MERGERADIO;
85 GroupRadio((DWORD)lastRadioButton);
86 CheckRadioButton(IDC_MERGERADIO, IDC_APPLYRADIO, (DWORD)lastRadioButton);
88 // turn on auto completion for the edit controls
89 AutoCompleteOn(IDC_BASEFILEEDIT);
90 AutoCompleteOn(IDC_THEIRFILEEDIT);
91 AutoCompleteOn(IDC_YOURFILEEDIT);
92 AutoCompleteOn(IDC_DIFFFILEEDIT);
93 AutoCompleteOn(IDC_DIRECTORYEDIT);
95 m_cFormat = RegisterClipboardFormat(_T("TSVN_UNIFIEDDIFF"));
96 m_nextViewer = SetClipboardViewer();
98 return TRUE; // return TRUE unless you set the focus to a control
99 // EXCEPTION: OCX Property Pages should return FALSE
102 // COpenDlg message handlers
104 void COpenDlg::OnBnClickedBasefilebrowse()
106 OnBrowseForFile(m_sBaseFile);
109 void COpenDlg::OnBnClickedTheirfilebrowse()
111 OnBrowseForFile(m_sTheirFile);
114 void COpenDlg::OnBnClickedYourfilebrowse()
116 OnBrowseForFile(m_sYourFile);
119 void COpenDlg::OnBnClickedHelp()
121 this->OnHelp();
124 void COpenDlg::OnBrowseForFile(CString& filepath, UINT nFileFilter)
126 UpdateData();
127 CCommonAppUtils::FileOpenSave(filepath, NULL, IDS_SELECTFILE, nFileFilter, true, m_hWnd);
128 UpdateData(FALSE);
131 void COpenDlg::OnBnClickedDifffilebrowse()
133 OnBrowseForFile(m_sUnifiedDiffFile, IDS_PATCHFILEFILTER);
136 void COpenDlg::OnBnClickedDirectorybrowse()
138 CBrowseFolder folderBrowser;
139 UpdateData();
140 folderBrowser.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
141 folderBrowser.Show(GetSafeHwnd(), m_sPatchDirectory, m_sPatchDirectory);
142 UpdateData(FALSE);
145 void COpenDlg::OnBnClickedMergeradio()
147 GroupRadio(IDC_MERGERADIO);
150 void COpenDlg::OnBnClickedApplyradio()
152 GroupRadio(IDC_APPLYRADIO);
155 void COpenDlg::GroupRadio(UINT nID)
157 BOOL bMerge = FALSE;
158 BOOL bUnified = FALSE;
159 if (nID == IDC_MERGERADIO)
160 bMerge = TRUE;
161 if (nID == IDC_APPLYRADIO)
162 bUnified = TRUE;
164 GetDlgItem(IDC_BASEFILEEDIT)->EnableWindow(bMerge);
165 GetDlgItem(IDC_BASEFILEBROWSE)->EnableWindow(bMerge);
166 GetDlgItem(IDC_THEIRFILEEDIT)->EnableWindow(bMerge);
167 GetDlgItem(IDC_THEIRFILEBROWSE)->EnableWindow(bMerge);
168 GetDlgItem(IDC_YOURFILEEDIT)->EnableWindow(bMerge);
169 GetDlgItem(IDC_YOURFILEBROWSE)->EnableWindow(bMerge);
171 GetDlgItem(IDC_DIFFFILEEDIT)->EnableWindow(bUnified);
172 GetDlgItem(IDC_DIFFFILEBROWSE)->EnableWindow(bUnified);
173 GetDlgItem(IDC_DIRECTORYEDIT)->EnableWindow(bUnified);
174 GetDlgItem(IDC_DIRECTORYBROWSE)->EnableWindow(bUnified);
176 CheckAndEnableClipboardChecker();
179 void COpenDlg::OnOK()
181 UpdateData(TRUE);
183 bool bUDiffOnClipboard = false;
184 if (OpenClipboard())
186 UINT enumFormat = 0;
189 if (enumFormat == m_cFormat)
191 bUDiffOnClipboard = true;
193 } while((enumFormat = EnumClipboardFormats(enumFormat))!=0);
194 CloseClipboard();
197 if (GetDlgItem(IDC_BASEFILEEDIT)->IsWindowEnabled())
199 m_sUnifiedDiffFile.Empty();
200 m_sPatchDirectory.Empty();
202 else
204 m_sBaseFile.Empty();
205 m_sYourFile.Empty();
206 m_sTheirFile.Empty();
208 UpdateData(FALSE);
209 CString sFile;
210 if (!m_sUnifiedDiffFile.IsEmpty())
211 if (!PathFileExists(m_sUnifiedDiffFile))
212 sFile = m_sUnifiedDiffFile;
213 if (!m_sPatchDirectory.IsEmpty())
214 if (!PathFileExists(m_sPatchDirectory))
215 sFile = m_sPatchDirectory;
216 if (!m_sBaseFile.IsEmpty())
217 if (!PathFileExists(m_sBaseFile))
218 sFile = m_sBaseFile;
219 if (!m_sYourFile.IsEmpty())
220 if (!PathFileExists(m_sYourFile))
221 sFile = m_sYourFile;
222 if (!m_sTheirFile.IsEmpty())
223 if (!PathFileExists(m_sTheirFile))
224 sFile = m_sTheirFile;
226 if (bUDiffOnClipboard && m_bFromClipboard)
228 if (OpenClipboard())
230 HGLOBAL hglb = GetClipboardData(m_cFormat);
231 LPCSTR lpstr = (LPCSTR)GlobalLock(hglb);
233 DWORD len = GetTempPath(0, NULL);
234 std::unique_ptr<TCHAR[]> path(new TCHAR[len+1]);
235 std::unique_ptr<TCHAR[]> tempF(new TCHAR[len+100]);
236 GetTempPath (len+1, path.get());
237 GetTempFileName (path.get(), _T("tsm"), 0, tempF.get());
238 CString sTempFile = CString(tempF.get());
240 FILE * outFile;
241 size_t patchlen = strlen(lpstr);
242 _tfopen_s(&outFile, sTempFile, _T("wb"));
243 if(outFile)
245 size_t size = fwrite(lpstr, sizeof(char), patchlen, outFile);
246 if (size < patchlen)
247 bUDiffOnClipboard = false;
248 else
250 m_sUnifiedDiffFile = sTempFile;
251 UpdateData(FALSE);
252 sFile.Empty();
254 fclose(outFile);
256 GlobalUnlock(hglb);
257 CloseClipboard();
262 if (!sFile.IsEmpty())
264 CString sErr;
265 sErr.Format(IDS_ERR_PATCH_INVALIDPATCHFILE, (LPCTSTR)sFile);
266 MessageBox(sErr, NULL, MB_ICONERROR);
267 return;
269 CRegDWORD lastRadioButton(_T("Software\\TortoiseGitMerge\\OpenRadio"), IDC_MERGERADIO);
270 lastRadioButton = GetCheckedRadioButton(IDC_MERGERADIO, IDC_APPLYRADIO);
271 CStandAloneDialog::OnOK();
274 void COpenDlg::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
276 CStandAloneDialog::OnChangeCbChain(hWndRemove, hWndAfter);
279 bool COpenDlg::CheckAndEnableClipboardChecker()
281 int radio = GetCheckedRadioButton(IDC_MERGERADIO, IDC_APPLYRADIO);
282 bool bUDiffOnClipboard = false;
283 if (radio == IDC_APPLYRADIO)
285 if (OpenClipboard())
287 UINT enumFormat = 0;
290 if (enumFormat == m_cFormat)
292 bUDiffOnClipboard = true;
294 } while((enumFormat = EnumClipboardFormats(enumFormat))!=0);
295 CloseClipboard();
299 DialogEnableWindow(IDC_PATCHFROMCLIPBOARD, bUDiffOnClipboard);
300 return bUDiffOnClipboard;
303 void COpenDlg::OnDrawClipboard()
305 CheckAndEnableClipboardChecker();
306 CStandAloneDialog::OnDrawClipboard();
309 void COpenDlg::OnDestroy()
311 ChangeClipboardChain(m_nextViewer);
312 CStandAloneDialog::OnDestroy();
315 void COpenDlg::OnBnClickedPatchfromclipboard()
317 UpdateData();
318 DialogEnableWindow(IDC_DIFFFILEEDIT, !m_bFromClipboard);
319 DialogEnableWindow(IDC_DIFFFILEBROWSE, !m_bFromClipboard);
322 void COpenDlg::AutoCompleteOn(int controlId)
324 HWND hwnd;
325 GetDlgItem(controlId, &hwnd);
326 if (hwnd)
327 SHAutoComplete(hwnd, SHACF_AUTOSUGGEST_FORCE_ON | SHACF_AUTOAPPEND_FORCE_ON | SHACF_FILESYSTEM);