RenameDlg: Improve error reporting for already existing files
[TortoiseGit.git] / src / TortoiseProc / Commands / DropCopyCommand.cpp
blob01f2fa2728570d287793e32ebae9c15e92ffd00e
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013, 2015-2017 - TortoiseGit
4 // Copyright (C) 2007-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "DropCopyCommand.h"
22 #include "SysProgressDlg.h"
23 #include "MessageBox.h"
24 #include "RenameDlg.h"
25 #include "Git.h"
26 #include "ShellUpdater.h"
28 bool DropCopyCommand::Execute()
30 CString sDroppath = parser.GetVal(L"droptarget");
31 if (CTGitPath(sDroppath).IsAdminDir())
33 MessageBox(hwndExplorer, L"Can't drop to .git repository directory\n", L"TortoiseGit", MB_OK | MB_ICONERROR);
34 return FALSE;
36 unsigned long count = 0;
38 CString sNewName;
39 pathList.RemoveAdminPaths();
40 if (parser.HasKey(L"rename") && pathList.GetCount() == 1)
42 // ask for a new name of the source item
43 CRenameDlg renDlg;
44 renDlg.SetInputValidator([&](const int /*nID*/, const CString& input) -> CString
46 if (PathFileExists(sDroppath + L'\\' + input))
47 return CString(CFormatMessageWrapper(ERROR_FILE_EXISTS));
49 return{};
50 });
51 renDlg.m_sBaseDir = sDroppath;
52 renDlg.m_windowtitle.LoadString(IDS_PROC_COPYRENAME);
53 renDlg.m_name = pathList[0].GetFileOrDirectoryName();
54 if (renDlg.DoModal() != IDOK)
55 return FALSE;
56 sNewName = renDlg.m_name;
58 CSysProgressDlg progress;
59 progress.SetTitle(IDS_PROC_COPYING);
60 progress.SetAnimation(IDR_MOVEANI);
61 progress.SetTime(true);
62 progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
63 for (int nPath = 0; nPath < pathList.GetCount(); ++nPath)
65 const CTGitPath& sourcePath = orgPathList[nPath];
67 CTGitPath fullDropPath(sDroppath);
69 if (sNewName.IsEmpty())
70 fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
71 else
72 fullDropPath.AppendPathString(sNewName);
74 // Check for a drop-on-to-ourselves
75 if (sourcePath.IsEquivalentTo(fullDropPath))
77 // Offer a rename
78 progress.Stop();
79 CRenameDlg dlg;
80 dlg.SetInputValidator([&](const int /*nID*/, const CString& input) -> CString
82 CTGitPath newPath(sDroppath);
83 newPath.AppendPathString(input);
84 if (newPath.Exists())
85 return CString(CFormatMessageWrapper(ERROR_FILE_EXISTS));
87 return{};
88 });
89 dlg.m_sBaseDir = fullDropPath.GetContainingDirectory().GetWinPathString();
90 dlg.m_name = fullDropPath.GetFileOrDirectoryName();
91 dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
92 if (dlg.DoModal() != IDOK)
93 return FALSE;
94 // rebuild the progress dialog
95 progress.EnsureValid();
96 progress.SetTitle(IDS_PROC_COPYING);
97 progress.SetAnimation(IDR_MOVEANI);
98 progress.SetTime(true);
99 progress.SetProgress(count, pathList.GetCount());
100 progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
101 // Rebuild the destination path, with the new name
102 fullDropPath.SetFromUnknown(sDroppath);
103 fullDropPath.AppendPathString(dlg.m_name);
106 if( CopyFile( sourcePath.GetWinPath(), fullDropPath.GetWinPath(), true))
108 CString ProjectTopDir;
109 if(fullDropPath.HasAdminDir(&ProjectTopDir))
111 g_Git.SetCurrentDir(ProjectTopDir);
112 SetCurrentDirectory(ProjectTopDir);
113 CString cmd;
114 cmd = L"git.exe add -- \"";
116 CString path;
117 path=fullDropPath.GetGitPathString().Mid(ProjectTopDir.GetLength());
118 if (!path.IsEmpty() && (path[0] == L'\\' || path[0] == L'/'))
119 path = path.Mid(1);
120 cmd += path;
121 cmd += L'"';
123 CString output;
124 if (g_Git.Run(cmd, &output, CP_UTF8))
125 MessageBox(hwndExplorer, output, L"TortoiseGit", MB_OK | MB_ICONERROR);
126 else
127 CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
130 }else
132 CString str;
133 str += L"Copy from \"";
134 str+=sourcePath.GetWinPath();
135 str += L"\" to \"";
136 str += fullDropPath.GetWinPath();
137 str += L"\" failed:\n";
138 str += CFormatMessageWrapper();
140 MessageBox(hwndExplorer, str, L"TortoiseGit", MB_OK | MB_ICONERROR);
143 ++count;
144 if (progress.IsValid())
146 progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
147 progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
148 progress.SetProgress(count, pathList.GetCount());
150 if ((progress.IsValid())&&(progress.HasUserCancelled()))
152 CMessageBox::Show(hwndExplorer, IDS_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
153 return false;
157 return true;