OSDN Git Service

Change Dir Structure to be same as TortoiseSVN'
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / Commands / RenameCommand.cpp
diff --git a/src/TortoiseProc/Commands/RenameCommand.cpp b/src/TortoiseProc/Commands/RenameCommand.cpp
new file mode 100644 (file)
index 0000000..8f37cf4
--- /dev/null
@@ -0,0 +1,236 @@
+// TortoiseSVN - a Windows shell extension for easy version control\r
+\r
+// Copyright (C) 2007-2008 - TortoiseSVN\r
+\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License\r
+// as published by the Free Software Foundation; either version 2\r
+// of the License, or (at your option) any later version.\r
+\r
+// This program is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+// GNU General Public License for more details.\r
+\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software Foundation,\r
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+//\r
+#include "StdAfx.h"\r
+#include "RenameCommand.h"\r
+\r
+#include "MessageBox.h"\r
+#include "SVNProgressDlg.h"\r
+#include "ProgressDlg.h"\r
+#include "RenameDlg.h"\r
+#include "InputLogDlg.h"\r
+#include "SVN.h"\r
+#include "DirFileEnum.h"\r
+#include "ShellUpdater.h"\r
+\r
+bool RenameCommand::Execute()\r
+{\r
+       bool bRet = false;\r
+       CString filename = cmdLinePath.GetFileOrDirectoryName();\r
+       CString basePath = cmdLinePath.GetContainingDirectory().GetWinPathString();\r
+       ::SetCurrentDirectory(basePath);\r
+\r
+       // show the rename dialog until the user either cancels or enters a new\r
+       // name (one that's different to the original name\r
+       CString sNewName;\r
+       do \r
+       {\r
+               CRenameDlg dlg;\r
+               dlg.m_name = filename;\r
+               if (dlg.DoModal() != IDOK)\r
+                       return FALSE;\r
+               sNewName = dlg.m_name;\r
+       } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));\r
+\r
+       TRACE(_T("rename file %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);\r
+       CTSVNPath destinationPath(basePath);\r
+       if (PathIsRelative(sNewName) && !PathIsURL(sNewName))\r
+               destinationPath.AppendPathString(sNewName);\r
+       else\r
+               destinationPath.SetFromWin(sNewName);\r
+       // check if a rename just with case is requested: that's not possible on windows file systems\r
+       // and we have to show an error.\r
+       if (cmdLinePath.GetWinPathString().CompareNoCase(destinationPath.GetWinPathString())==0)\r
+       {\r
+               //rename to the same file!\r
+               CString sHelpPath = theApp.m_pszHelpFilePath;\r
+               sHelpPath += _T("::/tsvn-dug-rename.html#tsvn-dug-renameincase");\r
+               CMessageBox::Show(hwndExplorer, IDS_PROC_CASERENAME, IDS_APPNAME, MB_OK|MB_HELP, sHelpPath);\r
+       }\r
+       else\r
+       {\r
+               CString sMsg;\r
+               if (SVN::PathIsURL(cmdLinePath))\r
+               {\r
+                       // rename an URL.\r
+                       // Ask for a commit message, then rename directly in\r
+                       // the repository\r
+                       CInputLogDlg input;\r
+                       CString sUUID;\r
+                       SVN svn;\r
+                       svn.GetRepositoryRootAndUUID(cmdLinePath, sUUID);\r
+                       input.SetUUID(sUUID);\r
+                       CString sHint;\r
+                       sHint.Format(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());\r
+                       input.SetActionText(sHint);\r
+                       if (input.DoModal() == IDOK)\r
+                       {\r
+                               sMsg = input.GetLogMessage();\r
+                       }\r
+                       else\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))\r
+               {\r
+                       // renaming a directory can take a while: use the\r
+                       // progress dialog to show the progress of the renaming\r
+                       // operation.\r
+                       CSVNProgressDlg progDlg;\r
+                       progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);\r
+                       if (parser.HasVal(_T("closeonend")))\r
+                               progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));\r
+                       progDlg.SetPathList(pathList);\r
+                       progDlg.SetUrl(destinationPath.GetWinPathString());\r
+                       progDlg.SetCommitMessage(sMsg);\r
+                       progDlg.SetRevision(SVNRev::REV_WC);\r
+                       progDlg.DoModal();\r
+                       bRet = !progDlg.DidErrorsOccur();\r
+               }\r
+               else\r
+               {\r
+                       SVN svn;\r
+                       CString sFilemask = cmdLinePath.GetFilename();\r
+                       if (sFilemask.ReverseFind('.')>=0)\r
+                       {\r
+                               sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));\r
+                       }\r
+                       else\r
+                               sFilemask.Empty();\r
+                       CString sNewMask = sNewName;\r
+                       if (sNewMask.ReverseFind('.'>=0))\r
+                       {\r
+                               sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));\r
+                       }\r
+                       else\r
+                               sNewMask.Empty();\r
+\r
+                       if (((!sFilemask.IsEmpty()) && (parser.HasKey(_T("noquestion")))) ||\r
+                               (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0))\r
+                       {\r
+                               if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))\r
+                               {\r
+                                       TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
+                                       CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+                               }\r
+                               else\r
+                                       bRet = true;\r
+                       }\r
+                       else\r
+                       {\r
+                               // when refactoring, multiple files have to be renamed\r
+                               // at once because those files belong together.\r
+                               // e.g. file.aspx, file.aspx.cs, file.aspx.resx\r
+                               CTSVNPathList renlist;\r
+                               CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+_T(".*"));\r
+                               while (filefind.FindNextFileNoDots())\r
+                               {\r
+                                       if (!filefind.IsDirectory())\r
+                                               renlist.AddPath(CTSVNPath(filefind.GetFilePath()));\r
+                               }\r
+                               if (renlist.GetCount()<=1)\r
+                               {\r
+                                       // we couldn't find any other matching files\r
+                                       // just do the default...\r
+                                       if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))\r
+                                       {\r
+                                               TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
+                                               CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               bRet = true;\r
+                                               CShellUpdater::Instance().AddPathForUpdate(destinationPath);\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       std::map<CString, CString> renmap;\r
+                                       CString sTemp;\r
+                                       CString sRenList;\r
+                                       for (int i=0; i<renlist.GetCount(); ++i)\r
+                                       {\r
+                                               CString sFilename = renlist[i].GetFilename();\r
+                                               CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());\r
+                                               sTemp.Format(_T("\n%s -> %s"), (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);\r
+                                               if (!renlist[i].IsEquivalentTo(cmdLinePath))\r
+                                                       sRenList += sTemp;\r
+                                               renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+_T("\\")+sNewFilename;\r
+                                       }\r
+                                       CString sRenameMultipleQuestion;\r
+                                       sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);\r
+                                       UINT idret = CMessageBox::Show(hwndExplorer, sRenameMultipleQuestion, _T("TortoiseSVN"), MB_ICONQUESTION|MB_YESNOCANCEL);\r
+                                       if (idret == IDYES)\r
+                                       {\r
+                                               CProgressDlg progress;\r
+                                               progress.SetTitle(IDS_PROC_MOVING);\r
+                                               progress.SetAnimation(IDR_MOVEANI);\r
+                                               progress.SetTime(true);\r
+                                               progress.ShowModeless(CWnd::FromHandle(hwndExplorer));\r
+                                               DWORD count = 1;\r
+                                               for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)\r
+                                               {\r
+                                                       progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);\r
+                                                       progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);\r
+                                                       progress.SetProgress(count, renmap.size());\r
+                                                       if (!svn.Move(CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), TRUE, sMsg))\r
+                                                       {\r
+                                                               if (svn.Err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)\r
+                                                               {\r
+                                                                       bRet = !!MoveFile(it->first, it->second);\r
+                                                               }\r
+                                                               else\r
+                                                               {\r
+                                                                       TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
+                                                                       CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+                                                                       bRet = false;\r
+                                                               }\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               bRet = true;\r
+                                                               CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));\r
+                                                       }\r
+                                               }\r
+                                               progress.Stop();\r
+                                       }\r
+                                       else if (idret == IDNO)\r
+                                       {\r
+                                               // no, user wants to just rename the file he selected\r
+                                               if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))\r
+                                               {\r
+                                                       TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
+                                                       CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       bRet = true;\r
+                                                       CShellUpdater::Instance().AddPathForUpdate(destinationPath);\r
+                                               }\r
+                                       }\r
+                                       else if (idret == IDCANCEL)\r
+                                       {\r
+                                               // nothing\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       return bRet;\r
+}\r