Add support for Git for Windows 2.x and windows-wide system config
[TortoiseGit.git] / src / TortoiseProc / Settings / SetMainPage.cpp
blob832b777d6d56b270f165f0a38fcbc78f85f9118b
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 && 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 environment please read the help file for the keyword \"cygwin 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();