bool RenameCommand::Execute()
{
	bool bRet = true;
	CString filename = cmdLinePath.GetFileOrDirectoryName();
	CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString();

	// show the rename dialog until the user either cancels or enters a new
	// name (one that's different to the original name
	CString sNewName;
	do
	{
		CRenameDlg dlg;
		dlg.m_name = filename;
		if (dlg.DoModal() != IDOK)
			return FALSE;
		sNewName = dlg.m_name;
	} while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));

	if(!basePath.IsEmpty())
		sNewName=basePath+"/"+sNewName;

	CString force;
	// if the filenames only differ in case, we have to pass "-f"
	if (sNewName.CompareNoCase(cmdLinePath.GetGitPathString()) == 0)
		force = _T("-f ");

	CString cmd;
	CString output;
	cmd.Format(_T("git.exe mv %s-- \"%s\" \"%s\""),
					force,
					cmdLinePath.GetGitPathString(),
					sNewName);

	if (g_Git.Run(cmd, &output, CP_UTF8))
	{
		CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);
		bRet = false;
	}

	CTGitPath newpath;
	newpath.SetFromGit(sNewName);

	CShellUpdater::Instance().AddPathForUpdate(newpath);
	CShellUpdater::Instance().Flush();
	return bRet;
}
Exemple #2
0
/*************
 * DESCRIPTION:	Rename current material
 * INPUT:			-
 * OUTPUT:			-
 *************/
void CMatView::OnRename()
{
    CRenameDlg dialog;
    CMaterial *pMat;

    if (nSelectedMaterial == -1)
        return;

    pMat = ((CMaterial*)aMaterials[nSelectedMaterial]);
    dialog.m_sName = pMat->pSurface->name;
    if (dialog.DoModal() == IDOK)
    {
        pMat->pSurface->SetName((char*)LPCTSTR(dialog.m_sName));
        pMat->Update();
        Invalidate(FALSE);
    }
}
Exemple #3
0
bool CReportDlg::RenameItem(int nItem)
{
	// Find the operation corresponding to this item.
	int nOperationIndex = (int) m_ctlReportList.GetItemData(nItem);

	// Show a message when the file doesn't exist.
	if (m_renamingList.GetOperationProblem(nOperationIndex).nErrorCode == CRenamingList::errFileMissing)
	{
		AfxMessageBox(IDS_CANNOT_RENAME_MISSING, MB_ICONINFORMATION);
		return false;
	}

	// Show renaming dialog
	CRenameDlg	ren;

	CPath fnOriginalFileName = m_renamingList[nOperationIndex].GetPathBefore();
	ren.SetOriginalFileName( fnOriginalFileName.GetFileName() );

	CPath pathAfter = m_renamingList[nOperationIndex].GetPathAfter();
	ren.SetNewFileName( pathAfter.GetFileName() );

	ASSERT(fnOriginalFileName.GetDirectoryName() == pathAfter.GetDirectoryName());
	CString strBaseFolder = fnOriginalFileName.GetDirectoryName();

	if (ren.DoModal() == IDOK)
	{
		// Change file name.
		CRenamingList::CRenamingOperation roRenamingOperation = m_renamingList[nOperationIndex];
		roRenamingOperation.SetPathAfter(strBaseFolder + ren.GetNewFileName());
		m_renamingList.SetRenamingOperation(nOperationIndex, roRenamingOperation);
		m_ctlReportList.SetItemText(nItem, 1, roRenamingOperation.GetPathAfter().GetDisplayPath());

		// Clear the error message.
		m_ctlReportList.SetItem(nItem, 0, LVIF_IMAGE, NULL, -1, 0, 0, NULL);
		m_ctlReportList.SetItemText(nItem, 2, _T(""));
		return true;
	}
	else
		return false;
}
bool DropCopyCommand::Execute()
{

    CString sDroppath = parser.GetVal(_T("droptarget"));
    if (CTGitPath(sDroppath).IsAdminDir())
    {
        CMessageBox::Show(NULL,_T("Can't drop to .git repository directory\n"),
                          _T("TortoiseGit"),MB_OK|MB_ICONERROR);
        return FALSE;
    }
    unsigned long count = 0;

    CString sNewName;
    pathList.RemoveAdminPaths();
    if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1))
    {
        // ask for a new name of the source item
        do
        {
            CRenameDlg renDlg;
            renDlg.m_windowtitle.LoadString(IDS_PROC_COPYRENAME);
            renDlg.m_name = pathList[0].GetFileOrDirectoryName();
            if (renDlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            sNewName = renDlg.m_name;
        } while(sNewName.IsEmpty() || PathFileExists(sDroppath+_T("\\")+sNewName));
    }
    CSysProgressDlg progress;
    progress.SetTitle(IDS_PROC_COPYING);
    progress.SetAnimation(IDR_MOVEANI);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
    for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        const CTGitPath& sourcePath = orgPathList[nPath];

        CTGitPath fullDropPath(sDroppath);

        if (sNewName.IsEmpty())
            fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
        else
            fullDropPath.AppendPathString(sNewName);

        // Check for a drop-on-to-ourselves
        if (sourcePath.IsEquivalentTo(fullDropPath))
        {
            // Offer a rename
            progress.Stop();
            CRenameDlg dlg;
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            // rebuild the progress dialog
            progress.EnsureValid();
            progress.SetTitle(IDS_PROC_COPYING);
            progress.SetAnimation(IDR_MOVEANI);
            progress.SetTime(true);
            progress.SetProgress(count, pathList.GetCount());
            progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
            // Rebuild the destination path, with the new name
            fullDropPath.SetFromUnknown(sDroppath);
            fullDropPath.AppendPathString(dlg.m_name);
        }

        if( CopyFile( sourcePath.GetWinPath(), fullDropPath.GetWinPath(), true))
        {
            CString ProjectTopDir;
            if(fullDropPath.HasAdminDir(&ProjectTopDir))
            {
                g_Git.SetCurrentDir(ProjectTopDir);
                SetCurrentDirectory(ProjectTopDir);
                CString cmd;
                cmd = _T("git.exe add \"");

                CString path;
                path=fullDropPath.GetGitPathString().Mid(ProjectTopDir.GetLength());
                if(path.GetLength()>0)
                    if(path[0]==_T('\\') || path[0]==_T('/'))
                        path=path.Mid(1);
                cmd += path;
                cmd +=_T('\"');

                CString output;
                if (g_Git.Run(cmd, &output, CP_UTF8))
                {
                    CMessageBox::Show(NULL, output, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
                } else
                    CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
            }

        } else
        {
            CString str;
            str+=_T("Copy file fail:");
            str+=sourcePath.GetWinPath();

            CMessageBox::Show(NULL, str, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
        }

        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
            return false;
        }
    }

    return true;
}
Exemple #5
0
bool PasteCopyCommand::Execute()
{
    CString sDroppath = parser.GetVal(_T("droptarget"));
    CTGitPath dropPath(sDroppath);
    ProjectProperties props;
    props.ReadProps(dropPath);
    if (dropPath.IsAdminDir())
        return FALSE;

    if(!dropPath.HasAdminDir(&g_Git.m_CurrentDir))
        return FALSE;
    //SVN svn;
    //SVNStatus status;
    unsigned long count = 0;
    CString sNewName;
    orgPathList.RemoveAdminPaths();
    CSysProgressDlg progress;
    progress.SetTitle(IDS_PROC_COPYING);
    progress.SetAnimation(IDR_MOVEANI);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
    for(int nPath = 0; nPath < orgPathList.GetCount(); nPath++)
    {
        const CTGitPath& sourcePath = orgPathList[nPath];

        CTGitPath fullDropPath = dropPath;
        if (sNewName.IsEmpty())
            fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
        else
            fullDropPath.AppendPathString(sNewName);

        // Check for a drop-on-to-ourselves
        if (sourcePath.IsEquivalentTo(fullDropPath))
        {
            // Offer a rename
            progress.Stop();
            CRenameDlg dlg;
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            // rebuild the progress dialog
            progress.EnsureValid();
            progress.SetTitle(IDS_PROC_COPYING);
            progress.SetAnimation(IDR_MOVEANI);
            progress.SetTime(true);
            progress.SetProgress(count, orgPathList.GetCount());
            progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
            // Rebuild the destination path, with the new name
            fullDropPath.SetFromUnknown(sDroppath);
            fullDropPath.AppendPathString(dlg.m_name);
        }

        //svn_wc_status_kind s = status.GetAllStatus(sourcePath);
        //if ((s == svn_wc_status_none)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_ignored))
        {
            // source file is unversioned: move the file to the target, then add it
            CopyFile(sourcePath.GetWinPath(), fullDropPath.GetWinPath(), FALSE);
            CString cmd,output;
            cmd.Format(_T("git.exe add \"%s\""),fullDropPath.GetWinPath());
            if( g_Git.Run(cmd,&output,CP_ACP))
            {
                TRACE(_T("%s\n"), (LPCTSTR)output);
                CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
                return FALSE;		//get out of here
            }
            else
                CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
        }
        //else
        //{
        //	if (!svn.Copy(CTSVNPathList(sourcePath), fullDropPath, SVNRev::REV_WC, SVNRev()))
        //	{
        //		TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
        //		CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
        //		return FALSE;		//get out of here
        //	}
        //	else
        //		CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
        //}
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
            progress.SetProgress(count, orgPathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
            return false;
        }
    }
    return true;
}
Exemple #6
0
bool DropMoveCommand::Execute()
{
	CString droppath = parser.GetVal(_T("droptarget"));
	CString ProjectTop;
	if (!CTGitPath(droppath).HasAdminDir(&ProjectTop))
		return FALSE;
	
	if (ProjectTop != g_Git.m_CurrentDir )
	{
		CMessageBox::Show(NULL,_T("Target and source must be the same git repository"),_T("TortoiseGit"),MB_OK);
		return FALSE;
	}

	droppath = droppath.Right(droppath.GetLength()-ProjectTop.GetLength()-1);

	unsigned long count = 0;
	pathList.RemoveAdminPaths();
	CString sNewName;

	if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1))
	{
		// ask for a new name of the source item
		do 
		{
			CRenameDlg renDlg;
			renDlg.m_windowtitle.LoadString(IDS_PROC_MOVERENAME);
			renDlg.m_name = pathList[0].GetFileOrDirectoryName();
			if (renDlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			sNewName = renDlg.m_name;
		} while(sNewName.IsEmpty() || PathFileExists(droppath+_T("\\")+sNewName));
	}
	CSysProgressDlg progress;
	if (progress.IsValid())
	{
		progress.SetTitle(IDS_PROC_MOVING);
		progress.SetAnimation(IDR_MOVEANI);
		progress.SetTime(true);
		progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
	}
	for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
	{
		CTGitPath destPath;
		if (sNewName.IsEmpty())
			destPath = CTGitPath(droppath+_T("\\")+pathList[nPath].GetFileOrDirectoryName());
		else
			destPath = CTGitPath(droppath+_T("\\")+sNewName);
		if (destPath.Exists())
		{
			CString name = pathList[nPath].GetFileOrDirectoryName();
			if (!sNewName.IsEmpty())
				name = sNewName;
			progress.Stop();
			CRenameDlg dlg;
			dlg.m_name = name;
			dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
			if (dlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			destPath.SetFromWin(droppath+_T("\\")+dlg.m_name);
		} 
		CString cmd,out;
		
		cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""),pathList[nPath].GetGitPathString(),destPath.GetGitPathString());
		if(g_Git.Run(cmd,&out,CP_ACP))
		{
			if (CMessageBox::Show(hwndExplorer, out, _T("TortoiseGit"), MB_YESNO)==IDYES)
			{
#if 0
					if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath, TRUE))
					{
						CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
						return FALSE;		//get out of here
					}
					CShellUpdater::Instance().AddPathForUpdate(destPath);
#endif
			}
			else
			{
				//TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
				CMessageBox::Show(hwndExplorer, _T("Cancel"), _T("TortoiseGit"), MB_ICONERROR);
				return FALSE;		//get out of here
			}
		} 
		else
			CShellUpdater::Instance().AddPathForUpdate(destPath);
		count++;
		if (progress.IsValid())
		{
			progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath());
			progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
			progress.SetProgress(count, pathList.GetCount());
		}
		if ((progress.IsValid())&&(progress.HasUserCancelled()))
		{
			CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
			return FALSE;
		}
	}
	return true;
}
Exemple #7
0
bool DropMoveCommand::Execute()
{
    CString droppath = parser.GetVal(_T("droptarget"));
    if (CTSVNPath(droppath).IsAdminDir())
        return FALSE;
    SVN svn;
    unsigned long count = 0;
    pathList.RemoveAdminPaths();
    CString sNewName;
    if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1))
    {
        // ask for a new name of the source item
        CRenameDlg renDlg;
        renDlg.SetInputValidator(this);
        renDlg.m_windowtitle.LoadString(IDS_PROC_MOVERENAME);
        renDlg.m_name = pathList[0].GetFileOrDirectoryName();
        if (renDlg.DoModal() != IDOK)
        {
            return FALSE;
        }
        sNewName = renDlg.m_name;
    }
    CProgressDlg progress;
    if (progress.IsValid())
    {
        progress.SetTitle(IDS_PROC_MOVING);
        progress.SetAnimation(IDR_MOVEANI);
        progress.SetTime(true);
        progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
    }
    UINT msgRet = IDNO;
    for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        CTSVNPath destPath;
        if (sNewName.IsEmpty())
            destPath = CTSVNPath(droppath+_T("\\")+pathList[nPath].GetFileOrDirectoryName());
        else
            destPath = CTSVNPath(droppath+_T("\\")+sNewName);
        // path the same but case-changed is ok: results in a case-rename
        if (!(pathList[nPath].IsEquivalentToWithoutCase(destPath) && !pathList[nPath].IsEquivalentTo(destPath)))
        {
            if (destPath.Exists())
            {
                CString name = pathList[nPath].GetFileOrDirectoryName();
                if (!sNewName.IsEmpty())
                    name = sNewName;
                progress.Stop();
                CRenameDlg dlg;
                dlg.SetInputValidator(this);
                dlg.m_name = name;
                dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
                if (dlg.DoModal() != IDOK)
                {
                    return FALSE;
                }
                destPath.SetFromWin(droppath+_T("\\")+dlg.m_name);
            }
        }
        if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath))
        {
            if ((svn.GetSVNError() && svn.GetSVNError()->apr_err == SVN_ERR_ENTRY_EXISTS) && (destPath.Exists()))
            {
                if ((msgRet != IDYESTOALL) && (msgRet != IDNOTOALL))
                {
                    // target file already exists. Ask user if he wants to replace the file
                    CString sReplace;
                    sReplace.Format(IDS_PROC_REPLACEEXISTING, destPath.GetWinPath());
                    if (CTaskDialog::IsSupported())
                    {
                        CTaskDialog taskdlg(sReplace,
                                            CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK2)),
                                            L"TortoiseSVN",
                                            0,
                                            TDF_USE_COMMAND_LINKS|TDF_ALLOW_DIALOG_CANCELLATION|TDF_POSITION_RELATIVE_TO_WINDOW);
                        taskdlg.AddCommandControl(1, CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK3)));
                        taskdlg.AddCommandControl(2, CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK4)));
                        taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
                        taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK5)));
                        taskdlg.SetVerificationCheckbox(false);
                        taskdlg.SetDefaultCommandControl(2);
                        taskdlg.SetMainIcon(TD_WARNING_ICON);
                        INT_PTR ret = taskdlg.DoModal(GetExplorerHWND());
                        if (ret == 1) // replace
                            msgRet = taskdlg.GetVerificationCheckboxState() ? IDYES : IDYESTOALL;
                        else
                            msgRet = taskdlg.GetVerificationCheckboxState() ? IDNO : IDNOTOALL;
                    }
                    else
                    {
                        msgRet = TSVNMessageBox(GetExplorerHWND(), sReplace, _T("TortoiseSVN"), MB_ICONQUESTION|MB_YESNO|MB_YESTOALL|MB_NOTOALL);
                    }
                }

                if ((msgRet == IDYES) || (msgRet == IDYESTOALL))
                {
                    if (!svn.Remove(CTSVNPathList(destPath), true, false))
                    {
                        destPath.Delete(true);
                    }
                    if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath))
                    {
                        svn.ShowErrorDialog(GetExplorerHWND(), pathList[nPath]);
                        return FALSE;       //get out of here
                    }
                    CShellUpdater::Instance().AddPathForUpdate(destPath);
                }
            }
            else
            {
                svn.ShowErrorDialog(GetExplorerHWND(), pathList[nPath]);
                return FALSE;       //get out of here
            }
        }
        else
            CShellUpdater::Instance().AddPathForUpdate(destPath);
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            TSVNMessageBox(GetExplorerHWND(), IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
            return FALSE;
        }
    }
    return true;
}
bool PasteMoveCommand::Execute()
{
	CString sDroppath = parser.GetVal(_T("droptarget"));
	CTGitPath dropPath(sDroppath);
	if (dropPath.IsAdminDir())
		return FALSE;

	if(!dropPath.HasAdminDir(&g_Git.m_CurrentDir))
		return FALSE;

	GitStatus status;
	unsigned long count = 0;
	orgPathList.RemoveAdminPaths();
	CString sNewName;
	CSysProgressDlg progress;
	progress.SetTitle(IDS_PROC_MOVING);
	progress.SetAnimation(IDR_MOVEANI);
	progress.SetTime(true);
	progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
	for (int nPath = 0; nPath < orgPathList.GetCount(); ++nPath)
	{
		CTGitPath destPath;
		if (sNewName.IsEmpty())
			destPath = CTGitPath(sDroppath+_T("\\")+orgPathList[nPath].GetFileOrDirectoryName());
		else
			destPath = CTGitPath(sDroppath+_T("\\")+sNewName);
		if (destPath.Exists())
		{
			CString name = orgPathList[nPath].GetFileOrDirectoryName();
			if (!sNewName.IsEmpty())
				name = sNewName;
			progress.Stop();
			CRenameDlg dlg;
			dlg.m_name = name;
			dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
			if (dlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			destPath.SetFromWin(sDroppath+_T("\\")+dlg.m_name);
		}
		CString top;
		top.Empty();
		orgPathList[nPath].HasAdminDir(&top);
		git_wc_status_kind s = status.GetAllStatus(orgPathList[nPath]);
		if ((s == git_wc_status_none)||(s == git_wc_status_unversioned)||(s == git_wc_status_ignored)||top != g_Git.m_CurrentDir)
		{
			// source file is unversioned: move the file to the target, then add it
			MoveFile(orgPathList[nPath].GetWinPath(), destPath.GetWinPath());
			CString cmd,output;
			cmd.Format(_T("git.exe add -- \"%s\""),destPath.GetWinPath());
			if (g_Git.Run(cmd, &output, CP_UTF8))
			//if (!Git.Add(CTGitorgPathList(destPath), &props, Git_depth_infinity, true, false, true))
			{
				TRACE(_T("%s\n"), output);
				CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
				return FALSE;		//get out of here
			}
			CShellUpdater::Instance().AddPathForUpdate(destPath);
		}
		else
		{
			CString cmd,output;
			cmd.Format(_T("git.exe mv \"%s\" \"%s\""),orgPathList[nPath].GetGitPathString(),destPath.GetGitPathString());
			if (g_Git.Run(cmd, &output, CP_UTF8))
			//if (!Git.Move(CTGitorgPathList(orgPathList[nPath]), destPath, FALSE))
			{
#if 0
				if (Git.Err && (Git.Err->apr_err == Git_ERR_UNVERSIONED_RESOURCE ||
					Git.Err->apr_err == Git_ERR_CLIENT_MODIFIED))
				{
					// file/folder seems to have local modifications. Ask the user if
					// a force is requested.
					CString temp = Git.GetLastErrorMessage();
					CString sQuestion(MAKEINTRESOURCE(IDS_PROC_FORCEMOVE));
					temp += _T("\n") + sQuestion;
					if (CMessageBox::Show(hwndExplorer, temp, _T("TortoiseGit"), MB_YESNO)==IDYES)
					{
						if (!Git.Move(CTGitPathList(pathList[nPath]), destPath, TRUE))
						{
							CMessageBox::Show(hwndExplorer, Git.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
							return FALSE;		//get out of here
						}
						CShellUpdater::Instance().AddPathForUpdate(destPath);
					}
				}
				else
#endif
				{
					TRACE(_T("%s\n"), (LPCTSTR)output);
					CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
					return FALSE;		//get out of here
				}
			}
			else
				CShellUpdater::Instance().AddPathForUpdate(destPath);
		}
		++count;
		if (progress.IsValid())
		{
			progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, orgPathList[nPath].GetWinPath());
			progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
			progress.SetProgress(count, orgPathList.GetCount());
		}
		if ((progress.IsValid())&&(progress.HasUserCancelled()))
		{
			CMessageBox::Show(hwndExplorer, IDS_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
			return FALSE;
		}
	}
	return true;
}
bool PasteMoveCommand::Execute()
{
    CString sDroppath = parser.GetVal(L"droptarget");
    CTSVNPath dropPath(sDroppath);
    ProjectProperties props;
    props.ReadProps(dropPath);
    if (dropPath.IsAdminDir())
        return FALSE;
    SVN svn;
    SVNStatus status;
    unsigned long count = 0;
    pathList.RemoveAdminPaths();
    CString sNewName;
    CProgressDlg progress;
    progress.SetTitle(IDS_PROC_MOVING);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
    for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        CTSVNPath destPath;
        if (sNewName.IsEmpty())
            destPath = CTSVNPath(sDroppath+L"\\"+pathList[nPath].GetFileOrDirectoryName());
        else
            destPath = CTSVNPath(sDroppath+L"\\"+sNewName);
        if (destPath.Exists())
        {
            CString name = pathList[nPath].GetFileOrDirectoryName();
            if (!sNewName.IsEmpty())
                name = sNewName;
            progress.Stop();
            CRenameDlg dlg;
            dlg.SetFileSystemAutoComplete();
            dlg.m_name = name;
            dlg.SetInputValidator(this);
            m_renPath = pathList[nPath];
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            destPath.SetFromWin(sDroppath+L"\\"+dlg.m_name);
        }
        svn_wc_status_kind s = status.GetAllStatus(pathList[nPath]);
        if ((s == svn_wc_status_none)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_ignored))
        {
            // source file is unversioned: move the file to the target, then add it
            MoveFile(pathList[nPath].GetWinPath(), destPath.GetWinPath());
            if (!svn.Add(CTSVNPathList(destPath), &props, svn_depth_infinity, true, true, false, true))
            {
                svn.ShowErrorDialog(GetExplorerHWND());
                return FALSE;       //get out of here
            }
            CShellUpdater::Instance().AddPathForUpdate(destPath);
        }
        else
        {
            if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath))
            {
                svn.ShowErrorDialog(GetExplorerHWND());
                return FALSE;       //get out of here
            }
            else
                CShellUpdater::Instance().AddPathForUpdate(destPath);
        }
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            TaskDialog(GetExplorerHWND(), AfxGetResourceHandle(), MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(IDS_SVN_USERCANCELLED), NULL, TDCBF_OK_BUTTON, TD_INFORMATION_ICON, NULL);
            return FALSE;
        }
    }
    return true;
}
bool RenameCommand::Execute()
{
	bool bRet = false;
	CString filename = cmdLinePath.GetFileOrDirectoryName();
	CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString();
	//::SetCurrentDirectory(basePath);

	// show the rename dialog until the user either cancels or enters a new
	// name (one that's different to the original name
	CString sNewName;
	do
	{
		CRenameDlg dlg;
		dlg.m_name = filename;
		if (dlg.DoModal() != IDOK)
			return FALSE;
		sNewName = dlg.m_name;
	} while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));

	if(!basePath.IsEmpty())
		sNewName=basePath+"/"+sNewName;

	CString cmd;
	CString output;
	cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""),
					cmdLinePath.GetGitPathString(),
					sNewName);

	if(g_Git.Run(cmd,&output,CP_ACP))
	{
		CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);
	}

	CTGitPath newpath;
	newpath.SetFromGit(sNewName);

	CShellUpdater::Instance().AddPathForUpdate(newpath);
#if 0
	TRACE(_T("rename file %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);
	CTSVNPath destinationPath(basePath);
	if (PathIsRelative(sNewName) && !PathIsURL(sNewName))
		destinationPath.AppendPathString(sNewName);
	else
		destinationPath.SetFromWin(sNewName);
	// check if a rename just with case is requested: that's not possible on windows file systems
	// and we have to show an error.
	if (cmdLinePath.GetWinPathString().CompareNoCase(destinationPath.GetWinPathString())==0)
	{
		//rename to the same file!
		CString sHelpPath = theApp.m_pszHelpFilePath;
		sHelpPath += _T("::/tsvn-dug-rename.html#tsvn-dug-renameincase");
		CMessageBox::Show(hwndExplorer, IDS_PROC_CASERENAME, IDS_APPNAME, MB_OK|MB_HELP, sHelpPath);
	}
	else
	{
		CString sMsg;
		if (SVN::PathIsURL(cmdLinePath))
		{
			// rename an URL.
			// Ask for a commit message, then rename directly in
			// the repository
			CInputLogDlg input;
			CString sUUID;
			SVN svn;
			svn.GetRepositoryRootAndUUID(cmdLinePath, sUUID);
			input.SetUUID(sUUID);
			CString sHint;
			sHint.Format(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());
			input.SetActionText(sHint);
			if (input.DoModal() == IDOK)
			{
				sMsg = input.GetLogMessage();
			}
			else
			{
				return FALSE;
			}
		}
		if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))
		{
			// renaming a directory can take a while: use the
			// progress dialog to show the progress of the renaming
			// operation.
			CSVNProgressDlg progDlg;
			progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);
			if (parser.HasVal(_T("closeonend")))
				progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));
			progDlg.SetPathList(pathList);
			progDlg.SetUrl(destinationPath.GetWinPathString());
			progDlg.SetCommitMessage(sMsg);
			progDlg.SetRevision(SVNRev::REV_WC);
			progDlg.DoModal();
			bRet = !progDlg.DidErrorsOccur();
		}
		else
		{
			SVN svn;
			CString sFilemask = cmdLinePath.GetFilename();
			if (sFilemask.ReverseFind('.')>=0)
			{
				sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));
			}
			else
				sFilemask.Empty();
			CString sNewMask = sNewName;
			if (sNewMask.ReverseFind('.'>=0))
			{
				sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));
			}
			else
				sNewMask.Empty();

			if (((!sFilemask.IsEmpty()) && (parser.HasKey(_T("noquestion")))) ||
				(cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0))
			{
				if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
				{
					TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
					CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
				}
				else
					bRet = true;
			}
			else
			{
				// when refactoring, multiple files have to be renamed
				// at once because those files belong together.
				// e.g. file.aspx, file.aspx.cs, file.aspx.resx
				CTSVNPathList renlist;
				CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+_T(".*"));
				while (filefind.FindNextFileNoDots())
				{
					if (!filefind.IsDirectory())
						renlist.AddPath(CTSVNPath(filefind.GetFilePath()));
				}
				if (renlist.GetCount()<=1)
				{
					// we couldn't find any other matching files
					// just do the default...
					if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
					{
						TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
						CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
					}
					else
					{
						bRet = true;
						CShellUpdater::Instance().AddPathForUpdate(destinationPath);
					}
				}
				else
				{
					std::map<CString, CString> renmap;
					CString sTemp;
					CString sRenList;
					for (int i=0; i<renlist.GetCount(); ++i)
					{
						CString sFilename = renlist[i].GetFilename();
						CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());
						sTemp.Format(_T("\n%s -> %s"), (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);
						if (!renlist[i].IsEquivalentTo(cmdLinePath))
							sRenList += sTemp;
						renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+_T("\\")+sNewFilename;
					}
					CString sRenameMultipleQuestion;
					sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);
					UINT idret = CMessageBox::Show(hwndExplorer, sRenameMultipleQuestion, _T("TortoiseGit"), MB_ICONQUESTION|MB_YESNOCANCEL);
					if (idret == IDYES)
					{
						CProgressDlg progress;
						progress.SetTitle(IDS_PROC_MOVING);
						progress.SetAnimation(IDR_MOVEANI);
						progress.SetTime(true);
						progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
						DWORD count = 1;
						for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)
						{
							progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);
							progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);
							progress.SetProgress(count, renmap.size());
							if (!svn.Move(CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), TRUE, sMsg))
							{
								if (svn.Err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
								{
									bRet = !!MoveFile(it->first, it->second);
								}
								else
								{
									TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
									CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
									bRet = false;
								}
							}
							else
							{
								bRet = true;
								CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));
							}
						}
						progress.Stop();
					}
					else if (idret == IDNO)
					{
						// no, user wants to just rename the file he selected
						if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
						{
							TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
							CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
						}
						else
						{
							bRet = true;
							CShellUpdater::Instance().AddPathForUpdate(destinationPath);
						}
					}
					else if (idret == IDCANCEL)
					{
						// nothing
					}
				}
			}
		}
	}
#endif
	CShellUpdater::Instance().Flush();
	return bRet;
}
bool DropCopyCommand::Execute()
{
    CString sDroppath = parser.GetVal(L"droptarget");
    if (CTSVNPath(sDroppath).IsAdminDir())
        return FALSE;
    SVN svn;
    unsigned long count = 0;
    CString sNewName;
    pathList.RemoveAdminPaths();
    if ((parser.HasKey(L"rename"))&&(pathList.GetCount()==1))
    {
        // ask for a new name of the source item
        CRenameDlg renDlg;
        renDlg.SetInputValidator(this);
        renDlg.SetFileSystemAutoComplete();
        renDlg.m_windowtitle.LoadString(IDS_PROC_COPYRENAME);
        renDlg.m_name = pathList[0].GetFileOrDirectoryName();
        if (renDlg.DoModal() != IDOK)
        {
            return FALSE;
        }
        sNewName = renDlg.m_name;
    }
    CProgressDlg progress;
    progress.SetTitle(IDS_PROC_COPYING);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
    UINT msgRet = IDNO;
    INT_PTR msgRetNonversioned = 0;
    for (int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        const CTSVNPath& sourcePath = pathList[nPath];

        CTSVNPath fullDropPath(sDroppath);
        if (sNewName.IsEmpty())
            fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
        else
            fullDropPath.AppendPathString(sNewName);

        // Check for a drop-on-to-ourselves
        if (sourcePath.IsEquivalentTo(fullDropPath))
        {
            // Offer a rename
            progress.Stop();
            CRenameDlg dlg;
            dlg.SetFileSystemAutoComplete();
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            // rebuild the progress dialog
            progress.EnsureValid();
            progress.SetTitle(IDS_PROC_COPYING);
            progress.SetTime(true);
            progress.SetProgress(count, pathList.GetCount());
            progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
            // Rebuild the destination path, with the new name
            fullDropPath.SetFromUnknown(sDroppath);
            fullDropPath.AppendPathString(dlg.m_name);
        }
        if (!svn.Copy(CTSVNPathList(sourcePath), fullDropPath, SVNRev::REV_WC, SVNRev()))
        {
            if ((svn.GetSVNError() && svn.GetSVNError()->apr_err == SVN_ERR_ENTRY_EXISTS) && (fullDropPath.Exists()))
            {
                if ((msgRet != IDYESTOALL) && (msgRet != IDNOTOALL))
                {
                    // target file already exists. Ask user if he wants to replace the file
                    CString sReplace;
                    sReplace.Format(IDS_PROC_REPLACEEXISTING, fullDropPath.GetWinPath());
                    CTaskDialog taskdlg(sReplace,
                                        CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK2)),
                                        L"TortoiseSVN",
                                        0,
                                        TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
                    taskdlg.AddCommandControl(1, CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK3)));
                    taskdlg.AddCommandControl(2, CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK4)));
                    taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
                    taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK5)));
                    taskdlg.SetVerificationCheckbox(false);
                    taskdlg.SetDefaultCommandControl(2);
                    taskdlg.SetMainIcon(TD_WARNING_ICON);
                    INT_PTR ret = taskdlg.DoModal(GetExplorerHWND());
                    if (ret == 1) // replace
                        msgRet = taskdlg.GetVerificationCheckboxState() ? IDYES : IDYESTOALL;
                    else
                        msgRet = taskdlg.GetVerificationCheckboxState() ? IDNO : IDNOTOALL;
                }

                if ((msgRet == IDYES) || (msgRet == IDYESTOALL))
                {
                    if (!svn.Remove(CTSVNPathList(fullDropPath), true, false))
                    {
                        fullDropPath.Delete(true);
                    }
                    if (!svn.Copy(CTSVNPathList(pathList[nPath]), fullDropPath, SVNRev::REV_WC, SVNRev()))
                    {
                        svn.ShowErrorDialog(GetExplorerHWND(), pathList[nPath]);
                        return FALSE;       //get out of here
                    }
                }
            }
            else
            {
                svn.ShowErrorDialog(GetExplorerHWND(), sourcePath);
                return FALSE;       //get out of here
            }
        }
        else if (svn.GetSVNError() && svn.GetSVNError()->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
        {
            INT_PTR ret = 0;
            if (msgRetNonversioned == 0)
            {
                CString sReplace;
                sReplace.Format(IDS_PROC_MOVEUNVERSIONED_TASK1, fullDropPath.GetWinPath());
                CTaskDialog taskdlg(sReplace,
                                    CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK2)),
                                    L"TortoiseSVN",
                                    TDCBF_CANCEL_BUTTON,
                                    TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
                taskdlg.AddCommandControl(101, CString(MAKEINTRESOURCE(IDS_PROC_COPYUNVERSIONED_TASK3)));
                taskdlg.AddCommandControl(102, CString(MAKEINTRESOURCE(IDS_PROC_COPYUNVERSIONED_TASK4)));
                taskdlg.AddCommandControl(103, CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK5)));
                taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK6)));
                taskdlg.SetVerificationCheckbox(false);
                taskdlg.SetDefaultCommandControl(103);
                taskdlg.SetMainIcon(TD_WARNING_ICON);
                ret = taskdlg.DoModal(GetExplorerHWND());
                if (taskdlg.GetVerificationCheckboxState())
                    msgRetNonversioned = ret;
            }
            else
            {
                ret = msgRetNonversioned;
            }
            switch (ret)
            {
                case 101: // copy
                    CopyFile(pathList[nPath].GetWinPath(), fullDropPath.GetWinPath(), FALSE);
                    break;
                case 102: // copy and add
                    CopyFile(pathList[nPath].GetWinPath(), fullDropPath.GetWinPath(), FALSE);
                    if (!svn.Add(CTSVNPathList(fullDropPath), NULL, svn_depth_infinity, true, false, false, false))
                    {
                        svn.ShowErrorDialog(GetExplorerHWND(), fullDropPath);
                        return FALSE;       //get out of here
                    }
                    break;
                case 103: // skip
                default:
                    break;
            }
        }
        else
            CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            TaskDialog(GetExplorerHWND(), AfxGetResourceHandle(), MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(IDS_SVN_USERCANCELLED), NULL, TDCBF_OK_BUTTON, TD_INFORMATION_ICON, NULL);
            return false;
        }
    }
    return true;
}
Exemple #12
0
bool RenameCommand::Execute()
{
    bool bRet = false;
    CString filename = cmdLinePath.GetFileOrDirectoryName();
    CString basePath = cmdLinePath.GetContainingDirectory().GetWinPathString();
    ::SetCurrentDirectory(basePath);

    // show the rename dialog until the user either cancels or enters a new
    // name (one that's different to the original name
    CString sNewName;
    do
    {
        CRenameDlg dlg;
        dlg.m_name = filename;
        if (!SVN::PathIsURL(cmdLinePath))
            dlg.SetFileSystemAutoComplete();
        if (dlg.DoModal() != IDOK)
            return FALSE;
        sNewName = dlg.m_name;
    } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));

    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": rename file %s to %s\n", (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);
    CTSVNPath destinationPath(basePath);
    if (PathIsRelative(sNewName) && !PathIsURL(sNewName))
        destinationPath.AppendPathString(sNewName);
    else
        destinationPath.SetFromWin(sNewName);
    CString sMsg;
    if (SVN::PathIsURL(cmdLinePath))
    {
        // rename an URL.
        // Ask for a commit message, then rename directly in
        // the repository
        CInputLogDlg input;
        CString sUUID;
        SVN svn;
        svn.GetRepositoryRootAndUUID(cmdLinePath, true, sUUID);
        input.SetUUID(sUUID);
        CString sHint;
        sHint.FormatMessage(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());
        input.SetActionText(sHint);
        if (input.DoModal() == IDOK)
        {
            sMsg = input.GetLogMessage();
        }
        else
        {
            return FALSE;
        }
    }
    if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))
    {
        // renaming a directory can take a while: use the
        // progress dialog to show the progress of the renaming
        // operation.
        CSVNProgressDlg progDlg;
        progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);
        progDlg.SetAutoClose (parser);
        progDlg.SetPathList(pathList);
        progDlg.SetUrl(destinationPath.GetWinPathString());
        progDlg.SetCommitMessage(sMsg);
        progDlg.DoModal();
        bRet = !progDlg.DidErrorsOccur();
    }
    else
    {
        CString sFilemask = cmdLinePath.GetFilename();
        int slashpos = 0;
        // find out up to which char sFilemask and sNewName are identical
        int minlen = min(sFilemask.GetLength(), sNewName.GetLength());
        for (; slashpos < minlen; ++slashpos)
        {
            if (sFilemask[slashpos] != sNewName[slashpos])
                break;
        }

        if (sFilemask.ReverseFind('.') >= slashpos)
        {
            while (sFilemask.ReverseFind('.') >= slashpos)
                sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));
        }
        else
            sFilemask.Empty();
        CString sNewMask = sNewName;
        if (sNewMask.ReverseFind('.') >= slashpos)
        {
            while (sNewMask.ReverseFind('.') >= slashpos)
                sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));
        }
        else
            sNewMask.Empty();

        CString sRightPartNew = sNewName.Mid(sNewMask.GetLength());
        CString sRightPartOld = cmdLinePath.GetFilename().Mid(sFilemask.GetLength());

        // if the file extension changed, or the old and new right parts are not the
        // same then we can not correctly guess the new names of similar files, so
        // just do the plain rename of the selected file and don't offer to rename similar ones.
        if (((!sFilemask.IsEmpty()) && (parser.HasKey(L"noquestion"))) ||
            (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0) ||
            (sRightPartOld.CompareNoCase(sRightPartNew)))
        {
            if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg))
                bRet = true;
        }
        else
        {
            // when refactoring, multiple files have to be renamed
            // at once because those files belong together.
            // e.g. file.aspx, file.aspx.cs, file.aspx.resx
            CTSVNPathList renlist;
            CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+L".*");
            while (filefind.FindNextFileNoDots())
            {
                if (!filefind.IsDirectory())
                    renlist.AddPath(CTSVNPath(filefind.GetFilePath()));
            }
            if ((renlist.GetCount() <= 1) ||
                (renlist.GetCount() > 10))  // arbitrary value of ten
            {
                // Either no matching files to rename, or way too many of them:
                // just do the default...
                if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg))
                {
                    bRet = true;
                    CShellUpdater::Instance().AddPathForUpdate(destinationPath);
                }
            }
            else
            {
                std::map<CString, CString> renmap;
                CString sTemp;
                CString sRenList;
                for (int i=0; i<renlist.GetCount(); ++i)
                {
                    CString sFilename = renlist[i].GetFilename();
                    CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());
                    sTemp.Format(L"\n%s -> %s", (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);
                    if (!renlist[i].IsEquivalentTo(cmdLinePath))
                        sRenList += sTemp;
                    renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+L"\\"+sNewFilename;
                }
                CString sRenameMultipleQuestion;
                sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);
                UINT idret = ::MessageBox(GetExplorerHWND(), sRenameMultipleQuestion, L"TortoiseSVN", MB_ICONQUESTION|MB_YESNOCANCEL);
                if (idret == IDYES)
                {
                    CProgressDlg progress;
                    progress.SetTitle(IDS_PROC_MOVING);
                    progress.SetTime(true);
                    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
                    DWORD count = 1;
                    for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)
                    {
                        progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);
                        progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);
                        progress.SetProgress64(count, renmap.size());
                        if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), sMsg))
                        {
                            bRet = true;
                            CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));
                        }
                    }
                    progress.Stop();
                }
                else if (idret == IDNO)
                {
                    // no, user wants to just rename the file he selected
                    if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg))
                    {
                        bRet = true;
                        CShellUpdater::Instance().AddPathForUpdate(destinationPath);
                    }
                }
                else if (idret == IDCANCEL)
                {
                    // nothing
                }
            }
        }
    }
    return bRet;
}
bool DropMoveCommand::Execute()
{
    CString droppath = parser.GetVal(L"droptarget");
    if (CTSVNPath(droppath).IsAdminDir())
        return FALSE;
    SVN svn;
    unsigned long count = 0;
    pathList.RemoveAdminPaths();
    CString sNewName;
    if ((parser.HasKey(L"rename"))&&(pathList.GetCount()==1))
    {
        // ask for a new name of the source item
        CRenameDlg renDlg;
        renDlg.SetFileSystemAutoComplete();
        renDlg.SetInputValidator(this);
        renDlg.m_windowtitle.LoadString(IDS_PROC_MOVERENAME);
        renDlg.m_name = pathList[0].GetFileOrDirectoryName();
        if (renDlg.DoModal() != IDOK)
        {
            return FALSE;
        }
        sNewName = renDlg.m_name;
    }
    CProgressDlg progress;
    if (progress.IsValid())
    {
        progress.SetTitle(IDS_PROC_MOVING);
        progress.SetTime(true);
        progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
    }
    UINT msgRet = IDNO;
    INT_PTR msgRetNonversioned = 0;
    for (int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        CTSVNPath destPath;
        if (sNewName.IsEmpty())
            destPath = CTSVNPath(droppath+L"\\"+pathList[nPath].GetFileOrDirectoryName());
        else
            destPath = CTSVNPath(droppath+L"\\"+sNewName);
        // path the same but case-changed is ok: results in a case-rename
        if (!(pathList[nPath].IsEquivalentToWithoutCase(destPath) && !pathList[nPath].IsEquivalentTo(destPath)))
        {
            if (destPath.Exists())
            {
                progress.Stop();

                CString name = pathList[nPath].GetFileOrDirectoryName();
                if (!sNewName.IsEmpty())
                    name = sNewName;
                progress.Stop();
                CRenameDlg dlg;
                dlg.SetFileSystemAutoComplete();
                dlg.SetInputValidator(this);
                dlg.m_name = name;
                dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
                if (dlg.DoModal() != IDOK)
                {
                    return FALSE;
                }
                destPath.SetFromWin(droppath+L"\\"+dlg.m_name);

                progress.EnsureValid();
                progress.SetTitle(IDS_PROC_MOVING);
                progress.SetTime(true);
                progress.SetProgress(count, pathList.GetCount());
                progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
            }
        }
        if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath))
        {
            if ((svn.GetSVNError() && svn.GetSVNError()->apr_err == SVN_ERR_ENTRY_EXISTS) && (destPath.Exists()))
            {
                if ((msgRet != IDYESTOALL) && (msgRet != IDNOTOALL))
                {
                    progress.Stop();
                    // target file already exists. Ask user if he wants to replace the file
                    CString sReplace;
                    sReplace.Format(IDS_PROC_REPLACEEXISTING, destPath.GetWinPath());
                    CTaskDialog taskdlg(sReplace,
                                        CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK2)),
                                        L"TortoiseSVN",
                                        0,
                                        TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
                    taskdlg.AddCommandControl(1, CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK3)));
                    taskdlg.AddCommandControl(2, CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK4)));
                    taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
                    taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_REPLACEEXISTING_TASK5)));
                    taskdlg.SetVerificationCheckbox(false);
                    taskdlg.SetDefaultCommandControl(2);
                    taskdlg.SetMainIcon(TD_WARNING_ICON);
                    INT_PTR ret = taskdlg.DoModal(GetExplorerHWND());
                    if (ret == 1) // replace
                        msgRet = taskdlg.GetVerificationCheckboxState() ? IDYESTOALL : IDYES;
                    else
                        msgRet = taskdlg.GetVerificationCheckboxState() ? IDNOTOALL : IDNO;

                    progress.EnsureValid();
                    progress.SetTitle(IDS_PROC_MOVING);
                    progress.SetTime(true);
                    progress.SetProgress(count, pathList.GetCount());
                    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
                }

                if ((msgRet == IDYES) || (msgRet == IDYESTOALL))
                {
                    if (!svn.Remove(CTSVNPathList(destPath), true, false))
                    {
                        destPath.Delete(true);
                    }
                    if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath))
                    {
                        progress.Stop();
                        svn.ShowErrorDialog(GetExplorerHWND(), pathList[nPath]);
                        return FALSE;       //get out of here
                    }
                    CShellUpdater::Instance().AddPathForUpdate(destPath);
                }
            }
            else if (svn.GetSVNError() && svn.GetSVNError()->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
            {
                INT_PTR ret = 0;
                if (msgRetNonversioned == 0)
                {
                    progress.Stop();

                    CString sReplace;
                    sReplace.Format(IDS_PROC_MOVEUNVERSIONED_TASK1, destPath.GetWinPath());
                    CTaskDialog taskdlg(sReplace,
                                        CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK2)),
                                        L"TortoiseSVN",
                                        TDCBF_CANCEL_BUTTON,
                                        TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
                    taskdlg.AddCommandControl(101, CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK3)));
                    taskdlg.AddCommandControl(102, CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK4)));
                    taskdlg.AddCommandControl(103, CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK5)));
                    taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_MOVEUNVERSIONED_TASK6)));
                    taskdlg.SetVerificationCheckbox(false);
                    taskdlg.SetDefaultCommandControl(103);
                    taskdlg.SetMainIcon(TD_WARNING_ICON);
                    ret = taskdlg.DoModal(GetExplorerHWND());
                    if (taskdlg.GetVerificationCheckboxState())
                        msgRetNonversioned = ret;

                    progress.EnsureValid();
                    progress.SetTitle(IDS_PROC_MOVING);
                    progress.SetTime(true);
                    progress.SetProgress(count, pathList.GetCount());
                    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
                }
                else
                {
                    ret = msgRetNonversioned;
                }
                switch (ret)
                {
                    case 101: // move
                        MoveFile(pathList[nPath].GetWinPath(), destPath.GetWinPath());
                        break;
                    case 102: // move and add
                        MoveFile(pathList[nPath].GetWinPath(), destPath.GetWinPath());
                        if (!svn.Add(CTSVNPathList(destPath), NULL, svn_depth_infinity, true, false, false, false))
                        {
                            progress.Stop();
                            svn.ShowErrorDialog(GetExplorerHWND(), destPath);
                            return FALSE;       //get out of here
                        }
                        break;
                    case 103: // skip
                    default:
                        break;
                }
            }
            else
            {
                progress.Stop();
                svn.ShowErrorDialog(GetExplorerHWND(), pathList[nPath]);
                return FALSE;       //get out of here
            }
        }
        else
            CShellUpdater::Instance().AddPathForUpdate(destPath);
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            progress.Stop();
            TaskDialog(GetExplorerHWND(), AfxGetResourceHandle(), MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(IDS_SVN_USERCANCELLED), NULL, TDCBF_OK_BUTTON, TD_INFORMATION_ICON, NULL);
            return FALSE;
        }
    }
    return true;
}