1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2007-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include "RelocateCommand.h"
\r
22 #include "SVNProgressDlg.h"
\r
23 #include "ProgressDlg.h"
\r
24 #include "RelocateDlg.h"
\r
26 #include "MessageBox.h"
\r
27 #include "PathUtils.h"
\r
29 bool RelocateCommand::Execute()
\r
34 dlg.m_sFromUrl = CPathUtils::PathUnescape(svn.GetURLFromPath(cmdLinePath));
\r
35 dlg.m_sToUrl = dlg.m_sFromUrl;
\r
37 if (dlg.DoModal() == IDOK)
\r
39 TRACE(_T("relocate from %s to %s\n"), (LPCTSTR)dlg.m_sFromUrl, (LPCTSTR)dlg.m_sToUrl);
\r
40 // crack the urls into their components
\r
41 TCHAR urlpath1[INTERNET_MAX_URL_LENGTH+1];
\r
42 TCHAR scheme1[INTERNET_MAX_URL_LENGTH+1];
\r
43 TCHAR hostname1[INTERNET_MAX_URL_LENGTH+1];
\r
44 TCHAR username1[INTERNET_MAX_URL_LENGTH+1];
\r
45 TCHAR password1[INTERNET_MAX_URL_LENGTH+1];
\r
46 TCHAR urlpath2[INTERNET_MAX_URL_LENGTH+1];
\r
47 TCHAR scheme2[INTERNET_MAX_URL_LENGTH+1];
\r
48 TCHAR hostname2[INTERNET_MAX_URL_LENGTH+1];
\r
49 TCHAR username2[INTERNET_MAX_URL_LENGTH+1];
\r
50 TCHAR password2[INTERNET_MAX_URL_LENGTH+1];
\r
51 URL_COMPONENTS components1 = {0};
\r
52 URL_COMPONENTS components2 = {0};
\r
53 components1.dwStructSize = sizeof(URL_COMPONENTS);
\r
54 components1.dwUrlPathLength = INTERNET_MAX_URL_LENGTH;
\r
55 components1.lpszUrlPath = urlpath1;
\r
56 components1.lpszScheme = scheme1;
\r
57 components1.dwSchemeLength = INTERNET_MAX_URL_LENGTH;
\r
58 components1.lpszHostName = hostname1;
\r
59 components1.dwHostNameLength = INTERNET_MAX_URL_LENGTH;
\r
60 components1.lpszUserName = username1;
\r
61 components1.dwUserNameLength = INTERNET_MAX_URL_LENGTH;
\r
62 components1.lpszPassword = password1;
\r
63 components1.dwPasswordLength = INTERNET_MAX_URL_LENGTH;
\r
64 components2.dwStructSize = sizeof(URL_COMPONENTS);
\r
65 components2.dwUrlPathLength = INTERNET_MAX_URL_LENGTH;
\r
66 components2.lpszUrlPath = urlpath2;
\r
67 components2.lpszScheme = scheme2;
\r
68 components2.dwSchemeLength = INTERNET_MAX_URL_LENGTH;
\r
69 components2.lpszHostName = hostname2;
\r
70 components2.dwHostNameLength = INTERNET_MAX_URL_LENGTH;
\r
71 components2.lpszUserName = username2;
\r
72 components2.dwUserNameLength = INTERNET_MAX_URL_LENGTH;
\r
73 components2.lpszPassword = password2;
\r
74 components2.dwPasswordLength = INTERNET_MAX_URL_LENGTH;
\r
75 CString sTempUrl = dlg.m_sFromUrl;
\r
76 if (sTempUrl.Left(8).Compare(_T("file:///\\"))==0)
\r
77 sTempUrl.Replace(_T("file:///\\"), _T("file://"));
\r
78 InternetCrackUrl((LPCTSTR)sTempUrl, sTempUrl.GetLength(), 0, &components1);
\r
79 sTempUrl = dlg.m_sToUrl;
\r
80 if (sTempUrl.Left(8).Compare(_T("file:///\\"))==0)
\r
81 sTempUrl.Replace(_T("file:///\\"), _T("file://"));
\r
82 InternetCrackUrl((LPCTSTR)sTempUrl, sTempUrl.GetLength(), 0, &components2);
\r
83 // now compare the url components.
\r
84 // If the 'main' parts differ (e.g. hostname, port, scheme, ...) then a relocate is
\r
85 // necessary and we don't show a warning. But if only the path part of the url
\r
86 // changed, we assume the user really wants to switch and show the warning.
\r
87 bool bPossibleSwitch = true;
\r
88 if (components1.dwSchemeLength != components2.dwSchemeLength)
\r
89 bPossibleSwitch = false;
\r
90 else if (_tcsncmp(components1.lpszScheme, components2.lpszScheme, components1.dwSchemeLength))
\r
91 bPossibleSwitch = false;
\r
92 if (components1.dwHostNameLength != components2.dwHostNameLength)
\r
93 bPossibleSwitch = false;
\r
94 else if (_tcsncmp(components1.lpszHostName, components2.lpszHostName, components1.dwHostNameLength))
\r
95 bPossibleSwitch = false;
\r
96 if (components1.dwUserNameLength != components2.dwUserNameLength)
\r
97 bPossibleSwitch = false;
\r
98 else if (_tcsncmp(components1.lpszUserName, components2.lpszUserName, components1.dwUserNameLength))
\r
99 bPossibleSwitch = false;
\r
100 if (components1.dwPasswordLength != components2.dwPasswordLength)
\r
101 bPossibleSwitch = false;
\r
102 else if (_tcsncmp(components1.lpszPassword, components2.lpszPassword, components1.dwPasswordLength))
\r
103 bPossibleSwitch = false;
\r
104 if (components1.nPort != components2.nPort)
\r
105 bPossibleSwitch = false;
\r
106 CString sWarning, sWarningTitle, sHelpPath;
\r
107 sWarning.Format(IDS_WARN_RELOCATEREALLY, (LPCTSTR)dlg.m_sFromUrl, (LPCTSTR)dlg.m_sToUrl);
\r
108 sWarningTitle.LoadString(IDS_WARN_RELOCATEREALLYTITLE);
\r
109 sHelpPath = theApp.m_pszHelpFilePath;
\r
110 sHelpPath += _T("::/tsvn-dug-relocate.html");
\r
111 if ((!bPossibleSwitch)||(CMessageBox::Show((hwndExplorer), sWarning, sWarningTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_HELP, sHelpPath)==IDYES))
\r
115 CProgressDlg progress;
\r
116 if (progress.IsValid())
\r
118 progress.SetTitle(IDS_PROC_RELOCATING);
\r
119 progress.ShowModeless(hwndExplorer);
\r
121 if (!s.Relocate(cmdLinePath, CTSVNPath(dlg.m_sFromUrl), CTSVNPath(dlg.m_sToUrl), TRUE))
\r
124 TRACE(_T("%s\n"), (LPCTSTR)s.GetLastErrorMessage());
\r
125 CMessageBox::Show(hwndExplorer, s.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
\r
130 CString strMessage;
\r
131 strMessage.Format(IDS_PROC_RELOCATEFINISHED, (LPCTSTR)dlg.m_sToUrl);
\r
132 CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseSVN"), MB_ICONINFORMATION);
\r