Add support for "project" config level
[TortoiseGit.git] / src / TortoiseProc / CloneDlg.cpp
blob451c404a702fb47859a792f51ccd280339410af9
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013 - 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_bAutoloadPuttyKeyFile = CAppUtils::IsSSHPutty();
38 m_bRecursive = FALSE;
39 m_bBare = FALSE;
40 m_bBranch = FALSE;
41 m_bOrigin = FALSE;
42 m_bNoCheckout = FALSE;
43 m_bSVN = FALSE;
44 m_bSVNTrunk = FALSE;
45 m_bSVNTags = FALSE;
46 m_bSVNBranch = FALSE;
47 m_bSVNFrom = FALSE;
48 m_bSVNUserName = FALSE;
49 m_bExactPath = FALSE;
51 m_strSVNTrunk = _T("trunk");
52 m_strSVNTags = _T("tags");
53 m_strSVNBranchs = _T("branches");
55 m_regBrowseUrl = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\CloneBrowse"),0);
56 m_nSVNFrom = 0;
58 m_nDepth = 0;
59 m_bDepth = false;
60 m_bSaving = false;
63 CCloneDlg::~CCloneDlg()
67 void CCloneDlg::DoDataExchange(CDataExchange* pDX)
69 CHorizontalResizableStandAloneDialog::DoDataExchange(pDX);
70 DDX_Control(pDX, IDC_URLCOMBO, m_URLCombo);
71 DDX_Control(pDX, IDC_PUTTYKEYFILE, m_PuttyKeyCombo);
72 DDX_Control(pDX, IDC_CLONE_BROWSE_URL, m_BrowseUrl);
73 DDX_Text(pDX, IDC_CLONE_DIR, m_Directory);
74 DDX_Check(pDX,IDC_PUTTYKEY_AUTOLOAD, m_bAutoloadPuttyKeyFile);
76 DDX_Check(pDX,IDC_CHECK_SVN, m_bSVN);
77 DDX_Check(pDX,IDC_CHECK_SVN_TRUNK, m_bSVNTrunk);
78 DDX_Check(pDX,IDC_CHECK_SVN_TAG, m_bSVNTags);
79 DDX_Check(pDX,IDC_CHECK_SVN_BRANCH, m_bSVNBranch);
80 DDX_Check(pDX,IDC_CHECK_SVN_FROM, m_bSVNFrom);
81 DDX_Check(pDX,IDC_CHECK_USERNAME, m_bSVNUserName);
83 DDX_Text(pDX, IDC_EDIT_SVN_TRUNK, m_strSVNTrunk);
84 DDX_Text(pDX, IDC_EDIT_SVN_TAG, m_strSVNTags);
85 DDX_Text(pDX, IDC_EDIT_SVN_BRANCH, m_strSVNBranchs);
86 DDX_Text(pDX, IDC_EDIT_SVN_FROM, this->m_nSVNFrom);
87 DDX_Text(pDX, IDC_EDIT_USERNAME,m_strUserName);
89 DDX_Check(pDX, IDC_CHECK_DEPTH, m_bDepth);
90 DDX_Check(pDX, IDC_CHECK_BARE, m_bBare);
91 DDX_Check(pDX, IDC_CHECK_RECURSIVE, m_bRecursive);
92 DDX_Text(pDX, IDC_EDIT_DEPTH,m_nDepth);
93 DDX_Check(pDX,IDC_CHECK_BRANCH, m_bBranch);
94 DDX_Text(pDX, IDC_EDIT_BRANCH, m_strBranch);
95 DDX_Check(pDX, IDC_CHECK_ORIGIN, m_bOrigin);
96 DDX_Text(pDX, IDC_EDIT_ORIGIN, m_strOrigin);
97 DDX_Check(pDX,IDC_CHECK_NOCHECKOUT, m_bNoCheckout);
100 BOOL CCloneDlg::OnInitDialog()
102 CHorizontalResizableStandAloneDialog::OnInitDialog();
103 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
105 AddAnchor(IDC_URLCOMBO, TOP_LEFT, TOP_RIGHT);
106 AddAnchor(IDC_CLONE_BROWSE_URL, TOP_RIGHT);
107 AddAnchor(IDC_CLONE_DIR, TOP_LEFT,TOP_RIGHT);
108 AddAnchor(IDC_CLONE_DIR_BROWSE, TOP_RIGHT);
109 AddAnchor(IDOK,BOTTOM_RIGHT);
110 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
112 AddAnchor(IDC_GROUP_CLONE,TOP_LEFT,TOP_RIGHT);
113 AddAnchor(IDC_PUTTYKEYFILE_BROWSE,TOP_RIGHT);
114 AddAnchor(IDC_PUTTYKEY_AUTOLOAD,TOP_LEFT);
115 AddAnchor(IDC_PUTTYKEYFILE,TOP_LEFT,TOP_RIGHT);
116 AddAnchor(IDC_CLONE_GROUP_SVN,TOP_LEFT,TOP_RIGHT);
117 AddAnchor(IDHELP, BOTTOM_RIGHT);
119 AdjustControlSize(IDC_CHECK_DEPTH);
120 AdjustControlSize(IDC_CHECK_RECURSIVE);
121 AdjustControlSize(IDC_CHECK_BARE);
122 AdjustControlSize(IDC_PUTTYKEY_AUTOLOAD);
123 AdjustControlSize(IDC_CHECK_SVN);
124 AdjustControlSize(IDC_CHECK_SVN_TRUNK);
125 AdjustControlSize(IDC_CHECK_SVN_TAG);
126 AdjustControlSize(IDC_CHECK_SVN_BRANCH);
127 AdjustControlSize(IDC_CHECK_SVN_FROM);
128 AdjustControlSize(IDC_CHECK_USERNAME);
130 m_tooltips.Create(this);
131 CString tt;
132 tt.LoadString(IDS_CLONE_DEPTH_TT);
133 m_tooltips.AddTool(IDC_EDIT_DEPTH,tt);
134 m_tooltips.AddTool(IDC_CHECK_DEPTH,tt);
136 this->AddOthersToAnchor();
138 m_URLCombo.SetURLHistory(TRUE);
139 m_URLCombo.LoadHistory(_T("Software\\TortoiseGit\\History\\repoURLS"), _T("url"));
140 if(m_URL.IsEmpty())
142 CString str = CAppUtils::GetClipboardLink(_T("git clone "));
143 str.Trim();
144 if(str.IsEmpty())
145 m_URLCombo.SetCurSel(0);
146 else
147 m_URLCombo.SetWindowText(str);
149 else
150 m_URLCombo.SetWindowText(m_URL);
152 CWnd *window=this->GetDlgItem(IDC_CLONE_DIR);
153 if(window)
154 SHAutoComplete(window->m_hWnd, SHACF_FILESYSTEM);
156 this->m_BrowseUrl.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_DIR)));
157 this->m_BrowseUrl.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_WEB)));
158 m_BrowseUrl.SetCurrentEntry(m_regBrowseUrl);
160 m_PuttyKeyCombo.SetPathHistory(TRUE);
161 m_PuttyKeyCombo.LoadHistory(_T("Software\\TortoiseGit\\History\\puttykey"), _T("key"));
162 m_PuttyKeyCombo.SetCurSel(0);
164 this->GetDlgItem(IDC_PUTTYKEY_AUTOLOAD)->EnableWindow( CAppUtils::IsSSHPutty() );
165 this->GetDlgItem(IDC_PUTTYKEYFILE)->EnableWindow(m_bAutoloadPuttyKeyFile);
166 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE)->EnableWindow(m_bAutoloadPuttyKeyFile);
168 EnableSaveRestore(_T("CloneDlg"));
170 OnBnClickedCheckSvn();
171 OnBnClickedCheckDepth();
172 OnBnClickedCheckBranch();
173 OnBnClickedCheckOrigin();
174 return TRUE; // return TRUE unless you set the focus to a control
177 BEGIN_MESSAGE_MAP(CCloneDlg, CHorizontalResizableStandAloneDialog)
178 ON_BN_CLICKED(IDC_CLONE_BROWSE_URL, &CCloneDlg::OnBnClickedCloneBrowseUrl)
179 ON_BN_CLICKED(IDC_CLONE_DIR_BROWSE, &CCloneDlg::OnBnClickedCloneDirBrowse)
180 ON_BN_CLICKED(IDC_CHECK_BRANCH, &CCloneDlg::OnBnClickedCheckBranch)
181 ON_BN_CLICKED(IDC_CHECK_ORIGIN, &CCloneDlg::OnBnClickedCheckOrigin)
182 ON_BN_CLICKED(IDC_PUTTYKEYFILE_BROWSE, &CCloneDlg::OnBnClickedPuttykeyfileBrowse)
183 ON_BN_CLICKED(IDC_PUTTYKEY_AUTOLOAD, &CCloneDlg::OnBnClickedPuttykeyAutoload)
184 ON_CBN_EDITCHANGE(IDC_URLCOMBO, &CCloneDlg::OnCbnEditchangeUrlcombo)
185 ON_BN_CLICKED(IDC_CHECK_SVN, &CCloneDlg::OnBnClickedCheckSvn)
186 ON_BN_CLICKED(IDC_CHECK_SVN_TRUNK, &CCloneDlg::OnBnClickedCheckSvnTrunk)
187 ON_BN_CLICKED(IDC_CHECK_SVN_TAG, &CCloneDlg::OnBnClickedCheckSvnTag)
188 ON_BN_CLICKED(IDC_CHECK_SVN_BRANCH, &CCloneDlg::OnBnClickedCheckSvnBranch)
189 ON_BN_CLICKED(IDC_CHECK_SVN_FROM, &CCloneDlg::OnBnClickedCheckSvnFrom)
190 ON_BN_CLICKED(IDC_CHECK_DEPTH, &CCloneDlg::OnBnClickedCheckDepth)
191 ON_BN_CLICKED(IDC_CHECK_BARE, &CCloneDlg::OnBnClickedCheckBare)
192 ON_BN_CLICKED(IDC_CHECK_RECURSIVE, &CCloneDlg::OnBnClickedCheckRecursive)
193 ON_BN_CLICKED(IDC_CHECK_USERNAME, &CCloneDlg::OnBnClickedCheckUsername)
194 END_MESSAGE_MAP()
196 // CCloneDlg message handlers
198 void CCloneDlg::OnOK()
200 m_bSaving = true;
201 this->m_URLCombo.GetWindowTextW(m_URL);
202 m_URL.Trim();
203 UpdateData(TRUE);
204 if(m_URL.IsEmpty() || m_Directory.IsEmpty())
206 CMessageBox::Show(NULL, IDS_PROC_CLONE_URLDIREMPTY, IDS_APPNAME, MB_OK);
207 m_bSaving = false;
208 return;
211 if (m_bBranch && !g_Git.IsBranchNameValid(m_strBranch))
213 ShowEditBalloon(IDC_EDIT_BRANCH, IDS_B_T_NOTEMPTY, TTI_ERROR);
214 m_bSaving = false;
215 return;
218 if (m_bOrigin && m_strOrigin.GetLength() == 0)
220 ShowEditBalloon(IDC_EDIT_ORIGIN, IDS_B_T_NOTEMPTY, TTI_ERROR);
221 m_bSaving = false;
222 return;
225 m_URLCombo.SaveHistory();
226 m_PuttyKeyCombo.SaveHistory();
228 this->m_PuttyKeyCombo.GetWindowText(m_strPuttyKeyFile);
229 CResizableDialog::OnOK();
230 m_bSaving = false;
234 void CCloneDlg::OnCancel()
236 CResizableDialog::OnCancel();
239 void CCloneDlg::OnBnClickedCloneBrowseUrl()
241 CBrowseFolder browseFolder;
242 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
243 CString strCloneDirectory;
245 int sel = (int)this->m_BrowseUrl.GetCurrentEntry();
246 this->m_regBrowseUrl = sel;
248 if( sel == 1 )
250 CString str;
251 m_URLCombo.GetWindowText(str);
252 ShellExecute(NULL, _T("open"), str.Trim(), NULL,NULL, SW_SHOW);
253 return ;
256 this->m_URLCombo.GetWindowTextW(strCloneDirectory);
257 if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK)
259 this->m_URLCombo.SetWindowTextW(strCloneDirectory);
263 void CCloneDlg::OnBnClickedCloneDirBrowse()
265 CBrowseFolder browseFolder;
266 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
267 CString strCloneDirectory = this->m_Directory;
268 if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK)
270 UpdateData(TRUE);
271 m_Directory = strCloneDirectory;
272 UpdateData(FALSE);
276 void CCloneDlg::OnBnClickedPuttykeyfileBrowse()
278 CFileDialog dlg(TRUE,NULL,
279 NULL,
280 OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
281 CString(MAKEINTRESOURCE(IDS_PUTTYKEYFILEFILTER)));
283 this->UpdateData();
284 if(dlg.DoModal()==IDOK)
286 this->m_PuttyKeyCombo.SetWindowText( dlg.GetPathName() );
291 void CCloneDlg::OnBnClickedPuttykeyAutoload()
293 this->UpdateData();
294 this->GetDlgItem(IDC_PUTTYKEYFILE)->EnableWindow(m_bAutoloadPuttyKeyFile);
295 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE)->EnableWindow(m_bAutoloadPuttyKeyFile);
298 void CCloneDlg::OnCbnEditchangeUrlcombo()
300 // do not update member variables from UI while saving
301 if (m_bSaving || m_bExactPath)
302 return;
304 this->UpdateData();
305 CString url;
306 m_URLCombo.GetWindowText(url);
307 url.Trim();
309 if(m_OldURL == url )
310 return;
312 m_OldURL=url;
314 //if(url.IsEmpty())
315 // return;
317 CString old;
318 old=m_ModuleName;
320 url.Replace(_T('\\'),_T('/'));
322 // add compatibility for Google Code git urls
323 if (url.GetLength() > 0 && url[url.GetLength()-1] == _T('/')) {
324 url = url.Left(url.GetLength() - 1);
327 int start=url.ReverseFind(_T('/'));
328 if(start<0)
330 start = url.ReverseFind(_T(':'));
331 if(start <0)
332 start = url.ReverseFind(_T('@'));
334 if(start<0)
335 start = 0;
337 CString temp;
338 temp=url.Mid(start+1);
340 temp=temp.MakeLower();
342 // we've to check whether the URL ends with .git (instead of using the first .git)
343 int end = temp.Right(4) == _T(".git") ? (temp.GetLength() - 4) : temp.GetLength();
345 //CString modulename;
346 m_ModuleName=url.Mid(start+1,end);
348 start = m_Directory.ReverseFind(_T('\\'));
349 if(start <0 )
350 start = m_Directory.ReverseFind(_T('/'));
351 if(start <0 )
352 start =0;
354 int dirstart=m_Directory.Find(old,start);
355 if(dirstart>=0 && (dirstart+old.GetLength() == m_Directory.GetLength()) )
357 m_Directory=m_Directory.Left(dirstart);
358 m_Directory+=m_ModuleName;
361 else
363 if(m_Directory.GetLength()>0 &&
364 (m_Directory[m_Directory.GetLength()-1] != _T('\\') &&
365 m_Directory[m_Directory.GetLength()-1] != _T('/') ) )
367 m_Directory += _T('\\');
369 m_Directory += m_ModuleName;
372 if(m_Directory.GetLength()>0)
374 if( m_Directory[m_Directory.GetLength()-1] == _T('\\') ||
375 m_Directory[m_Directory.GetLength()-1] == _T('/')
378 m_Directory=m_Directory.Left(m_Directory.GetLength()-1);
382 this->UpdateData(FALSE);
385 void CCloneDlg::OnBnClickedCheckSvn()
387 this->UpdateData();
389 if(this->m_bSVN)
391 CString str;
392 m_URLCombo.GetWindowText(str);
394 while(str.GetLength()>=1 &&
395 str[str.GetLength()-1] == _T('\\') &&
396 str[str.GetLength()-1] == _T('/'))
398 str=str.Left(str.GetLength()-1);
400 if(str.GetLength()>=5 && (str.Right(5).MakeLower() == _T("trunk") ))
402 this->m_bSVNBranch=this->m_bSVNTags=this->m_bSVNTrunk = FALSE;
404 else
406 this->m_bSVNBranch=this->m_bSVNTags=this->m_bSVNTrunk = TRUE;
408 m_bDepth = false;
409 m_bBare = false;
410 m_bRecursive = false;
411 m_bBranch = FALSE;
412 m_bOrigin = FALSE;
413 this->UpdateData(FALSE);
414 OnBnClickedCheckDepth();
416 this->GetDlgItem(IDC_CHECK_DEPTH)->EnableWindow(!m_bSVN);
417 this->GetDlgItem(IDC_CHECK_BARE)->EnableWindow(!m_bSVN);
418 this->GetDlgItem(IDC_CHECK_RECURSIVE)->EnableWindow(!m_bSVN);
419 this->GetDlgItem(IDC_CHECK_BRANCH)->EnableWindow(!m_bSVN);
420 this->GetDlgItem(IDC_EDIT_BRANCH)->EnableWindow(!m_bSVN);
421 this->GetDlgItem(IDC_CHECK_ORIGIN)->EnableWindow(!m_bSVN);
422 this->GetDlgItem(IDC_EDIT_ORIGIN)->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);
462 void CCloneDlg::OnBnClickedCheckBare()
464 UpdateData(TRUE);
466 void CCloneDlg::OnBnClickedCheckDepth()
468 UpdateData(TRUE);
469 this->GetDlgItem(IDC_EDIT_DEPTH)->EnableWindow(this->m_bDepth);
472 void CCloneDlg::OnBnClickedCheckBranch()
474 UpdateData(TRUE);
475 this->GetDlgItem(IDC_EDIT_BRANCH)->EnableWindow(this->m_bBranch);
478 void CCloneDlg::OnBnClickedCheckOrigin()
480 UpdateData(TRUE);
481 this->GetDlgItem(IDC_EDIT_ORIGIN)->EnableWindow(this->m_bOrigin);
484 BOOL CCloneDlg::PreTranslateMessage(MSG* pMsg)
486 m_tooltips.RelayEvent(pMsg);
488 return CHorizontalResizableStandAloneDialog::PreTranslateMessage(pMsg);
491 void CCloneDlg::OnBnClickedCheckUsername()
493 UpdateData(TRUE);
494 this->GetDlgItem(IDC_CHECK_USERNAME)->EnableWindow(this->m_bSVN);
495 this->GetDlgItem(IDC_EDIT_USERNAME)->EnableWindow(this->m_bSVNUserName && this->m_bSVN);