Uncheck autoload putty key for git://, http://, and https:// clone URLs
[TortoiseGit.git] / src / TortoiseProc / CloneDlg.cpp
blobcb1b9e6f1f0a23a1df28c37fc1419dcf1fc11f15
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2015 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // CloneDlg.cpp : implementation file
22 #include "stdafx.h"
23 #include "TortoiseProc.h"
24 #include "CloneDlg.h"
25 #include "BrowseFolder.h"
26 #include "MessageBox.h"
27 #include "AppUtils.h"
28 // CCloneDlg dialog
30 IMPLEMENT_DYNCREATE(CCloneDlg, CHorizontalResizableStandAloneDialog)
32 CCloneDlg::CCloneDlg(CWnd* pParent /*=NULL*/)
33 : CHorizontalResizableStandAloneDialog(CCloneDlg::IDD, pParent)
34 , m_Directory(_T(""))
36 m_bRecursive = FALSE;
37 m_bBare = FALSE;
38 m_bBranch = FALSE;
39 m_bOrigin = FALSE;
40 m_bNoCheckout = FALSE;
41 m_bSVN = FALSE;
42 m_bSVNTrunk = FALSE;
43 m_bSVNTags = FALSE;
44 m_bSVNBranch = FALSE;
45 m_bSVNFrom = FALSE;
46 m_bSVNUserName = FALSE;
47 m_bExactPath = FALSE;
49 m_strSVNTrunk = _T("trunk");
50 m_strSVNTags = _T("tags");
51 m_strSVNBranchs = _T("branches");
53 m_regBrowseUrl = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\CloneBrowse"),0);
54 m_regCloneDir = CRegString(_T("Software\\TortoiseGit\\TortoiseProc\\CloneDir"));
55 m_regUseSSHKey = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\CloneUseSSHKey"), TRUE);
56 m_nSVNFrom = 0;
58 m_bAutoloadPuttyKeyFile = m_regUseSSHKey && CAppUtils::IsSSHPutty();
60 m_nDepth = 1;
61 m_bDepth = false;
62 m_bSaving = false;
65 CCloneDlg::~CCloneDlg()
69 void CCloneDlg::DoDataExchange(CDataExchange* pDX)
71 CHorizontalResizableStandAloneDialog::DoDataExchange(pDX);
72 DDX_Control(pDX, IDC_URLCOMBO, m_URLCombo);
73 DDX_Control(pDX, IDC_PUTTYKEYFILE, m_PuttyKeyCombo);
74 DDX_Control(pDX, IDC_CLONE_BROWSE_URL, m_BrowseUrl);
75 DDX_Text(pDX, IDC_CLONE_DIR, m_Directory);
76 DDX_Check(pDX,IDC_PUTTYKEY_AUTOLOAD, m_bAutoloadPuttyKeyFile);
78 DDX_Check(pDX,IDC_CHECK_SVN, m_bSVN);
79 DDX_Check(pDX,IDC_CHECK_SVN_TRUNK, m_bSVNTrunk);
80 DDX_Check(pDX,IDC_CHECK_SVN_TAG, m_bSVNTags);
81 DDX_Check(pDX,IDC_CHECK_SVN_BRANCH, m_bSVNBranch);
82 DDX_Check(pDX,IDC_CHECK_SVN_FROM, m_bSVNFrom);
83 DDX_Check(pDX,IDC_CHECK_USERNAME, m_bSVNUserName);
85 DDX_Text(pDX, IDC_EDIT_SVN_TRUNK, m_strSVNTrunk);
86 DDX_Text(pDX, IDC_EDIT_SVN_TAG, m_strSVNTags);
87 DDX_Text(pDX, IDC_EDIT_SVN_BRANCH, m_strSVNBranchs);
88 DDX_Text(pDX, IDC_EDIT_SVN_FROM, this->m_nSVNFrom);
89 DDX_Text(pDX, IDC_EDIT_USERNAME,m_strUserName);
91 DDX_Check(pDX, IDC_CHECK_DEPTH, m_bDepth);
92 DDX_Check(pDX, IDC_CHECK_BARE, m_bBare);
93 DDX_Check(pDX, IDC_CHECK_RECURSIVE, m_bRecursive);
94 DDX_Text(pDX, IDC_EDIT_DEPTH,m_nDepth);
95 DDX_Check(pDX,IDC_CHECK_BRANCH, m_bBranch);
96 DDX_Text(pDX, IDC_EDIT_BRANCH, m_strBranch);
97 DDX_Check(pDX, IDC_CHECK_ORIGIN, m_bOrigin);
98 DDX_Text(pDX, IDC_EDIT_ORIGIN, m_strOrigin);
99 DDX_Check(pDX,IDC_CHECK_NOCHECKOUT, m_bNoCheckout);
102 BOOL CCloneDlg::OnInitDialog()
104 CHorizontalResizableStandAloneDialog::OnInitDialog();
105 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
107 AddAnchor(IDC_URLCOMBO, TOP_LEFT, TOP_RIGHT);
108 AddAnchor(IDC_CLONE_BROWSE_URL, TOP_RIGHT);
109 AddAnchor(IDC_CLONE_DIR, TOP_LEFT,TOP_RIGHT);
110 AddAnchor(IDC_CLONE_DIR_BROWSE, TOP_RIGHT);
111 AddAnchor(IDOK,BOTTOM_RIGHT);
112 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
114 AddAnchor(IDC_GROUP_CLONE,TOP_LEFT,TOP_RIGHT);
115 AddAnchor(IDC_PUTTYKEYFILE_BROWSE,TOP_RIGHT);
116 AddAnchor(IDC_PUTTYKEY_AUTOLOAD,TOP_LEFT);
117 AddAnchor(IDC_PUTTYKEYFILE,TOP_LEFT,TOP_RIGHT);
118 AddAnchor(IDC_CLONE_GROUP_SVN,TOP_LEFT,TOP_RIGHT);
119 AddAnchor(IDHELP, BOTTOM_RIGHT);
121 AdjustControlSize(IDC_CHECK_DEPTH);
122 AdjustControlSize(IDC_CHECK_RECURSIVE);
123 AdjustControlSize(IDC_CHECK_BARE);
124 AdjustControlSize(IDC_PUTTYKEY_AUTOLOAD);
125 AdjustControlSize(IDC_CHECK_SVN);
126 AdjustControlSize(IDC_CHECK_SVN_TRUNK);
127 AdjustControlSize(IDC_CHECK_SVN_TAG);
128 AdjustControlSize(IDC_CHECK_SVN_BRANCH);
129 AdjustControlSize(IDC_CHECK_SVN_FROM);
130 AdjustControlSize(IDC_CHECK_USERNAME);
132 m_tooltips.Create(this);
133 CString tt;
134 tt.LoadString(IDS_CLONE_DEPTH_TT);
135 m_tooltips.AddTool(IDC_EDIT_DEPTH,tt);
136 m_tooltips.AddTool(IDC_CHECK_DEPTH,tt);
138 this->AddOthersToAnchor();
140 if (m_Directory.IsEmpty())
142 CString dir = m_regCloneDir;
143 int index = dir.ReverseFind('\\');
144 if (index >= 0)
145 dir = dir.Left(index);
146 m_Directory = dir;
148 if (m_Directory.IsEmpty())
150 TCHAR szPath[MAX_PATH] = {0};
151 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, szPath)))
152 m_Directory = szPath;
154 UpdateData(FALSE);
156 m_URLCombo.SetCaseSensitive(TRUE);
157 m_URLCombo.SetURLHistory(TRUE);
158 m_URLCombo.LoadHistory(_T("Software\\TortoiseGit\\History\\repoURLS"), _T("url"));
159 if(m_URL.IsEmpty())
161 CString str = CAppUtils::GetClipboardLink(_T("git clone "));
162 str.Trim();
163 if(str.IsEmpty())
164 m_URLCombo.SetCurSel(0);
165 else
166 m_URLCombo.SetWindowText(str);
168 else
169 m_URLCombo.SetWindowText(m_URL);
171 CWnd *window=this->GetDlgItem(IDC_CLONE_DIR);
172 if(window)
173 SHAutoComplete(window->m_hWnd, SHACF_FILESYSTEM);
175 this->m_BrowseUrl.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_DIR)));
176 this->m_BrowseUrl.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_WEB)));
177 m_BrowseUrl.SetCurrentEntry(m_regBrowseUrl);
179 m_PuttyKeyCombo.SetPathHistory(TRUE);
180 m_PuttyKeyCombo.LoadHistory(_T("Software\\TortoiseGit\\History\\puttykey"), _T("key"));
181 m_PuttyKeyCombo.SetCurSel(0);
183 this->GetDlgItem(IDC_PUTTYKEY_AUTOLOAD)->EnableWindow( CAppUtils::IsSSHPutty() );
184 this->GetDlgItem(IDC_PUTTYKEYFILE)->EnableWindow(m_bAutoloadPuttyKeyFile);
185 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE)->EnableWindow(m_bAutoloadPuttyKeyFile);
187 EnableSaveRestore(_T("CloneDlg"));
189 OnBnClickedCheckSvn();
190 OnBnClickedCheckDepth();
191 OnBnClickedCheckBranch();
192 OnBnClickedCheckOrigin();
193 return TRUE; // return TRUE unless you set the focus to a control
196 BEGIN_MESSAGE_MAP(CCloneDlg, CHorizontalResizableStandAloneDialog)
197 ON_BN_CLICKED(IDC_CLONE_BROWSE_URL, &CCloneDlg::OnBnClickedCloneBrowseUrl)
198 ON_BN_CLICKED(IDC_CLONE_DIR_BROWSE, &CCloneDlg::OnBnClickedCloneDirBrowse)
199 ON_BN_CLICKED(IDC_CHECK_BRANCH, &CCloneDlg::OnBnClickedCheckBranch)
200 ON_BN_CLICKED(IDC_CHECK_ORIGIN, &CCloneDlg::OnBnClickedCheckOrigin)
201 ON_BN_CLICKED(IDC_PUTTYKEYFILE_BROWSE, &CCloneDlg::OnBnClickedPuttykeyfileBrowse)
202 ON_BN_CLICKED(IDC_PUTTYKEY_AUTOLOAD, &CCloneDlg::OnBnClickedPuttykeyAutoload)
203 ON_CBN_EDITCHANGE(IDC_URLCOMBO, &CCloneDlg::OnCbnEditchangeUrlcombo)
204 ON_BN_CLICKED(IDC_CHECK_SVN, &CCloneDlg::OnBnClickedCheckSvn)
205 ON_BN_CLICKED(IDC_CHECK_SVN_TRUNK, &CCloneDlg::OnBnClickedCheckSvnTrunk)
206 ON_BN_CLICKED(IDC_CHECK_SVN_TAG, &CCloneDlg::OnBnClickedCheckSvnTag)
207 ON_BN_CLICKED(IDC_CHECK_SVN_BRANCH, &CCloneDlg::OnBnClickedCheckSvnBranch)
208 ON_BN_CLICKED(IDC_CHECK_SVN_FROM, &CCloneDlg::OnBnClickedCheckSvnFrom)
209 ON_BN_CLICKED(IDC_CHECK_DEPTH, &CCloneDlg::OnBnClickedCheckDepth)
210 ON_BN_CLICKED(IDC_CHECK_BARE, &CCloneDlg::OnBnClickedCheckBare)
211 ON_BN_CLICKED(IDC_CHECK_RECURSIVE, &CCloneDlg::OnBnClickedCheckRecursive)
212 ON_BN_CLICKED(IDC_CHECK_NOCHECKOUT, &CCloneDlg::OnBnClickedCheckRecursive)
213 ON_BN_CLICKED(IDC_CHECK_USERNAME, &CCloneDlg::OnBnClickedCheckUsername)
214 END_MESSAGE_MAP()
216 // CCloneDlg message handlers
218 void CCloneDlg::OnOK()
220 m_bSaving = true;
221 this->m_URLCombo.GetWindowTextW(m_URL);
222 m_URL.Trim();
223 UpdateData(TRUE);
224 if(m_URL.IsEmpty() || m_Directory.IsEmpty())
226 CMessageBox::Show(NULL, IDS_PROC_CLONE_URLDIREMPTY, IDS_APPNAME, MB_OK);
227 m_bSaving = false;
228 return;
231 if (m_bBranch && !g_Git.IsBranchNameValid(m_strBranch))
233 ShowEditBalloon(IDC_EDIT_BRANCH, IDS_B_T_NOTEMPTY, IDS_ERR_ERROR, TTI_ERROR);
234 m_bSaving = false;
235 return;
238 if (m_bOrigin && m_strOrigin.GetLength() == 0 && !m_bSVN)
240 ShowEditBalloon(IDC_EDIT_ORIGIN, IDS_B_T_NOTEMPTY, IDS_ERR_ERROR, TTI_ERROR);
241 m_bSaving = false;
242 return;
245 m_URLCombo.SaveHistory();
246 m_PuttyKeyCombo.SaveHistory();
247 m_regCloneDir = m_Directory;
248 m_regUseSSHKey = m_bAutoloadPuttyKeyFile;
250 this->m_PuttyKeyCombo.GetWindowText(m_strPuttyKeyFile);
251 CResizableDialog::OnOK();
252 m_bSaving = false;
256 void CCloneDlg::OnCancel()
258 CResizableDialog::OnCancel();
261 void CCloneDlg::OnBnClickedCloneBrowseUrl()
263 CBrowseFolder browseFolder;
264 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
265 CString strCloneDirectory;
267 int sel = (int)this->m_BrowseUrl.GetCurrentEntry();
268 this->m_regBrowseUrl = sel;
270 if( sel == 1 )
272 CString str;
273 m_URLCombo.GetWindowText(str);
274 ShellExecute(NULL, _T("open"), str.Trim(), NULL,NULL, SW_SHOW);
275 return ;
278 this->m_URLCombo.GetWindowTextW(strCloneDirectory);
279 if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK)
281 this->m_URLCombo.SetWindowTextW(strCloneDirectory);
285 void CCloneDlg::OnBnClickedCloneDirBrowse()
287 CBrowseFolder browseFolder;
288 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
289 CString strCloneDirectory = this->m_Directory;
290 if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK)
292 UpdateData(TRUE);
293 m_Directory = strCloneDirectory;
294 UpdateData(FALSE);
298 void CCloneDlg::OnBnClickedPuttykeyfileBrowse()
300 CFileDialog dlg(TRUE,NULL,
301 NULL,
302 OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
303 CString(MAKEINTRESOURCE(IDS_PUTTYKEYFILEFILTER)));
305 this->UpdateData();
306 if(dlg.DoModal()==IDOK)
308 this->m_PuttyKeyCombo.SetWindowText( dlg.GetPathName() );
313 void CCloneDlg::OnBnClickedPuttykeyAutoload()
315 this->UpdateData();
316 this->GetDlgItem(IDC_PUTTYKEYFILE)->EnableWindow(m_bAutoloadPuttyKeyFile);
317 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE)->EnableWindow(m_bAutoloadPuttyKeyFile);
320 void CCloneDlg::OnCbnEditchangeUrlcombo()
322 // do not update member variables from UI while saving
323 if (m_bSaving || m_bExactPath)
324 return;
326 this->UpdateData();
327 CString url;
328 m_URLCombo.GetWindowText(url);
329 url.Trim();
331 if(m_OldURL == url )
332 return;
334 m_OldURL=url;
336 //if(url.IsEmpty())
337 // return;
339 CString old;
340 old=m_ModuleName;
342 url.Replace(_T('\\'),_T('/'));
344 // add compatibility for Google Code git urls
345 url.TrimRight(L"/");
347 int start=url.ReverseFind(_T('/'));
348 if(start<0)
350 start = url.ReverseFind(_T(':'));
351 if(start <0)
352 start = url.ReverseFind(_T('@'));
354 if(start<0)
355 start = 0;
357 CString temp;
358 temp=url.Mid(start+1);
360 temp=temp.MakeLower();
362 // we've to check whether the URL ends with .git (instead of using the first .git)
363 int end = temp.Right(4) == _T(".git") ? (temp.GetLength() - 4) : temp.GetLength();
365 //CString modulename;
366 m_ModuleName=url.Mid(start+1,end);
368 start = m_Directory.ReverseFind(_T('\\'));
369 if(start <0 )
370 start = m_Directory.ReverseFind(_T('/'));
371 if(start <0 )
372 start =0;
374 int dirstart=m_Directory.Find(old,start);
375 if(dirstart>=0 && (dirstart+old.GetLength() == m_Directory.GetLength()) )
376 m_Directory=m_Directory.Left(dirstart);
378 m_Directory.TrimRight(L"\\/");
379 m_Directory += _T('\\');
380 m_Directory += m_ModuleName;
382 // check if URL starts with http://, https:// or git:// in those cases loading putty keys is only
383 // asking for passwords for keys that are never used
384 if (url.Find(L"http://", 0) >= 0 || url.Find(L"https://", 0) >= 0 || url.Find(L"git://", 0) >= 0)
385 m_bAutoloadPuttyKeyFile = false;
386 else
387 m_bAutoloadPuttyKeyFile = m_regUseSSHKey && CAppUtils::IsSSHPutty();
390 this->UpdateData(FALSE);
393 void CCloneDlg::OnBnClickedCheckSvn()
395 this->UpdateData();
397 if(this->m_bSVN)
399 CString str;
400 m_URLCombo.GetWindowText(str);
402 str.TrimRight(L"\\/");
403 if(str.GetLength()>=5 && (str.Right(5).MakeLower() == _T("trunk") ))
405 this->m_bSVNBranch=this->m_bSVNTags=this->m_bSVNTrunk = FALSE;
407 else
409 this->m_bSVNBranch=this->m_bSVNTags=this->m_bSVNTrunk = TRUE;
411 m_bDepth = false;
412 m_bBare = false;
413 m_bRecursive = false;
414 m_bBranch = FALSE;
415 this->UpdateData(FALSE);
416 OnBnClickedCheckDepth();
418 this->GetDlgItem(IDC_CHECK_DEPTH)->EnableWindow(!m_bSVN);
419 this->GetDlgItem(IDC_CHECK_BARE)->EnableWindow(!m_bSVN);
420 this->GetDlgItem(IDC_CHECK_RECURSIVE)->EnableWindow(!m_bSVN);
421 this->GetDlgItem(IDC_CHECK_BRANCH)->EnableWindow(!m_bSVN);
422 this->GetDlgItem(IDC_EDIT_BRANCH)->EnableWindow(!m_bSVN);
423 OnBnClickedCheckSvnTrunk();
424 OnBnClickedCheckSvnTag();
425 OnBnClickedCheckSvnBranch();
426 OnBnClickedCheckSvnFrom();
427 OnBnClickedCheckUsername();
430 void CCloneDlg::OnBnClickedCheckSvnTrunk()
432 UpdateData(TRUE);
433 this->GetDlgItem(IDC_CHECK_SVN_TRUNK)->EnableWindow(this->m_bSVN);
434 this->GetDlgItem(IDC_EDIT_SVN_TRUNK)->EnableWindow(this->m_bSVNTrunk&&this->m_bSVN);
437 void CCloneDlg::OnBnClickedCheckSvnTag()
439 UpdateData(TRUE);
440 this->GetDlgItem(IDC_CHECK_SVN_TAG)->EnableWindow(this->m_bSVN);
441 this->GetDlgItem(IDC_EDIT_SVN_TAG)->EnableWindow(this->m_bSVNTags&&this->m_bSVN);
444 void CCloneDlg::OnBnClickedCheckSvnBranch()
446 UpdateData(TRUE);
447 this->GetDlgItem(IDC_CHECK_SVN_BRANCH)->EnableWindow(this->m_bSVN);
448 this->GetDlgItem(IDC_EDIT_SVN_BRANCH)->EnableWindow(this->m_bSVNBranch&&this->m_bSVN);
451 void CCloneDlg::OnBnClickedCheckSvnFrom()
453 UpdateData(TRUE);
454 this->GetDlgItem(IDC_CHECK_SVN_FROM)->EnableWindow(this->m_bSVN);
455 this->GetDlgItem(IDC_EDIT_SVN_FROM)->EnableWindow(this->m_bSVNFrom&&this->m_bSVN);
458 void CCloneDlg::OnBnClickedCheckRecursive()
460 UpdateData(TRUE);
461 if (m_bRecursive || m_bNoCheckout)
463 m_bBare = FALSE;
464 GetDlgItem(IDC_CHECK_BARE)->EnableWindow(FALSE);
465 UpdateData(FALSE);
467 else
468 GetDlgItem(IDC_CHECK_BARE)->EnableWindow(TRUE);
471 void CCloneDlg::OnBnClickedCheckBare()
473 UpdateData(TRUE);
474 if (m_bBare)
476 m_bRecursive = FALSE;
477 m_bNoCheckout = FALSE;
478 GetDlgItem(IDC_CHECK_RECURSIVE)->EnableWindow(FALSE);
479 GetDlgItem(IDC_CHECK_NOCHECKOUT)->EnableWindow(FALSE);
480 UpdateData(FALSE);
482 else
484 GetDlgItem(IDC_CHECK_RECURSIVE)->EnableWindow(TRUE);
485 GetDlgItem(IDC_CHECK_NOCHECKOUT)->EnableWindow(TRUE);
488 void CCloneDlg::OnBnClickedCheckDepth()
490 UpdateData(TRUE);
491 this->GetDlgItem(IDC_EDIT_DEPTH)->EnableWindow(this->m_bDepth);
494 void CCloneDlg::OnBnClickedCheckBranch()
496 UpdateData(TRUE);
497 this->GetDlgItem(IDC_EDIT_BRANCH)->EnableWindow(this->m_bBranch);
500 void CCloneDlg::OnBnClickedCheckOrigin()
502 UpdateData(TRUE);
503 this->GetDlgItem(IDC_EDIT_ORIGIN)->EnableWindow(this->m_bOrigin);
506 BOOL CCloneDlg::PreTranslateMessage(MSG* pMsg)
508 m_tooltips.RelayEvent(pMsg);
510 return CHorizontalResizableStandAloneDialog::PreTranslateMessage(pMsg);
513 void CCloneDlg::OnBnClickedCheckUsername()
515 UpdateData(TRUE);
516 this->GetDlgItem(IDC_CHECK_USERNAME)->EnableWindow(this->m_bSVN);
517 this->GetDlgItem(IDC_EDIT_USERNAME)->EnableWindow(this->m_bSVNUserName && this->m_bSVN);