Add Shell Notification at add, cleanup and remove and rename, CommitDlg.cpp
[TortoiseGit.git] / src / TortoiseProc / Commands / RenameCommand.cpp
blobb4a4e6d6c34742d28cd9f392f83ad19e5290bed2
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.
19 #include "StdAfx.h"
20 #include "RenameCommand.h"
22 #include "MessageBox.h"
23 //#include "SVNProgressDlg.h"
24 //#include "ProgressDlg.h"
25 #include "RenameDlg.h"
26 #include "InputLogDlg.h"
27 #include "Git.h"
28 #include "DirFileEnum.h"
29 #include "ShellUpdater.h"
31 bool RenameCommand::Execute()
33 bool bRet = false;
34 CString filename = cmdLinePath.GetFileOrDirectoryName();
35 CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString();
36 //::SetCurrentDirectory(basePath);
38 // show the rename dialog until the user either cancels or enters a new
39 // name (one that's different to the original name
40 CString sNewName;
41 do
43 CRenameDlg dlg;
44 dlg.m_name = filename;
45 if (dlg.DoModal() != IDOK)
46 return FALSE;
47 sNewName = dlg.m_name;
48 } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));
50 if(!basePath.IsEmpty())
51 sNewName=basePath+"/"+sNewName;
53 CString cmd;
54 CString output;
55 cmd.Format(_T("git.exe mv \"%s\" \"%s\""),
56 cmdLinePath.GetGitPathString(),
57 sNewName);
59 if(g_Git.Run(cmd,&output,CP_OEMCP))
61 CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);
64 CTGitPath newpath;
65 newpath.SetFromGit(sNewName);
67 CShellUpdater::Instance().AddPathForUpdate(newpath);
68 #if 0
69 TRACE(_T("rename file %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);
70 CTSVNPath destinationPath(basePath);
71 if (PathIsRelative(sNewName) && !PathIsURL(sNewName))
72 destinationPath.AppendPathString(sNewName);
73 else
74 destinationPath.SetFromWin(sNewName);
75 // check if a rename just with case is requested: that's not possible on windows file systems
76 // and we have to show an error.
77 if (cmdLinePath.GetWinPathString().CompareNoCase(destinationPath.GetWinPathString())==0)
79 //rename to the same file!
80 CString sHelpPath = theApp.m_pszHelpFilePath;
81 sHelpPath += _T("::/tsvn-dug-rename.html#tsvn-dug-renameincase");
82 CMessageBox::Show(hwndExplorer, IDS_PROC_CASERENAME, IDS_APPNAME, MB_OK|MB_HELP, sHelpPath);
84 else
86 CString sMsg;
87 if (SVN::PathIsURL(cmdLinePath))
89 // rename an URL.
90 // Ask for a commit message, then rename directly in
91 // the repository
92 CInputLogDlg input;
93 CString sUUID;
94 SVN svn;
95 svn.GetRepositoryRootAndUUID(cmdLinePath, sUUID);
96 input.SetUUID(sUUID);
97 CString sHint;
98 sHint.Format(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());
99 input.SetActionText(sHint);
100 if (input.DoModal() == IDOK)
102 sMsg = input.GetLogMessage();
104 else
106 return FALSE;
109 if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))
111 // renaming a directory can take a while: use the
112 // progress dialog to show the progress of the renaming
113 // operation.
114 CSVNProgressDlg progDlg;
115 progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);
116 if (parser.HasVal(_T("closeonend")))
117 progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));
118 progDlg.SetPathList(pathList);
119 progDlg.SetUrl(destinationPath.GetWinPathString());
120 progDlg.SetCommitMessage(sMsg);
121 progDlg.SetRevision(SVNRev::REV_WC);
122 progDlg.DoModal();
123 bRet = !progDlg.DidErrorsOccur();
125 else
127 SVN svn;
128 CString sFilemask = cmdLinePath.GetFilename();
129 if (sFilemask.ReverseFind('.')>=0)
131 sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));
133 else
134 sFilemask.Empty();
135 CString sNewMask = sNewName;
136 if (sNewMask.ReverseFind('.'>=0))
138 sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));
140 else
141 sNewMask.Empty();
143 if (((!sFilemask.IsEmpty()) && (parser.HasKey(_T("noquestion")))) ||
144 (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0))
146 if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
148 TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
149 CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
151 else
152 bRet = true;
154 else
156 // when refactoring, multiple files have to be renamed
157 // at once because those files belong together.
158 // e.g. file.aspx, file.aspx.cs, file.aspx.resx
159 CTSVNPathList renlist;
160 CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+_T(".*"));
161 while (filefind.FindNextFileNoDots())
163 if (!filefind.IsDirectory())
164 renlist.AddPath(CTSVNPath(filefind.GetFilePath()));
166 if (renlist.GetCount()<=1)
168 // we couldn't find any other matching files
169 // just do the default...
170 if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
172 TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
173 CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
175 else
177 bRet = true;
178 CShellUpdater::Instance().AddPathForUpdate(destinationPath);
181 else
183 std::map<CString, CString> renmap;
184 CString sTemp;
185 CString sRenList;
186 for (int i=0; i<renlist.GetCount(); ++i)
188 CString sFilename = renlist[i].GetFilename();
189 CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());
190 sTemp.Format(_T("\n%s -> %s"), (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);
191 if (!renlist[i].IsEquivalentTo(cmdLinePath))
192 sRenList += sTemp;
193 renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+_T("\\")+sNewFilename;
195 CString sRenameMultipleQuestion;
196 sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);
197 UINT idret = CMessageBox::Show(hwndExplorer, sRenameMultipleQuestion, _T("TortoiseSVN"), MB_ICONQUESTION|MB_YESNOCANCEL);
198 if (idret == IDYES)
200 CProgressDlg progress;
201 progress.SetTitle(IDS_PROC_MOVING);
202 progress.SetAnimation(IDR_MOVEANI);
203 progress.SetTime(true);
204 progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
205 DWORD count = 1;
206 for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)
208 progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);
209 progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);
210 progress.SetProgress(count, renmap.size());
211 if (!svn.Move(CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), TRUE, sMsg))
213 if (svn.Err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
215 bRet = !!MoveFile(it->first, it->second);
217 else
219 TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
220 CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
221 bRet = false;
224 else
226 bRet = true;
227 CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));
230 progress.Stop();
232 else if (idret == IDNO)
234 // no, user wants to just rename the file he selected
235 if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
237 TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
238 CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
240 else
242 bRet = true;
243 CShellUpdater::Instance().AddPathForUpdate(destinationPath);
246 else if (idret == IDCANCEL)
248 // nothing
254 #endif
255 CShellUpdater::Instance().Flush();
256 return bRet;