Apply backgroundcolors.patch
[TortoiseGit.git] / src / TortoiseMerge / OpenDlg.cpp
blob036e41132514056f64e439fd6ffc6f4c87306c9b
1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2012, 2019-2020, 2023 - TortoiseGit
4 // Copyright (C) 2006-2010, 2012-2013 - 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"
26 #include "ClipboardHelper.h"
28 // COpenDlg dialog
30 IMPLEMENT_DYNAMIC(COpenDlg, CStandAloneDialog)
31 COpenDlg::COpenDlg(CWnd* pParent /*=nullptr*/)
32 : CStandAloneDialog(COpenDlg::IDD, pParent)
36 COpenDlg::~COpenDlg()
40 void COpenDlg::DoDataExchange(CDataExchange* pDX)
42 CStandAloneDialog::DoDataExchange(pDX);
43 DDX_Text(pDX, IDC_BASEFILEEDIT, m_sBaseFile);
44 DDX_Text(pDX, IDC_THEIRFILEEDIT, m_sTheirFile);
45 DDX_Text(pDX, IDC_YOURFILEEDIT, m_sYourFile);
46 DDX_Text(pDX, IDC_DIFFFILEEDIT, m_sUnifiedDiffFile);
47 DDX_Text(pDX, IDC_DIRECTORYEDIT, m_sPatchDirectory);
48 DDX_Control(pDX, IDC_BASEFILEEDIT, m_cBaseFileEdit);
49 DDX_Control(pDX, IDC_THEIRFILEEDIT, m_cTheirFileEdit);
50 DDX_Control(pDX, IDC_YOURFILEEDIT, m_cYourFileEdit);
51 DDX_Control(pDX, IDC_DIFFFILEEDIT, m_cDiffFileEdit);
52 DDX_Control(pDX, IDC_DIRECTORYEDIT, m_cDirEdit);
53 DDX_Check(pDX, IDC_PATCHFROMCLIPBOARD, m_bFromClipboard);
56 BEGIN_MESSAGE_MAP(COpenDlg, CStandAloneDialog)
57 ON_BN_CLICKED(IDC_BASEFILEBROWSE, OnBnClickedBasefilebrowse)
58 ON_BN_CLICKED(IDC_THEIRFILEBROWSE, OnBnClickedTheirfilebrowse)
59 ON_BN_CLICKED(IDC_YOURFILEBROWSE, OnBnClickedYourfilebrowse)
60 ON_BN_CLICKED(IDHELP, OnBnClickedHelp)
61 ON_BN_CLICKED(IDC_DIFFFILEBROWSE, OnBnClickedDifffilebrowse)
62 ON_BN_CLICKED(IDC_DIRECTORYBROWSE, OnBnClickedDirectorybrowse)
63 ON_BN_CLICKED(IDC_MERGERADIO, OnBnClickedMergeradio)
64 ON_BN_CLICKED(IDC_APPLYRADIO, OnBnClickedApplyradio)
65 ON_WM_CHANGECBCHAIN()
66 ON_WM_DRAWCLIPBOARD()
67 ON_WM_DESTROY()
68 ON_BN_CLICKED(IDC_PATCHFROMCLIPBOARD, &COpenDlg::OnBnClickedPatchfromclipboard)
69 END_MESSAGE_MAP()
71 BOOL COpenDlg::OnInitDialog()
73 CStandAloneDialog::OnInitDialog();
75 CRegDWORD lastRadioButton(L"Software\\TortoiseGitMerge\\OpenRadio", IDC_MERGERADIO);
76 if (static_cast<DWORD>(lastRadioButton) != IDC_MERGERADIO && static_cast<DWORD>(lastRadioButton) != IDC_APPLYRADIO)
77 lastRadioButton = IDC_MERGERADIO;
78 GroupRadio(static_cast<DWORD>(lastRadioButton));
79 CheckRadioButton(IDC_MERGERADIO, IDC_APPLYRADIO, static_cast<DWORD>(lastRadioButton));
81 // turn on auto completion for the edit controls
82 AutoCompleteOn(IDC_BASEFILEEDIT);
83 AutoCompleteOn(IDC_THEIRFILEEDIT);
84 AutoCompleteOn(IDC_YOURFILEEDIT);
85 AutoCompleteOn(IDC_DIFFFILEEDIT);
86 AutoCompleteOn(IDC_DIRECTORYEDIT);
88 m_cFormat = RegisterClipboardFormat(L"TGIT_UNIFIEDDIFF");
89 m_nextViewer = SetClipboardViewer();
91 return TRUE; // return TRUE unless you set the focus to a control
92 // EXCEPTION: OCX Property Pages should return FALSE
95 // COpenDlg message handlers
97 void COpenDlg::OnBnClickedBasefilebrowse()
99 OnBrowseForFile(m_sBaseFile);
102 void COpenDlg::OnBnClickedTheirfilebrowse()
104 OnBrowseForFile(m_sTheirFile);
107 void COpenDlg::OnBnClickedYourfilebrowse()
109 OnBrowseForFile(m_sYourFile);
112 void COpenDlg::OnBnClickedHelp()
114 this->OnHelp();
117 void COpenDlg::OnBrowseForFile(CString& filepath, UINT nFileFilter)
119 UpdateData();
120 CCommonAppUtils::FileOpenSave(filepath, nullptr, IDS_SELECTFILE, nFileFilter, true, m_hWnd);
121 UpdateData(FALSE);
124 void COpenDlg::OnBnClickedDifffilebrowse()
126 OnBrowseForFile(m_sUnifiedDiffFile, IDS_PATCHFILEFILTER);
129 void COpenDlg::OnBnClickedDirectorybrowse()
131 CBrowseFolder folderBrowser;
132 UpdateData();
133 folderBrowser.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
134 folderBrowser.Show(GetSafeHwnd(), m_sPatchDirectory, m_sPatchDirectory);
135 UpdateData(FALSE);
138 void COpenDlg::OnBnClickedMergeradio()
140 GroupRadio(IDC_MERGERADIO);
143 void COpenDlg::OnBnClickedApplyradio()
145 GroupRadio(IDC_APPLYRADIO);
148 void COpenDlg::GroupRadio(UINT nID)
150 BOOL bMerge = FALSE;
151 BOOL bUnified = FALSE;
152 if (nID == IDC_MERGERADIO)
153 bMerge = TRUE;
154 if (nID == IDC_APPLYRADIO)
155 bUnified = TRUE;
157 GetDlgItem(IDC_BASEFILEEDIT)->EnableWindow(bMerge);
158 GetDlgItem(IDC_BASEFILEBROWSE)->EnableWindow(bMerge);
159 GetDlgItem(IDC_THEIRFILEEDIT)->EnableWindow(bMerge);
160 GetDlgItem(IDC_THEIRFILEBROWSE)->EnableWindow(bMerge);
161 GetDlgItem(IDC_YOURFILEEDIT)->EnableWindow(bMerge);
162 GetDlgItem(IDC_YOURFILEBROWSE)->EnableWindow(bMerge);
164 GetDlgItem(IDC_DIFFFILEEDIT)->EnableWindow(bUnified);
165 GetDlgItem(IDC_DIFFFILEBROWSE)->EnableWindow(bUnified);
166 GetDlgItem(IDC_DIRECTORYEDIT)->EnableWindow(bUnified);
167 GetDlgItem(IDC_DIRECTORYBROWSE)->EnableWindow(bUnified);
169 CheckAndEnableClipboardChecker();
172 void COpenDlg::OnOK()
174 UpdateData(TRUE);
176 bool bUDiffOnClipboard = false;
177 if (CClipboardHelper clipboardHelper; clipboardHelper.Open(nullptr))
179 UINT enumFormat = 0;
182 if (enumFormat == m_cFormat)
184 bUDiffOnClipboard = true;
186 } while((enumFormat = EnumClipboardFormats(enumFormat))!=0);
189 if (GetDlgItem(IDC_BASEFILEEDIT)->IsWindowEnabled())
191 m_sUnifiedDiffFile.Empty();
192 m_sPatchDirectory.Empty();
194 else
196 m_sBaseFile.Empty();
197 m_sYourFile.Empty();
198 m_sTheirFile.Empty();
200 UpdateData(FALSE);
201 CString sFile;
202 if (!m_sUnifiedDiffFile.IsEmpty())
203 if (!PathFileExists(m_sUnifiedDiffFile))
204 sFile = m_sUnifiedDiffFile;
205 if (!m_sPatchDirectory.IsEmpty())
206 if (!PathFileExists(m_sPatchDirectory))
207 sFile = m_sPatchDirectory;
208 if (!m_sBaseFile.IsEmpty())
209 if (!PathFileExists(m_sBaseFile))
210 sFile = m_sBaseFile;
211 if (!m_sYourFile.IsEmpty())
212 if (!PathFileExists(m_sYourFile))
213 sFile = m_sYourFile;
214 if (!m_sTheirFile.IsEmpty())
215 if (!PathFileExists(m_sTheirFile))
216 sFile = m_sTheirFile;
218 if (bUDiffOnClipboard && m_bFromClipboard)
220 CClipboardHelper clipboardHelper;
221 if (clipboardHelper.Open(nullptr))
223 HGLOBAL hglb = GetClipboardData(m_cFormat);
224 auto lpstr = static_cast<LPCSTR>(GlobalLock(hglb));
226 DWORD len = GetTempPath(0, nullptr);
227 auto path = std::make_unique<wchar_t[]>(len + 1);
228 auto tempF = std::make_unique<wchar_t[]>(len + 100);
229 GetTempPath (len+1, path.get());
230 GetTempFileName(path.get(), L"tsm", 0, tempF.get());
231 CString sTempFile = CString(tempF.get());
233 FILE * outFile;
234 size_t patchlen = strlen(lpstr);
235 _wfopen_s(&outFile, sTempFile, L"wb");
236 if(outFile)
238 size_t size = fwrite(lpstr, sizeof(char), patchlen, outFile);
239 if (size < patchlen)
240 bUDiffOnClipboard = false;
241 else
243 m_sUnifiedDiffFile = sTempFile;
244 UpdateData(FALSE);
245 sFile.Empty();
247 fclose(outFile);
249 GlobalUnlock(hglb);
254 if (!sFile.IsEmpty())
256 CString sErr;
257 sErr.Format(IDS_ERR_PATCH_INVALIDPATCHFILE, static_cast<LPCWSTR>(sFile));
258 MessageBox(sErr, nullptr, MB_ICONERROR);
259 return;
261 CRegDWORD lastRadioButton(L"Software\\TortoiseGitMerge\\OpenRadio", IDC_MERGERADIO);
262 lastRadioButton = GetCheckedRadioButton(IDC_MERGERADIO, IDC_APPLYRADIO);
263 CStandAloneDialog::OnOK();
266 void COpenDlg::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
268 CStandAloneDialog::OnChangeCbChain(hWndRemove, hWndAfter);
271 bool COpenDlg::CheckAndEnableClipboardChecker()
273 int radio = GetCheckedRadioButton(IDC_MERGERADIO, IDC_APPLYRADIO);
274 bool bUDiffOnClipboard = false;
275 if (radio == IDC_APPLYRADIO)
277 CClipboardHelper clipboardHelper;
278 if (clipboardHelper.Open(nullptr))
280 UINT enumFormat = 0;
283 if (enumFormat == m_cFormat)
285 bUDiffOnClipboard = true;
287 } while((enumFormat = EnumClipboardFormats(enumFormat))!=0);
291 DialogEnableWindow(IDC_PATCHFROMCLIPBOARD, bUDiffOnClipboard);
292 return bUDiffOnClipboard;
295 void COpenDlg::OnDrawClipboard()
297 CheckAndEnableClipboardChecker();
298 CStandAloneDialog::OnDrawClipboard();
301 void COpenDlg::OnDestroy()
303 ChangeClipboardChain(m_nextViewer);
304 CStandAloneDialog::OnDestroy();
307 void COpenDlg::OnBnClickedPatchfromclipboard()
309 UpdateData();
310 DialogEnableWindow(IDC_DIFFFILEEDIT, !m_bFromClipboard);
311 DialogEnableWindow(IDC_DIFFFILEBROWSE, !m_bFromClipboard);
314 void COpenDlg::AutoCompleteOn(int controlId)
316 HWND hwnd;
317 GetDlgItem(controlId, &hwnd);
318 if (hwnd)
319 SHAutoComplete(hwnd, SHACF_AUTOSUGGEST_FORCE_ON | SHACF_AUTOAPPEND_FORCE_ON | SHACF_FILESYSTEM);