1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2014 - 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
23 #include "TortoiseProc.h"
25 #include "BrowseFolder.h"
26 #include "MessageBox.h"
30 IMPLEMENT_DYNCREATE(CCloneDlg
, CHorizontalResizableStandAloneDialog
)
32 CCloneDlg::CCloneDlg(CWnd
* pParent
/*=NULL*/)
33 : CHorizontalResizableStandAloneDialog(CCloneDlg::IDD
, pParent
)
36 m_bAutoloadPuttyKeyFile
= CAppUtils::IsSSHPutty();
42 m_bNoCheckout
= FALSE
;
48 m_bSVNUserName
= 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_regCloneDir
= CRegString(_T("Software\\TortoiseGit\\TortoiseProc\\CloneDir"));
64 CCloneDlg::~CCloneDlg()
68 void CCloneDlg::DoDataExchange(CDataExchange
* pDX
)
70 CHorizontalResizableStandAloneDialog::DoDataExchange(pDX
);
71 DDX_Control(pDX
, IDC_URLCOMBO
, m_URLCombo
);
72 DDX_Control(pDX
, IDC_PUTTYKEYFILE
, m_PuttyKeyCombo
);
73 DDX_Control(pDX
, IDC_CLONE_BROWSE_URL
, m_BrowseUrl
);
74 DDX_Text(pDX
, IDC_CLONE_DIR
, m_Directory
);
75 DDX_Check(pDX
,IDC_PUTTYKEY_AUTOLOAD
, m_bAutoloadPuttyKeyFile
);
77 DDX_Check(pDX
,IDC_CHECK_SVN
, m_bSVN
);
78 DDX_Check(pDX
,IDC_CHECK_SVN_TRUNK
, m_bSVNTrunk
);
79 DDX_Check(pDX
,IDC_CHECK_SVN_TAG
, m_bSVNTags
);
80 DDX_Check(pDX
,IDC_CHECK_SVN_BRANCH
, m_bSVNBranch
);
81 DDX_Check(pDX
,IDC_CHECK_SVN_FROM
, m_bSVNFrom
);
82 DDX_Check(pDX
,IDC_CHECK_USERNAME
, m_bSVNUserName
);
84 DDX_Text(pDX
, IDC_EDIT_SVN_TRUNK
, m_strSVNTrunk
);
85 DDX_Text(pDX
, IDC_EDIT_SVN_TAG
, m_strSVNTags
);
86 DDX_Text(pDX
, IDC_EDIT_SVN_BRANCH
, m_strSVNBranchs
);
87 DDX_Text(pDX
, IDC_EDIT_SVN_FROM
, this->m_nSVNFrom
);
88 DDX_Text(pDX
, IDC_EDIT_USERNAME
,m_strUserName
);
90 DDX_Check(pDX
, IDC_CHECK_DEPTH
, m_bDepth
);
91 DDX_Check(pDX
, IDC_CHECK_BARE
, m_bBare
);
92 DDX_Check(pDX
, IDC_CHECK_RECURSIVE
, m_bRecursive
);
93 DDX_Text(pDX
, IDC_EDIT_DEPTH
,m_nDepth
);
94 DDX_Check(pDX
,IDC_CHECK_BRANCH
, m_bBranch
);
95 DDX_Text(pDX
, IDC_EDIT_BRANCH
, m_strBranch
);
96 DDX_Check(pDX
, IDC_CHECK_ORIGIN
, m_bOrigin
);
97 DDX_Text(pDX
, IDC_EDIT_ORIGIN
, m_strOrigin
);
98 DDX_Check(pDX
,IDC_CHECK_NOCHECKOUT
, m_bNoCheckout
);
101 BOOL
CCloneDlg::OnInitDialog()
103 CHorizontalResizableStandAloneDialog::OnInitDialog();
104 CAppUtils::MarkWindowAsUnpinnable(m_hWnd
);
106 AddAnchor(IDC_URLCOMBO
, TOP_LEFT
, TOP_RIGHT
);
107 AddAnchor(IDC_CLONE_BROWSE_URL
, TOP_RIGHT
);
108 AddAnchor(IDC_CLONE_DIR
, TOP_LEFT
,TOP_RIGHT
);
109 AddAnchor(IDC_CLONE_DIR_BROWSE
, TOP_RIGHT
);
110 AddAnchor(IDOK
,BOTTOM_RIGHT
);
111 AddAnchor(IDCANCEL
,BOTTOM_RIGHT
);
113 AddAnchor(IDC_GROUP_CLONE
,TOP_LEFT
,TOP_RIGHT
);
114 AddAnchor(IDC_PUTTYKEYFILE_BROWSE
,TOP_RIGHT
);
115 AddAnchor(IDC_PUTTYKEY_AUTOLOAD
,TOP_LEFT
);
116 AddAnchor(IDC_PUTTYKEYFILE
,TOP_LEFT
,TOP_RIGHT
);
117 AddAnchor(IDC_CLONE_GROUP_SVN
,TOP_LEFT
,TOP_RIGHT
);
118 AddAnchor(IDHELP
, BOTTOM_RIGHT
);
120 AdjustControlSize(IDC_CHECK_DEPTH
);
121 AdjustControlSize(IDC_CHECK_RECURSIVE
);
122 AdjustControlSize(IDC_CHECK_BARE
);
123 AdjustControlSize(IDC_PUTTYKEY_AUTOLOAD
);
124 AdjustControlSize(IDC_CHECK_SVN
);
125 AdjustControlSize(IDC_CHECK_SVN_TRUNK
);
126 AdjustControlSize(IDC_CHECK_SVN_TAG
);
127 AdjustControlSize(IDC_CHECK_SVN_BRANCH
);
128 AdjustControlSize(IDC_CHECK_SVN_FROM
);
129 AdjustControlSize(IDC_CHECK_USERNAME
);
131 m_tooltips
.Create(this);
133 tt
.LoadString(IDS_CLONE_DEPTH_TT
);
134 m_tooltips
.AddTool(IDC_EDIT_DEPTH
,tt
);
135 m_tooltips
.AddTool(IDC_CHECK_DEPTH
,tt
);
137 this->AddOthersToAnchor();
139 if (m_Directory
.IsEmpty())
141 CString dir
= m_regCloneDir
;
142 int index
= dir
.ReverseFind('\\');
144 dir
= dir
.Left(index
);
147 if (m_Directory
.IsEmpty())
149 TCHAR szPath
[MAX_PATH
] = {0};
150 if (SUCCEEDED(SHGetFolderPath(NULL
, CSIDL_PERSONAL
| CSIDL_FLAG_CREATE
, NULL
, SHGFP_TYPE_CURRENT
, szPath
)))
151 m_Directory
= szPath
;
155 m_URLCombo
.SetCaseSensitive(TRUE
);
156 m_URLCombo
.SetURLHistory(TRUE
);
157 m_URLCombo
.LoadHistory(_T("Software\\TortoiseGit\\History\\repoURLS"), _T("url"));
160 CString str
= CAppUtils::GetClipboardLink(_T("git clone "));
163 m_URLCombo
.SetCurSel(0);
165 m_URLCombo
.SetWindowText(str
);
168 m_URLCombo
.SetWindowText(m_URL
);
170 CWnd
*window
=this->GetDlgItem(IDC_CLONE_DIR
);
172 SHAutoComplete(window
->m_hWnd
, SHACF_FILESYSTEM
);
174 this->m_BrowseUrl
.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_DIR
)));
175 this->m_BrowseUrl
.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_WEB
)));
176 m_BrowseUrl
.SetCurrentEntry(m_regBrowseUrl
);
178 m_PuttyKeyCombo
.SetPathHistory(TRUE
);
179 m_PuttyKeyCombo
.LoadHistory(_T("Software\\TortoiseGit\\History\\puttykey"), _T("key"));
180 m_PuttyKeyCombo
.SetCurSel(0);
182 this->GetDlgItem(IDC_PUTTYKEY_AUTOLOAD
)->EnableWindow( CAppUtils::IsSSHPutty() );
183 this->GetDlgItem(IDC_PUTTYKEYFILE
)->EnableWindow(m_bAutoloadPuttyKeyFile
);
184 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE
)->EnableWindow(m_bAutoloadPuttyKeyFile
);
186 EnableSaveRestore(_T("CloneDlg"));
188 OnBnClickedCheckSvn();
189 OnBnClickedCheckDepth();
190 OnBnClickedCheckBranch();
191 OnBnClickedCheckOrigin();
192 return TRUE
; // return TRUE unless you set the focus to a control
195 BEGIN_MESSAGE_MAP(CCloneDlg
, CHorizontalResizableStandAloneDialog
)
196 ON_BN_CLICKED(IDC_CLONE_BROWSE_URL
, &CCloneDlg::OnBnClickedCloneBrowseUrl
)
197 ON_BN_CLICKED(IDC_CLONE_DIR_BROWSE
, &CCloneDlg::OnBnClickedCloneDirBrowse
)
198 ON_BN_CLICKED(IDC_CHECK_BRANCH
, &CCloneDlg::OnBnClickedCheckBranch
)
199 ON_BN_CLICKED(IDC_CHECK_ORIGIN
, &CCloneDlg::OnBnClickedCheckOrigin
)
200 ON_BN_CLICKED(IDC_PUTTYKEYFILE_BROWSE
, &CCloneDlg::OnBnClickedPuttykeyfileBrowse
)
201 ON_BN_CLICKED(IDC_PUTTYKEY_AUTOLOAD
, &CCloneDlg::OnBnClickedPuttykeyAutoload
)
202 ON_CBN_EDITCHANGE(IDC_URLCOMBO
, &CCloneDlg::OnCbnEditchangeUrlcombo
)
203 ON_BN_CLICKED(IDC_CHECK_SVN
, &CCloneDlg::OnBnClickedCheckSvn
)
204 ON_BN_CLICKED(IDC_CHECK_SVN_TRUNK
, &CCloneDlg::OnBnClickedCheckSvnTrunk
)
205 ON_BN_CLICKED(IDC_CHECK_SVN_TAG
, &CCloneDlg::OnBnClickedCheckSvnTag
)
206 ON_BN_CLICKED(IDC_CHECK_SVN_BRANCH
, &CCloneDlg::OnBnClickedCheckSvnBranch
)
207 ON_BN_CLICKED(IDC_CHECK_SVN_FROM
, &CCloneDlg::OnBnClickedCheckSvnFrom
)
208 ON_BN_CLICKED(IDC_CHECK_DEPTH
, &CCloneDlg::OnBnClickedCheckDepth
)
209 ON_BN_CLICKED(IDC_CHECK_BARE
, &CCloneDlg::OnBnClickedCheckBare
)
210 ON_BN_CLICKED(IDC_CHECK_RECURSIVE
, &CCloneDlg::OnBnClickedCheckRecursive
)
211 ON_BN_CLICKED(IDC_CHECK_NOCHECKOUT
, &CCloneDlg::OnBnClickedCheckRecursive
)
212 ON_BN_CLICKED(IDC_CHECK_USERNAME
, &CCloneDlg::OnBnClickedCheckUsername
)
215 // CCloneDlg message handlers
217 void CCloneDlg::OnOK()
220 this->m_URLCombo
.GetWindowTextW(m_URL
);
223 if(m_URL
.IsEmpty() || m_Directory
.IsEmpty())
225 CMessageBox::Show(NULL
, IDS_PROC_CLONE_URLDIREMPTY
, IDS_APPNAME
, MB_OK
);
230 if (m_bBranch
&& !g_Git
.IsBranchNameValid(m_strBranch
))
232 ShowEditBalloon(IDC_EDIT_BRANCH
, IDS_B_T_NOTEMPTY
, IDS_ERR_ERROR
, TTI_ERROR
);
237 if (m_bOrigin
&& m_strOrigin
.GetLength() == 0 && !m_bSVN
)
239 ShowEditBalloon(IDC_EDIT_ORIGIN
, IDS_B_T_NOTEMPTY
, IDS_ERR_ERROR
, TTI_ERROR
);
244 m_URLCombo
.SaveHistory();
245 m_PuttyKeyCombo
.SaveHistory();
246 m_regCloneDir
= m_Directory
;
248 this->m_PuttyKeyCombo
.GetWindowText(m_strPuttyKeyFile
);
249 CResizableDialog::OnOK();
254 void CCloneDlg::OnCancel()
256 CResizableDialog::OnCancel();
259 void CCloneDlg::OnBnClickedCloneBrowseUrl()
261 CBrowseFolder browseFolder
;
262 browseFolder
.m_style
= BIF_EDITBOX
| BIF_NEWDIALOGSTYLE
| BIF_RETURNFSANCESTORS
| BIF_RETURNONLYFSDIRS
;
263 CString strCloneDirectory
;
265 int sel
= (int)this->m_BrowseUrl
.GetCurrentEntry();
266 this->m_regBrowseUrl
= sel
;
271 m_URLCombo
.GetWindowText(str
);
272 ShellExecute(NULL
, _T("open"), str
.Trim(), NULL
,NULL
, SW_SHOW
);
276 this->m_URLCombo
.GetWindowTextW(strCloneDirectory
);
277 if (browseFolder
.Show(GetSafeHwnd(), strCloneDirectory
) == CBrowseFolder::OK
)
279 this->m_URLCombo
.SetWindowTextW(strCloneDirectory
);
283 void CCloneDlg::OnBnClickedCloneDirBrowse()
285 CBrowseFolder browseFolder
;
286 browseFolder
.m_style
= BIF_EDITBOX
| BIF_NEWDIALOGSTYLE
| BIF_RETURNFSANCESTORS
| BIF_RETURNONLYFSDIRS
;
287 CString strCloneDirectory
= this->m_Directory
;
288 if (browseFolder
.Show(GetSafeHwnd(), strCloneDirectory
) == CBrowseFolder::OK
)
291 m_Directory
= strCloneDirectory
;
296 void CCloneDlg::OnBnClickedPuttykeyfileBrowse()
298 CFileDialog
dlg(TRUE
,NULL
,
300 OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
,
301 CString(MAKEINTRESOURCE(IDS_PUTTYKEYFILEFILTER
)));
304 if(dlg
.DoModal()==IDOK
)
306 this->m_PuttyKeyCombo
.SetWindowText( dlg
.GetPathName() );
311 void CCloneDlg::OnBnClickedPuttykeyAutoload()
314 this->GetDlgItem(IDC_PUTTYKEYFILE
)->EnableWindow(m_bAutoloadPuttyKeyFile
);
315 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE
)->EnableWindow(m_bAutoloadPuttyKeyFile
);
318 void CCloneDlg::OnCbnEditchangeUrlcombo()
320 // do not update member variables from UI while saving
321 if (m_bSaving
|| m_bExactPath
)
326 m_URLCombo
.GetWindowText(url
);
340 url
.Replace(_T('\\'),_T('/'));
342 // add compatibility for Google Code git urls
345 int start
=url
.ReverseFind(_T('/'));
348 start
= url
.ReverseFind(_T(':'));
350 start
= url
.ReverseFind(_T('@'));
356 temp
=url
.Mid(start
+1);
358 temp
=temp
.MakeLower();
360 // we've to check whether the URL ends with .git (instead of using the first .git)
361 int end
= temp
.Right(4) == _T(".git") ? (temp
.GetLength() - 4) : temp
.GetLength();
363 //CString modulename;
364 m_ModuleName
=url
.Mid(start
+1,end
);
366 start
= m_Directory
.ReverseFind(_T('\\'));
368 start
= m_Directory
.ReverseFind(_T('/'));
372 int dirstart
=m_Directory
.Find(old
,start
);
373 if(dirstart
>=0 && (dirstart
+old
.GetLength() == m_Directory
.GetLength()) )
374 m_Directory
=m_Directory
.Left(dirstart
);
376 m_Directory
.TrimRight(L
"\\/");
377 m_Directory
+= _T('\\');
378 m_Directory
+= m_ModuleName
;
380 this->UpdateData(FALSE
);
383 void CCloneDlg::OnBnClickedCheckSvn()
390 m_URLCombo
.GetWindowText(str
);
392 str
.TrimRight(L
"\\/");
393 if(str
.GetLength()>=5 && (str
.Right(5).MakeLower() == _T("trunk") ))
395 this->m_bSVNBranch
=this->m_bSVNTags
=this->m_bSVNTrunk
= FALSE
;
399 this->m_bSVNBranch
=this->m_bSVNTags
=this->m_bSVNTrunk
= TRUE
;
403 m_bRecursive
= false;
405 this->UpdateData(FALSE
);
406 OnBnClickedCheckDepth();
408 this->GetDlgItem(IDC_CHECK_DEPTH
)->EnableWindow(!m_bSVN
);
409 this->GetDlgItem(IDC_CHECK_BARE
)->EnableWindow(!m_bSVN
);
410 this->GetDlgItem(IDC_CHECK_RECURSIVE
)->EnableWindow(!m_bSVN
);
411 this->GetDlgItem(IDC_CHECK_BRANCH
)->EnableWindow(!m_bSVN
);
412 this->GetDlgItem(IDC_EDIT_BRANCH
)->EnableWindow(!m_bSVN
);
413 OnBnClickedCheckSvnTrunk();
414 OnBnClickedCheckSvnTag();
415 OnBnClickedCheckSvnBranch();
416 OnBnClickedCheckSvnFrom();
417 OnBnClickedCheckUsername();
420 void CCloneDlg::OnBnClickedCheckSvnTrunk()
423 this->GetDlgItem(IDC_CHECK_SVN_TRUNK
)->EnableWindow(this->m_bSVN
);
424 this->GetDlgItem(IDC_EDIT_SVN_TRUNK
)->EnableWindow(this->m_bSVNTrunk
&&this->m_bSVN
);
427 void CCloneDlg::OnBnClickedCheckSvnTag()
430 this->GetDlgItem(IDC_CHECK_SVN_TAG
)->EnableWindow(this->m_bSVN
);
431 this->GetDlgItem(IDC_EDIT_SVN_TAG
)->EnableWindow(this->m_bSVNTags
&&this->m_bSVN
);
434 void CCloneDlg::OnBnClickedCheckSvnBranch()
437 this->GetDlgItem(IDC_CHECK_SVN_BRANCH
)->EnableWindow(this->m_bSVN
);
438 this->GetDlgItem(IDC_EDIT_SVN_BRANCH
)->EnableWindow(this->m_bSVNBranch
&&this->m_bSVN
);
441 void CCloneDlg::OnBnClickedCheckSvnFrom()
444 this->GetDlgItem(IDC_CHECK_SVN_FROM
)->EnableWindow(this->m_bSVN
);
445 this->GetDlgItem(IDC_EDIT_SVN_FROM
)->EnableWindow(this->m_bSVNFrom
&&this->m_bSVN
);
448 void CCloneDlg::OnBnClickedCheckRecursive()
451 if (m_bRecursive
|| m_bNoCheckout
)
454 GetDlgItem(IDC_CHECK_BARE
)->EnableWindow(FALSE
);
458 GetDlgItem(IDC_CHECK_BARE
)->EnableWindow(TRUE
);
461 void CCloneDlg::OnBnClickedCheckBare()
466 m_bRecursive
= FALSE
;
467 m_bNoCheckout
= FALSE
;
468 GetDlgItem(IDC_CHECK_RECURSIVE
)->EnableWindow(FALSE
);
469 GetDlgItem(IDC_CHECK_NOCHECKOUT
)->EnableWindow(FALSE
);
474 GetDlgItem(IDC_CHECK_RECURSIVE
)->EnableWindow(TRUE
);
475 GetDlgItem(IDC_CHECK_NOCHECKOUT
)->EnableWindow(TRUE
);
478 void CCloneDlg::OnBnClickedCheckDepth()
481 this->GetDlgItem(IDC_EDIT_DEPTH
)->EnableWindow(this->m_bDepth
);
484 void CCloneDlg::OnBnClickedCheckBranch()
487 this->GetDlgItem(IDC_EDIT_BRANCH
)->EnableWindow(this->m_bBranch
);
490 void CCloneDlg::OnBnClickedCheckOrigin()
493 this->GetDlgItem(IDC_EDIT_ORIGIN
)->EnableWindow(this->m_bOrigin
);
496 BOOL
CCloneDlg::PreTranslateMessage(MSG
* pMsg
)
498 m_tooltips
.RelayEvent(pMsg
);
500 return CHorizontalResizableStandAloneDialog::PreTranslateMessage(pMsg
);
503 void CCloneDlg::OnBnClickedCheckUsername()
506 this->GetDlgItem(IDC_CHECK_USERNAME
)->EnableWindow(this->m_bSVN
);
507 this->GetDlgItem(IDC_EDIT_USERNAME
)->EnableWindow(this->m_bSVNUserName
&& this->m_bSVN
);