SyncDlg: Disallow in/out changes to include local context menu
[TortoiseGit.git] / src / TortoiseProc / CloneDlg.cpp
blobec9e113405217ee613ed19ccc87478e0681957a1
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2017 - 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 "Git.h"
25 #include "CloneDlg.h"
26 #include "BrowseFolder.h"
27 #include "MessageBox.h"
28 #include "AppUtils.h"
29 // CCloneDlg dialog
31 IMPLEMENT_DYNCREATE(CCloneDlg, CHorizontalResizableStandAloneDialog)
33 CCloneDlg::CCloneDlg(CWnd* pParent /*=nullptr*/)
34 : CHorizontalResizableStandAloneDialog(CCloneDlg::IDD, pParent)
35 , m_bRecursive(BST_UNCHECKED)
36 , m_bBare(BST_UNCHECKED)
37 , m_bBranch(BST_UNCHECKED)
38 , m_bOrigin(BST_UNCHECKED)
39 , m_bNoCheckout(BST_UNCHECKED)
40 , m_bSVN(BST_UNCHECKED)
41 , m_bSVNTrunk(BST_UNCHECKED)
42 , m_bSVNTags(BST_UNCHECKED)
43 , m_bSVNBranch(BST_UNCHECKED)
44 , m_bSVNFrom(BST_UNCHECKED)
45 , m_bSVNUserName(BST_UNCHECKED)
46 , m_bExactPath(FALSE)
47 , m_strSVNTrunk(L"trunk")
48 , m_strSVNTags(L"tags")
49 , m_strSVNBranchs(L"branches")
50 , m_nDepth(1)
51 , m_bDepth(BST_UNCHECKED)
52 , m_bSaving(false)
53 , m_nSVNFrom(0)
54 , m_regBrowseUrl(L"Software\\TortoiseGit\\TortoiseProc\\CloneBrowse", 0)
55 , m_regCloneDir(L"Software\\TortoiseGit\\TortoiseProc\\CloneDir")
56 , m_regCloneRecursive(L"Software\\TortoiseGit\\TortoiseProc\\CloneRecursive", FALSE)
57 , m_regUseSSHKey(L"Software\\TortoiseGit\\TortoiseProc\\CloneUseSSHKey", TRUE)
59 m_bAutoloadPuttyKeyFile = m_regUseSSHKey && CAppUtils::IsSSHPutty();
62 CCloneDlg::~CCloneDlg()
66 void CCloneDlg::DoDataExchange(CDataExchange* pDX)
68 CHorizontalResizableStandAloneDialog::DoDataExchange(pDX);
69 DDX_Control(pDX, IDC_URLCOMBO, m_URLCombo);
70 DDX_Control(pDX, IDC_PUTTYKEYFILE, m_PuttyKeyCombo);
71 DDX_Control(pDX, IDC_CLONE_BROWSE_URL, m_BrowseUrl);
72 DDX_Text(pDX, IDC_CLONE_DIR, m_Directory);
73 DDX_Check(pDX,IDC_PUTTYKEY_AUTOLOAD, m_bAutoloadPuttyKeyFile);
75 DDX_Check(pDX,IDC_CHECK_SVN, m_bSVN);
76 DDX_Check(pDX,IDC_CHECK_SVN_TRUNK, m_bSVNTrunk);
77 DDX_Check(pDX,IDC_CHECK_SVN_TAG, m_bSVNTags);
78 DDX_Check(pDX,IDC_CHECK_SVN_BRANCH, m_bSVNBranch);
79 DDX_Check(pDX,IDC_CHECK_SVN_FROM, m_bSVNFrom);
80 DDX_Check(pDX,IDC_CHECK_USERNAME, m_bSVNUserName);
82 DDX_Text(pDX, IDC_EDIT_SVN_TRUNK, m_strSVNTrunk);
83 DDX_Text(pDX, IDC_EDIT_SVN_TAG, m_strSVNTags);
84 DDX_Text(pDX, IDC_EDIT_SVN_BRANCH, m_strSVNBranchs);
85 DDX_Text(pDX, IDC_EDIT_SVN_FROM, this->m_nSVNFrom);
86 DDX_Text(pDX, IDC_EDIT_USERNAME,m_strUserName);
88 DDX_Check(pDX, IDC_CHECK_DEPTH, m_bDepth);
89 DDX_Check(pDX, IDC_CHECK_BARE, m_bBare);
90 DDX_Check(pDX, IDC_CHECK_RECURSIVE, m_bRecursive);
91 DDX_Text(pDX, IDC_EDIT_DEPTH,m_nDepth);
92 DDX_Check(pDX,IDC_CHECK_BRANCH, m_bBranch);
93 DDX_Text(pDX, IDC_EDIT_BRANCH, m_strBranch);
94 DDX_Check(pDX, IDC_CHECK_ORIGIN, m_bOrigin);
95 DDX_Text(pDX, IDC_EDIT_ORIGIN, m_strOrigin);
96 DDX_Check(pDX,IDC_CHECK_NOCHECKOUT, m_bNoCheckout);
99 BOOL CCloneDlg::OnInitDialog()
101 CHorizontalResizableStandAloneDialog::OnInitDialog();
102 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
104 AddAnchor(IDC_URLCOMBO, TOP_LEFT, TOP_RIGHT);
105 AddAnchor(IDC_CLONE_BROWSE_URL, TOP_RIGHT);
106 AddAnchor(IDC_CLONE_DIR, TOP_LEFT,TOP_RIGHT);
107 AddAnchor(IDC_CLONE_DIR_BROWSE, TOP_RIGHT);
108 AddAnchor(IDOK,BOTTOM_RIGHT);
109 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
111 AddAnchor(IDC_GROUP_CLONE,TOP_LEFT,TOP_RIGHT);
112 AddAnchor(IDC_PUTTYKEYFILE_BROWSE,TOP_RIGHT);
113 AddAnchor(IDC_PUTTYKEY_AUTOLOAD,TOP_LEFT);
114 AddAnchor(IDC_PUTTYKEYFILE,TOP_LEFT,TOP_RIGHT);
115 AddAnchor(IDC_CLONE_GROUP_SVN,TOP_LEFT,TOP_RIGHT);
116 AddAnchor(IDHELP, BOTTOM_RIGHT);
118 AdjustControlSize(IDC_CHECK_DEPTH);
119 AdjustControlSize(IDC_CHECK_RECURSIVE);
120 AdjustControlSize(IDC_CHECK_BARE);
121 AdjustControlSize(IDC_PUTTYKEY_AUTOLOAD);
122 AdjustControlSize(IDC_CHECK_SVN);
123 AdjustControlSize(IDC_CHECK_SVN_TRUNK);
124 AdjustControlSize(IDC_CHECK_SVN_TAG);
125 AdjustControlSize(IDC_CHECK_SVN_BRANCH);
126 AdjustControlSize(IDC_CHECK_SVN_FROM);
127 AdjustControlSize(IDC_CHECK_USERNAME);
129 CString tt;
130 tt.LoadString(IDS_CLONE_DEPTH_TT);
131 m_tooltips.AddTool(IDC_EDIT_DEPTH,tt);
132 m_tooltips.AddTool(IDC_CHECK_DEPTH,tt);
134 this->AddOthersToAnchor();
136 if (m_Directory.IsEmpty())
138 CString dir = m_regCloneDir;
139 int index = dir.ReverseFind('\\');
140 if (index >= 0)
141 dir = dir.Left(index);
142 m_Directory = dir;
144 if (m_Directory.IsEmpty())
146 TCHAR szPath[MAX_PATH] = {0};
147 if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, nullptr, SHGFP_TYPE_CURRENT, szPath)))
148 m_Directory = szPath;
150 m_bRecursive = m_regCloneRecursive;
151 UpdateData(FALSE);
153 m_URLCombo.SetCaseSensitive(TRUE);
154 m_URLCombo.SetURLHistory(TRUE);
155 m_URLCombo.LoadHistory(L"Software\\TortoiseGit\\History\\repoURLS", L"url");
156 if(m_URL.IsEmpty())
158 CString str = CAppUtils::GetClipboardLink(L"git clone ");
159 str.Trim();
160 if(str.IsEmpty())
161 m_URLCombo.SetCurSel(0);
162 else
163 m_URLCombo.SetWindowText(str);
165 else
166 m_URLCombo.SetWindowText(m_URL);
168 CWnd *window=this->GetDlgItem(IDC_CLONE_DIR);
169 if(window)
170 SHAutoComplete(window->m_hWnd, SHACF_FILESYSTEM);
172 this->m_BrowseUrl.AddEntry(CString(MAKEINTRESOURCE(IDS_PROC_CLONE_DIR)));
173 this->m_BrowseUrl.AddEntry(CString(MAKEINTRESOURCE(IDS_REPOBROWSE_OPEN)));
174 m_BrowseUrl.SetCurrentEntry(m_regBrowseUrl);
176 m_PuttyKeyCombo.SetPathHistory(TRUE);
177 m_PuttyKeyCombo.LoadHistory(L"Software\\TortoiseGit\\History\\puttykey", L"key");
178 m_PuttyKeyCombo.SetCurSel(0);
180 this->GetDlgItem(IDC_PUTTYKEY_AUTOLOAD)->EnableWindow( CAppUtils::IsSSHPutty() );
181 this->GetDlgItem(IDC_PUTTYKEYFILE)->EnableWindow(m_bAutoloadPuttyKeyFile);
182 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE)->EnableWindow(m_bAutoloadPuttyKeyFile);
184 EnableSaveRestore(L"CloneDlg");
186 OnBnClickedCheckSvn();
187 OnBnClickedCheckDepth();
188 OnBnClickedCheckBranch();
189 OnBnClickedCheckOrigin();
190 return TRUE; // return TRUE unless you set the focus to a control
193 BEGIN_MESSAGE_MAP(CCloneDlg, CHorizontalResizableStandAloneDialog)
194 ON_BN_CLICKED(IDC_CLONE_BROWSE_URL, &CCloneDlg::OnBnClickedCloneBrowseUrl)
195 ON_BN_CLICKED(IDC_CLONE_DIR_BROWSE, &CCloneDlg::OnBnClickedCloneDirBrowse)
196 ON_BN_CLICKED(IDC_CHECK_BRANCH, &CCloneDlg::OnBnClickedCheckBranch)
197 ON_BN_CLICKED(IDC_CHECK_ORIGIN, &CCloneDlg::OnBnClickedCheckOrigin)
198 ON_BN_CLICKED(IDC_PUTTYKEYFILE_BROWSE, &CCloneDlg::OnBnClickedPuttykeyfileBrowse)
199 ON_BN_CLICKED(IDC_PUTTYKEY_AUTOLOAD, &CCloneDlg::OnBnClickedPuttykeyAutoload)
200 ON_CBN_EDITCHANGE(IDC_URLCOMBO, &CCloneDlg::OnCbnEditchangeUrlcombo)
201 ON_BN_CLICKED(IDC_CHECK_SVN, &CCloneDlg::OnBnClickedCheckSvn)
202 ON_BN_CLICKED(IDC_CHECK_SVN_TRUNK, &CCloneDlg::OnBnClickedCheckSvnTrunk)
203 ON_BN_CLICKED(IDC_CHECK_SVN_TAG, &CCloneDlg::OnBnClickedCheckSvnTag)
204 ON_BN_CLICKED(IDC_CHECK_SVN_BRANCH, &CCloneDlg::OnBnClickedCheckSvnBranch)
205 ON_BN_CLICKED(IDC_CHECK_SVN_FROM, &CCloneDlg::OnBnClickedCheckSvnFrom)
206 ON_BN_CLICKED(IDC_CHECK_DEPTH, &CCloneDlg::OnBnClickedCheckDepth)
207 ON_BN_CLICKED(IDC_CHECK_BARE, &CCloneDlg::OnBnClickedCheckBare)
208 ON_BN_CLICKED(IDC_CHECK_RECURSIVE, &CCloneDlg::OnBnClickedCheckRecursive)
209 ON_BN_CLICKED(IDC_CHECK_NOCHECKOUT, &CCloneDlg::OnBnClickedCheckRecursive)
210 ON_BN_CLICKED(IDC_CHECK_USERNAME, &CCloneDlg::OnBnClickedCheckUsername)
211 END_MESSAGE_MAP()
213 // CCloneDlg message handlers
215 void CCloneDlg::OnOK()
217 m_bSaving = true;
218 this->m_URLCombo.GetWindowTextW(m_URL);
219 m_URL.Trim();
220 UpdateData(TRUE);
221 if(m_URL.IsEmpty() || m_Directory.IsEmpty())
223 CMessageBox::Show(GetSafeHwnd(), IDS_PROC_CLONE_URLDIREMPTY, IDS_APPNAME, MB_OK | MB_ICONEXCLAMATION);
224 m_bSaving = false;
225 return;
228 if (m_bBranch && !g_Git.IsBranchNameValid(m_strBranch))
230 ShowEditBalloon(IDC_EDIT_BRANCH, IDS_B_T_NOTEMPTY, IDS_ERR_ERROR, TTI_ERROR);
231 m_bSaving = false;
232 return;
235 if (m_bOrigin && m_strOrigin.IsEmpty() && !m_bSVN)
237 ShowEditBalloon(IDC_EDIT_ORIGIN, IDS_B_T_NOTEMPTY, IDS_ERR_ERROR, TTI_ERROR);
238 m_bSaving = false;
239 return;
242 m_URLCombo.SaveHistory();
243 m_PuttyKeyCombo.SaveHistory();
244 m_regCloneDir = m_Directory;
245 m_regUseSSHKey = m_bAutoloadPuttyKeyFile;
246 m_regCloneRecursive = m_bRecursive;
248 this->m_PuttyKeyCombo.GetWindowText(m_strPuttyKeyFile);
249 CResizableDialog::OnOK();
250 m_bSaving = false;
253 void CCloneDlg::OnCancel()
255 CResizableDialog::OnCancel();
258 void CCloneDlg::OnBnClickedCloneBrowseUrl()
260 CBrowseFolder browseFolder;
261 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
262 CString strCloneDirectory;
264 int sel = (int)this->m_BrowseUrl.GetCurrentEntry();
265 this->m_regBrowseUrl = sel;
267 if( sel == 1 )
269 CString str;
270 m_URLCombo.GetWindowText(str);
271 str.Trim();
272 if (str.IsEmpty())
274 CMessageBox::Show(GetSafeHwnd(), IDS_PROC_CLONE_URLDIREMPTY, IDS_APPNAME, MB_ICONEXCLAMATION);
275 return;
277 if (CAppUtils::ExploreTo(GetSafeHwnd(), str) && (INT_PTR)ShellExecute(nullptr, L"open", str, nullptr, nullptr, SW_SHOW) <= 32)
278 MessageBox(CFormatMessageWrapper(), L"TortoiseGit", MB_ICONERROR);
279 return;
282 this->m_URLCombo.GetWindowTextW(strCloneDirectory);
283 if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK)
285 this->m_URLCombo.SetWindowTextW(strCloneDirectory);
289 void CCloneDlg::OnBnClickedCloneDirBrowse()
291 UpdateData(TRUE);
292 CBrowseFolder browseFolder;
293 browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
294 CString strCloneDirectory = this->m_Directory;
295 if (browseFolder.Show(GetSafeHwnd(), strCloneDirectory) == CBrowseFolder::OK)
297 m_Directory = strCloneDirectory;
298 UpdateData(FALSE);
302 void CCloneDlg::OnBnClickedPuttykeyfileBrowse()
304 UpdateData();
305 CString filename;
306 m_PuttyKeyCombo.GetWindowText(filename);
307 if (!PathFileExists(filename))
308 filename.Empty();
309 if (!CAppUtils::FileOpenSave(filename, nullptr, 0, IDS_PUTTYKEYFILEFILTER, true, GetSafeHwnd()))
310 return;
312 m_PuttyKeyCombo.SetWindowText(filename);
315 void CCloneDlg::OnBnClickedPuttykeyAutoload()
317 this->UpdateData();
318 this->GetDlgItem(IDC_PUTTYKEYFILE)->EnableWindow(m_bAutoloadPuttyKeyFile);
319 this->GetDlgItem(IDC_PUTTYKEYFILE_BROWSE)->EnableWindow(m_bAutoloadPuttyKeyFile);
322 void CCloneDlg::OnCbnEditchangeUrlcombo()
324 // do not update member variables from UI while saving
325 if (m_bSaving || m_bExactPath)
326 return;
328 this->UpdateData();
329 CString url;
330 m_URLCombo.GetWindowText(url);
331 url.Trim();
333 if(m_OldURL == url )
334 return;
336 m_OldURL=url;
338 //if(url.IsEmpty())
339 // return;
341 CString old;
342 old=m_ModuleName;
344 url.Replace(L'\\', L'/');
346 // add compatibility for Google Code git urls
347 url.TrimRight(L"/");
349 int start = url.ReverseFind(L'/');
350 if(start<0)
352 start = url.ReverseFind(L':');
353 if(start <0)
354 start = url.ReverseFind(L'@');
356 if(start<0)
357 start = 0;
359 CString temp;
360 temp=url.Mid(start+1);
362 temp=temp.MakeLower();
364 // we've to check whether the URL ends with .git (instead of using the first .git)
365 int end = CStringUtils::EndsWith(temp, L".git") ? (temp.GetLength() - 4) : temp.GetLength();
367 //CString modulename;
368 m_ModuleName=url.Mid(start+1,end);
370 start = m_Directory.ReverseFind(L'\\');
371 if(start <0 )
372 start = m_Directory.ReverseFind(L'/');
373 if(start <0 )
374 start =0;
376 int dirstart=m_Directory.Find(old,start);
377 if(dirstart>=0 && (dirstart+old.GetLength() == m_Directory.GetLength()) )
378 m_Directory=m_Directory.Left(dirstart);
380 m_Directory.TrimRight(L"\\/");
381 m_Directory += L'\\';
382 m_Directory += m_ModuleName;
384 // check if URL starts with http://, https:// or git:// in those cases loading putty keys is only
385 // asking for passwords for keys that are never used
386 if (url.Find(L"http://", 0) >= 0 || url.Find(L"https://", 0) >= 0 || url.Find(L"git://", 0) >= 0)
387 m_bAutoloadPuttyKeyFile = false;
388 else
389 m_bAutoloadPuttyKeyFile = m_regUseSSHKey && CAppUtils::IsSSHPutty();
391 this->UpdateData(FALSE);
394 void CCloneDlg::OnBnClickedCheckSvn()
396 this->UpdateData();
398 if(this->m_bSVN)
400 CString str;
401 m_URLCombo.GetWindowText(str);
403 str.TrimRight(L"\\/");
404 if (CStringUtils::EndsWithI(str, L"trunk"))
405 this->m_bSVNBranch=this->m_bSVNTags=this->m_bSVNTrunk = FALSE;
406 else
407 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_bNoCheckout = 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_NOCHECKOUT)->EnableWindow(!m_bSVN);
422 OnBnClickedCheckSvnTrunk();
423 OnBnClickedCheckSvnTag();
424 OnBnClickedCheckSvnBranch();
425 OnBnClickedCheckSvnFrom();
426 OnBnClickedCheckUsername();
429 void CCloneDlg::OnBnClickedCheckSvnTrunk()
431 UpdateData(TRUE);
432 this->GetDlgItem(IDC_CHECK_SVN_TRUNK)->EnableWindow(this->m_bSVN);
433 this->GetDlgItem(IDC_EDIT_SVN_TRUNK)->EnableWindow(this->m_bSVNTrunk&&this->m_bSVN);
436 void CCloneDlg::OnBnClickedCheckSvnTag()
438 UpdateData(TRUE);
439 this->GetDlgItem(IDC_CHECK_SVN_TAG)->EnableWindow(this->m_bSVN);
440 this->GetDlgItem(IDC_EDIT_SVN_TAG)->EnableWindow(this->m_bSVNTags&&this->m_bSVN);
443 void CCloneDlg::OnBnClickedCheckSvnBranch()
445 UpdateData(TRUE);
446 this->GetDlgItem(IDC_CHECK_SVN_BRANCH)->EnableWindow(this->m_bSVN);
447 this->GetDlgItem(IDC_EDIT_SVN_BRANCH)->EnableWindow(this->m_bSVNBranch&&this->m_bSVN);
450 void CCloneDlg::OnBnClickedCheckSvnFrom()
452 UpdateData(TRUE);
453 this->GetDlgItem(IDC_CHECK_SVN_FROM)->EnableWindow(this->m_bSVN);
454 this->GetDlgItem(IDC_EDIT_SVN_FROM)->EnableWindow(this->m_bSVNFrom&&this->m_bSVN);
457 void CCloneDlg::OnBnClickedCheckRecursive()
459 UpdateData(TRUE);
460 if (m_bRecursive || m_bNoCheckout)
462 m_bBare = FALSE;
463 GetDlgItem(IDC_CHECK_BARE)->EnableWindow(FALSE);
464 UpdateData(FALSE);
466 else
467 GetDlgItem(IDC_CHECK_BARE)->EnableWindow(TRUE);
470 void CCloneDlg::OnBnClickedCheckBare()
472 UpdateData(TRUE);
473 if (m_bBare)
475 m_bRecursive = FALSE;
476 m_bNoCheckout = FALSE;
477 GetDlgItem(IDC_CHECK_RECURSIVE)->EnableWindow(FALSE);
478 GetDlgItem(IDC_CHECK_NOCHECKOUT)->EnableWindow(FALSE);
479 UpdateData(FALSE);
481 else
483 GetDlgItem(IDC_CHECK_RECURSIVE)->EnableWindow(TRUE);
484 GetDlgItem(IDC_CHECK_NOCHECKOUT)->EnableWindow(TRUE);
487 void CCloneDlg::OnBnClickedCheckDepth()
489 UpdateData(TRUE);
490 this->GetDlgItem(IDC_EDIT_DEPTH)->EnableWindow(this->m_bDepth);
493 void CCloneDlg::OnBnClickedCheckBranch()
495 UpdateData(TRUE);
496 this->GetDlgItem(IDC_EDIT_BRANCH)->EnableWindow(this->m_bBranch);
499 void CCloneDlg::OnBnClickedCheckOrigin()
501 UpdateData(TRUE);
502 this->GetDlgItem(IDC_EDIT_ORIGIN)->EnableWindow(this->m_bOrigin);
505 void CCloneDlg::OnBnClickedCheckUsername()
507 UpdateData(TRUE);
508 this->GetDlgItem(IDC_CHECK_USERNAME)->EnableWindow(this->m_bSVN);
509 this->GetDlgItem(IDC_EDIT_USERNAME)->EnableWindow(this->m_bSVNUserName && this->m_bSVN);