1 // TortoiseSVN - a Windows shell extension for easy version control
3 // Copyright (C) 2007-2008 - TortoiseSVN
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.
20 #include "RelocateCommand.h"
22 #include "SVNProgressDlg.h"
23 #include "ProgressDlg.h"
24 #include "RelocateDlg.h"
26 #include "MessageBox.h"
27 #include "PathUtils.h"
29 bool RelocateCommand::Execute()
34 dlg
.m_sFromUrl
= CPathUtils::PathUnescape(svn
.GetURLFromPath(cmdLinePath
));
35 dlg
.m_sToUrl
= dlg
.m_sFromUrl
;
37 if (dlg
.DoModal() == IDOK
)
39 TRACE(_T("relocate from %s to %s\n"), (LPCTSTR
)dlg
.m_sFromUrl
, (LPCTSTR
)dlg
.m_sToUrl
);
40 // crack the urls into their components
41 TCHAR urlpath1
[INTERNET_MAX_URL_LENGTH
+1];
42 TCHAR scheme1
[INTERNET_MAX_URL_LENGTH
+1];
43 TCHAR hostname1
[INTERNET_MAX_URL_LENGTH
+1];
44 TCHAR username1
[INTERNET_MAX_URL_LENGTH
+1];
45 TCHAR password1
[INTERNET_MAX_URL_LENGTH
+1];
46 TCHAR urlpath2
[INTERNET_MAX_URL_LENGTH
+1];
47 TCHAR scheme2
[INTERNET_MAX_URL_LENGTH
+1];
48 TCHAR hostname2
[INTERNET_MAX_URL_LENGTH
+1];
49 TCHAR username2
[INTERNET_MAX_URL_LENGTH
+1];
50 TCHAR password2
[INTERNET_MAX_URL_LENGTH
+1];
51 URL_COMPONENTS components1
= {0};
52 URL_COMPONENTS components2
= {0};
53 components1
.dwStructSize
= sizeof(URL_COMPONENTS
);
54 components1
.dwUrlPathLength
= INTERNET_MAX_URL_LENGTH
;
55 components1
.lpszUrlPath
= urlpath1
;
56 components1
.lpszScheme
= scheme1
;
57 components1
.dwSchemeLength
= INTERNET_MAX_URL_LENGTH
;
58 components1
.lpszHostName
= hostname1
;
59 components1
.dwHostNameLength
= INTERNET_MAX_URL_LENGTH
;
60 components1
.lpszUserName
= username1
;
61 components1
.dwUserNameLength
= INTERNET_MAX_URL_LENGTH
;
62 components1
.lpszPassword
= password1
;
63 components1
.dwPasswordLength
= INTERNET_MAX_URL_LENGTH
;
64 components2
.dwStructSize
= sizeof(URL_COMPONENTS
);
65 components2
.dwUrlPathLength
= INTERNET_MAX_URL_LENGTH
;
66 components2
.lpszUrlPath
= urlpath2
;
67 components2
.lpszScheme
= scheme2
;
68 components2
.dwSchemeLength
= INTERNET_MAX_URL_LENGTH
;
69 components2
.lpszHostName
= hostname2
;
70 components2
.dwHostNameLength
= INTERNET_MAX_URL_LENGTH
;
71 components2
.lpszUserName
= username2
;
72 components2
.dwUserNameLength
= INTERNET_MAX_URL_LENGTH
;
73 components2
.lpszPassword
= password2
;
74 components2
.dwPasswordLength
= INTERNET_MAX_URL_LENGTH
;
75 CString sTempUrl
= dlg
.m_sFromUrl
;
76 if (sTempUrl
.Left(8).Compare(_T("file:///\\"))==0)
77 sTempUrl
.Replace(_T("file:///\\"), _T("file://"));
78 InternetCrackUrl((LPCTSTR
)sTempUrl
, sTempUrl
.GetLength(), 0, &components1
);
79 sTempUrl
= dlg
.m_sToUrl
;
80 if (sTempUrl
.Left(8).Compare(_T("file:///\\"))==0)
81 sTempUrl
.Replace(_T("file:///\\"), _T("file://"));
82 InternetCrackUrl((LPCTSTR
)sTempUrl
, sTempUrl
.GetLength(), 0, &components2
);
83 // now compare the url components.
84 // If the 'main' parts differ (e.g. hostname, port, scheme, ...) then a relocate is
85 // necessary and we don't show a warning. But if only the path part of the url
86 // changed, we assume the user really wants to switch and show the warning.
87 bool bPossibleSwitch
= true;
88 if (components1
.dwSchemeLength
!= components2
.dwSchemeLength
)
89 bPossibleSwitch
= false;
90 else if (_tcsncmp(components1
.lpszScheme
, components2
.lpszScheme
, components1
.dwSchemeLength
))
91 bPossibleSwitch
= false;
92 if (components1
.dwHostNameLength
!= components2
.dwHostNameLength
)
93 bPossibleSwitch
= false;
94 else if (_tcsncmp(components1
.lpszHostName
, components2
.lpszHostName
, components1
.dwHostNameLength
))
95 bPossibleSwitch
= false;
96 if (components1
.dwUserNameLength
!= components2
.dwUserNameLength
)
97 bPossibleSwitch
= false;
98 else if (_tcsncmp(components1
.lpszUserName
, components2
.lpszUserName
, components1
.dwUserNameLength
))
99 bPossibleSwitch
= false;
100 if (components1
.dwPasswordLength
!= components2
.dwPasswordLength
)
101 bPossibleSwitch
= false;
102 else if (_tcsncmp(components1
.lpszPassword
, components2
.lpszPassword
, components1
.dwPasswordLength
))
103 bPossibleSwitch
= false;
104 if (components1
.nPort
!= components2
.nPort
)
105 bPossibleSwitch
= false;
106 CString sWarning
, sWarningTitle
, sHelpPath
;
107 sWarning
.Format(IDS_WARN_RELOCATEREALLY
, (LPCTSTR
)dlg
.m_sFromUrl
, (LPCTSTR
)dlg
.m_sToUrl
);
108 sWarningTitle
.LoadString(IDS_WARN_RELOCATEREALLYTITLE
);
109 sHelpPath
= theApp
.m_pszHelpFilePath
;
110 sHelpPath
+= _T("::/tsvn-dug-relocate.html");
111 if ((!bPossibleSwitch
)||(CMessageBox::Show((hwndExplorer
), sWarning
, sWarningTitle
, MB_YESNO
|MB_ICONWARNING
|MB_DEFBUTTON2
|MB_HELP
, sHelpPath
)==IDYES
))
115 CProgressDlg progress
;
116 if (progress
.IsValid())
118 progress
.SetTitle(IDS_PROC_RELOCATING
);
119 progress
.ShowModeless(hwndExplorer
);
121 if (!s
.Relocate(cmdLinePath
, CTSVNPath(dlg
.m_sFromUrl
), CTSVNPath(dlg
.m_sToUrl
), TRUE
))
124 TRACE(_T("%s\n"), (LPCTSTR
)s
.GetLastErrorMessage());
125 CMessageBox::Show(hwndExplorer
, s
.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR
);
131 strMessage
.Format(IDS_PROC_RELOCATEFINISHED
, (LPCTSTR
)dlg
.m_sToUrl
);
132 CMessageBox::Show(hwndExplorer
, strMessage
, _T("TortoiseSVN"), MB_ICONINFORMATION
);