Fixed issue #2280: Add Msys2 workarounds
[TortoiseGit.git] / src / TortoiseProc / Settings / SetMainPage.cpp
blobc4877e1b37c11f1e9bb8368415fd158d86c53d85
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2015 - TortoiseGit
4 // Copyright (C) 2003-2008 - 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 "TortoiseProc.h"
22 #include "SetMainPage.h"
23 #include "AppUtils.h"
24 #include "PathUtils.h"
25 #include "DirFileEnum.h"
26 #include "GitProgressDlg.h"
27 #include "..\version.h"
28 #include "Git.h"
29 #include "MessageBox.h"
30 #include "GitForWindows.h"
31 #include "BrowseFolder.h"
32 #include "SysInfo.h"
33 #include "Libraries.h"
35 IMPLEMENT_DYNAMIC(CSetMainPage, ISettingsPropPage)
36 CSetMainPage::CSetMainPage()
37 : ISettingsPropPage(CSetMainPage::IDD)
38 , m_sMsysGitPath(_T(""))
39 , m_bCheckNewer(TRUE)
40 , m_dwLanguage(0)
42 m_regLanguage = CRegDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
43 CString temp = CRegString(REG_MSYSGIT_INSTALL, _T(""), FALSE, HKEY_LOCAL_MACHINE);
44 if(!temp.IsEmpty())
45 temp+=_T("bin");
46 m_regMsysGitPath = CRegString(REG_MSYSGIT_PATH,temp,FALSE);
48 m_regMsysGitExtranPath =CRegString(REG_MSYSGIT_EXTRA_PATH);
50 m_sMsysGitPath = m_regMsysGitPath;
51 m_sMsysGitExtranPath = m_regMsysGitExtranPath;
53 m_regCheckNewer = CRegDWORD(_T("Software\\TortoiseGit\\VersionCheck"), TRUE);
56 CSetMainPage::~CSetMainPage()
60 void CSetMainPage::DoDataExchange(CDataExchange* pDX)
62 ISettingsPropPage::DoDataExchange(pDX);
63 DDX_Control(pDX, IDC_LANGUAGECOMBO, m_LanguageCombo);
64 m_dwLanguage = (DWORD)m_LanguageCombo.GetItemData(m_LanguageCombo.GetCurSel());
65 DDX_Text(pDX, IDC_MSYSGIT_PATH, m_sMsysGitPath);
66 DDX_Text(pDX, IDC_MSYSGIT_EXTERN_PATH, m_sMsysGitExtranPath);
67 DDX_Check(pDX, IDC_CHECKNEWERVERSION, m_bCheckNewer);
71 BEGIN_MESSAGE_MAP(CSetMainPage, ISettingsPropPage)
72 ON_CBN_SELCHANGE(IDC_LANGUAGECOMBO, OnModified)
73 // ON_EN_CHANGE(IDC_TEMPEXTENSIONS, OnModified)
74 ON_BN_CLICKED(IDC_CHECKNEWERVERSION, OnModified)
75 ON_BN_CLICKED(IDC_CHECKNEWERBUTTON, OnBnClickedChecknewerbutton)
76 ON_BN_CLICKED(IDC_MSYSGIT_BROWSE,OnBrowseDir)
77 ON_BN_CLICKED(IDC_MSYSGIT_CHECK,OnCheck)
78 ON_EN_CHANGE(IDC_MSYSGIT_PATH, OnMsysGitPathModify)
79 ON_EN_CHANGE(IDC_MSYSGIT_EXTERN_PATH, OnModified)
80 ON_BN_CLICKED(IDC_BUTTON_SHOW_ENV, &CSetMainPage::OnBnClickedButtonShowEnv)
81 ON_BN_CLICKED(IDC_CREATELIB, &CSetMainPage::OnBnClickedCreatelib)
82 END_MESSAGE_MAP()
84 BOOL CSetMainPage::OnInitDialog()
86 ISettingsPropPage::OnInitDialog();
88 EnableToolTips();
89 AdjustControlSize(IDC_CHECKNEWERVERSION);
91 m_dwLanguage = m_regLanguage;
92 m_bCheckNewer = m_regCheckNewer;
94 m_tooltips.AddTool(IDC_MSYSGIT_PATH,IDS_MSYSGIT_PATH_TT);
95 m_tooltips.AddTool(IDC_CHECKNEWERVERSION, IDS_SETTINGS_CHECKNEWER_TT);
96 m_tooltips.AddTool(IDC_CREATELIB, IDS_SETTINGS_CREATELIB_TT);
98 GetDlgItem(IDC_CREATELIB)->EnableWindow(SysInfo::Instance().IsWin7OrLater());
100 SHAutoComplete(GetDlgItem(IDC_MSYSGIT_PATH)->m_hWnd, SHACF_FILESYSTEM);
102 // set up the language selecting combobox
103 TCHAR buf[MAX_PATH] = {0};
104 GetLocaleInfo(1033, LOCALE_SNATIVELANGNAME, buf, _countof(buf));
105 m_LanguageCombo.AddString(buf);
106 m_LanguageCombo.SetItemData(0, 1033);
107 CString path = CPathUtils::GetAppParentDirectory();
108 path = path + _T("Languages\\");
109 CSimpleFileFind finder(path, _T("*.dll"));
110 int langcount = 1;
111 while (finder.FindNextFileNoDirectories())
113 CString file = finder.GetFilePath();
114 CString filename = finder.GetFileName();
115 if (filename.Left(12).CompareNoCase(_T("TortoiseProc"))==0)
117 CString sVer = _T(STRPRODUCTVER);
118 sVer = sVer.Left(sVer.ReverseFind('.'));
119 CString sFileVer = CPathUtils::GetVersionFromFile(file);
120 sFileVer = sFileVer.Left(sFileVer.ReverseFind('.'));
121 if (sFileVer.Compare(sVer)!=0)
122 continue;
123 CString sLoc = filename.Mid(12);
124 sLoc = sLoc.Left(sLoc.GetLength()-4); // cut off ".dll"
125 if ((sLoc.Left(2) == L"32")&&(sLoc.GetLength() > 5))
126 continue;
127 DWORD loc = _tstoi(filename.Mid(12));
128 GetLocaleInfo(loc, LOCALE_SNATIVELANGNAME, buf, _countof(buf));
129 CString sLang = buf;
130 GetLocaleInfo(loc, LOCALE_SNATIVECTRYNAME, buf, _countof(buf));
131 if (buf[0])
133 sLang += _T(" (");
134 sLang += buf;
135 sLang += _T(")");
137 m_LanguageCombo.AddString(sLang);
138 m_LanguageCombo.SetItemData(langcount++, loc);
142 for (int i=0; i<m_LanguageCombo.GetCount(); i++)
144 if (m_LanguageCombo.GetItemData(i) == m_dwLanguage)
145 m_LanguageCombo.SetCurSel(i);
148 UpdateData(FALSE);
149 return TRUE;
152 void CSetMainPage::OnModified()
154 SetModified();
157 static void PerformCommonGitPathCleanup(CString &path)
159 path.Trim(L"\"'");
161 if (path.Find(L"%") >= 0)
163 int neededSize = ExpandEnvironmentStrings(path, nullptr, 0);
164 CString origPath(path);
165 ExpandEnvironmentStrings(origPath, path.GetBufferSetLength(neededSize), neededSize);
166 path.ReleaseBuffer();
169 path.Replace(L"/", L"\\");
170 path.Replace(L"\\\\", L"\\");
172 if (path.GetLength() > 7 && path.Right(7) == _T("git.exe"))
173 path = path.Left(path.GetLength() - 7);
175 path.TrimRight(L"\\");
177 // prefer git.exe in cmd-directory for Git for Windows based on msys2
178 if (path.GetLength() > 12 && (path.Right(12) == _T("\\mingw32\\bin") || path.Right(12) == _T("\\mingw64\\bin")) && PathFileExists(path.Left(path.GetLength() - 12) + _T("\\cmd\\git.exe")))
179 path = path.Left(path.GetLength() - 12) + _T("\\cmd");
181 // prefer git.exe in bin-directory, see https://github.com/msysgit/msysgit/issues/103
182 if (path.GetLength() > 5 && path.Right(4) == _T("\\cmd") && PathFileExists(path.Left(path.GetLength() - 4) + _T("\\bin\\git.exe")))
183 path = path.Left(path.GetLength() - 4) + _T("\\bin");
186 void CSetMainPage::OnMsysGitPathModify()
188 this->UpdateData();
189 CString str=this->m_sMsysGitPath;
190 if(!str.IsEmpty())
192 PerformCommonGitPathCleanup(str);
194 if(str.GetLength()>=3 && str.Find(_T("bin"), str.GetLength()-3) >=0)
196 str=str.Left(str.GetLength()-3);
197 str += _T("mingw\\bin");
198 if(::PathFileExists(str))
200 str+=_T(";");
201 if(this->m_sMsysGitExtranPath.Find(str)<0)
203 m_sMsysGitExtranPath = str + m_sMsysGitExtranPath;
204 this->UpdateData(FALSE);
209 SetModified();
212 BOOL CSetMainPage::OnApply()
214 UpdateData();
216 PerformCommonGitPathCleanup(m_sMsysGitPath);
217 UpdateData(FALSE);
219 Store(m_dwLanguage, m_regLanguage);
220 if (m_sMsysGitPath.Compare(CString(m_regMsysGitPath)) ||
221 this->m_sMsysGitExtranPath.Compare(CString(m_regMsysGitExtranPath)))
223 Store(m_sMsysGitPath, m_regMsysGitPath);
224 Store(m_sMsysGitExtranPath, m_regMsysGitExtranPath);
225 m_restart = Restart_Cache;
227 Store(m_bCheckNewer, m_regCheckNewer);
229 // only complete if the msysgit directory is ok
230 g_Git.m_bInitialized = FALSE;
231 if (g_Git.CheckMsysGitDir(FALSE))
233 SetModified(FALSE);
234 return ISettingsPropPage::OnApply();
236 else
238 if (CMessageBox::Show(NULL, _T("Invalid git.exe path.\nCheck help file for \"Git.exe Path\"."), _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)), CString(MAKEINTRESOURCE(IDS_MSGBOX_HELP))) == 2)
239 OnHelp();
240 return 0;
244 void CSetMainPage::OnBnClickedChecknewerbutton()
246 CAppUtils::RunTortoiseGitProc(_T("/command:updatecheck /visible"), false, false);
249 void CSetMainPage::OnBrowseDir()
251 CBrowseFolder browseFolder;
252 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
253 CString dir;
254 this->UpdateData(TRUE);
255 dir=this->m_sMsysGitPath;
256 if (browseFolder.Show(GetSafeHwnd(), dir) == CBrowseFolder::OK)
258 m_sMsysGitPath=dir;
259 PerformCommonGitPathCleanup(m_sMsysGitPath);
260 this->UpdateData(FALSE);
261 OnMsysGitPathModify();
263 SetModified(TRUE);
266 void CSetMainPage::OnCheck()
268 GetDlgItem(IDC_MSYSGIT_VER)->SetWindowText(L"");
270 this->UpdateData(TRUE);
272 PerformCommonGitPathCleanup(m_sMsysGitPath);
273 UpdateData(FALSE);
275 OnMsysGitPathModify();
277 CString oldpath = m_regMsysGitPath;
278 CString oldextranpath = this->m_regMsysGitExtranPath;
280 Store(m_sMsysGitPath, m_regMsysGitPath);
281 Store(m_sMsysGitExtranPath, m_regMsysGitExtranPath);
283 g_Git.m_bInitialized = false;
285 if (g_Git.CheckMsysGitDir(FALSE))
287 CString cmd;
288 CString out;
289 cmd=_T("git.exe --version");
290 int ret = g_Git.Run(cmd,&out,CP_UTF8);
291 this->GetDlgItem(IDC_MSYSGIT_VER)->SetWindowText(out);
292 if (out.IsEmpty())
294 if (ret == 0xC0000135 && CMessageBox::Show(NULL, _T("Could not start git.exe. A dynamic library (dll) is missing.\nCheck help file for \"Extern DLL Path\"."), _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)), CString(MAKEINTRESOURCE(IDS_MSGBOX_HELP))) == 2)
295 OnHelp();
296 else if (CMessageBox::Show(NULL, _T("Could not get read version information from git.exe.\nCheck help file for \"Git.exe Path\"."),_T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)), CString(MAKEINTRESOURCE(IDS_MSGBOX_HELP))) == 2)
297 OnHelp();
299 else if (!(CGit::ms_bCygwinGit || CGit::ms_bMsys2Git) && out.Find(_T("msysgit")) == -1 && out.Find(_T("windows")) == -1 && CMessageBox::Show(NULL, _T("Could not find \"msysgit\" or \"windows\" in versionstring of git.exe.\nIf you are using git of the cygwin or msys2 environment please read the help file for the keyword \"cygwin git\" or \"msys2 git\"."), _T("TortoiseGit"), 1, IDI_INFORMATION, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)), CString(MAKEINTRESOURCE(IDS_MSGBOX_HELP))) == 2)
300 OnHelp();
302 else
304 if (CMessageBox::Show(NULL, _T("Invalid git.exe path.\nCheck help file for \"Git.exe Path\"."), _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_MSGBOX_OK)), CString(MAKEINTRESOURCE(IDS_MSGBOX_HELP))) == 2)
305 OnHelp();
308 Store(oldpath, m_regMsysGitPath);
309 Store(oldextranpath, m_regMsysGitExtranPath);
312 void CSetMainPage::OnBnClickedButtonShowEnv()
314 CString cmd, err;
315 CString tempfile=::GetTempFile();
317 cmd=_T("cmd /c set");
318 if (g_Git.RunLogFile(cmd, tempfile, &err))
320 CMessageBox::Show(GetSafeHwnd(), _T("Could not get environment variables:\n") + err, _T("TortoiseGit"), MB_OK);
321 return;
323 CAppUtils::LaunchAlternativeEditor(tempfile);
326 void CSetMainPage::OnBnClickedCreatelib()
328 CoInitialize(NULL);
329 EnsureGitLibrary();
330 CoUninitialize();