示例#1
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;
}
示例#2
0
bool ExportCommand::Execute()
{
    bool bRet = false;
    // When the user clicked on a working copy, we know that the export should
    // be done from that. We then have to ask where the export should go to.
    // If however the user clicked on an unversioned folder, we assume that
    // this is where the export should go to and have to ask from where
    // the export should be done from.
    bool bURL = !!SVN::PathIsURL(cmdLinePath);
    svn_wc_status_kind s = SVNStatus::GetAllStatus(cmdLinePath);
    if ((bURL)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_none))
    {
        // ask from where the export has to be done
        CExportDlg dlg;
        if (bURL)
            dlg.m_URL = cmdLinePath.GetSVNPathString();
        else
            dlg.m_strExportDirectory = cmdLinePath.GetWinPathString();
        if (parser.HasKey(_T("revision")))
        {
            SVNRev Rev = SVNRev(parser.GetVal(_T("revision")));
            dlg.Revision = Rev;
        }
        dlg.m_blockPathAdjustments = parser.HasKey(L"blockpathadjustments");
        if (dlg.DoModal() == IDOK)
        {
            CTSVNPath exportPath(dlg.m_strExportDirectory);

            CSVNProgressDlg progDlg;
            theApp.m_pMainWnd = &progDlg;
            progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Export);
            progDlg.SetAutoClose (parser);
            DWORD options = dlg.m_bNoExternals ? ProgOptIgnoreExternals : ProgOptNone;
            options |= dlg.m_bNoKeywords ? ProgOptIgnoreKeywords : ProgOptNone;
            if (dlg.m_eolStyle.CompareNoCase(_T("CRLF"))==0)
                options |= ProgOptEolCRLF;
            if (dlg.m_eolStyle.CompareNoCase(_T("CR"))==0)
                options |= ProgOptEolCR;
            if (dlg.m_eolStyle.CompareNoCase(_T("LF"))==0)
                options |= ProgOptEolLF;
            progDlg.SetOptions(options);
            progDlg.SetPathList(CTSVNPathList(exportPath));
            progDlg.SetUrl(dlg.m_URL);
            progDlg.SetRevision(dlg.Revision);
            progDlg.SetDepth(dlg.m_depth);
            progDlg.DoModal();
            bRet = !progDlg.DidErrorsOccur();
        }
    }
    else
    {
        // ask where the export should go to.
        CBrowseFolder folderBrowser;
        CString strTemp;
        strTemp.LoadString(IDS_PROC_EXPORT_1);
        folderBrowser.SetInfo(strTemp);
        folderBrowser.m_style = BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_EDITBOX;
        strTemp.LoadString(IDS_PROC_EXPORT_2);
        folderBrowser.SetCheckBoxText(strTemp);
        strTemp.LoadString(IDS_PROC_OMMITEXTERNALS);
        folderBrowser.SetCheckBoxText2(strTemp);
        folderBrowser.DisableCheckBox2WhenCheckbox1IsEnabled(true);
        CRegDWORD regExtended = CRegDWORD(_T("Software\\TortoiseSVN\\ExportExtended"), FALSE);
        CBrowseFolder::m_bCheck = regExtended;
        TCHAR saveto[MAX_PATH];
        if (folderBrowser.Show(GetExplorerHWND(), saveto, _countof(saveto))==CBrowseFolder::OK)
        {
            CString saveplace = CString(saveto);

            if (cmdLinePath.IsEquivalentTo(CTSVNPath(saveplace)))
            {
                // exporting to itself:
                // remove all svn admin dirs, effectively unversion the 'exported' folder.
                CString msg;
                msg.Format(IDS_PROC_EXPORTUNVERSION, (LPCTSTR)saveplace);
                bool bUnversion = false;
                if (CTaskDialog::IsSupported())
                {
                    CTaskDialog taskdlg(msg,
                                        CString(MAKEINTRESOURCE(IDS_PROC_EXPORTUNVERSION_TASK2)),
                                        L"TortoiseSVN",
                                        0,
                                        TDF_ENABLE_HYPERLINKS|TDF_USE_COMMAND_LINKS|TDF_ALLOW_DIALOG_CANCELLATION|TDF_POSITION_RELATIVE_TO_WINDOW);
                    taskdlg.AddCommandControl(1, CString(MAKEINTRESOURCE(IDS_PROC_EXPORTUNVERSION_TASK3)));
                    taskdlg.AddCommandControl(2, CString(MAKEINTRESOURCE(IDS_PROC_EXPORTUNVERSION_TASK4)));
                    taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
                    taskdlg.SetDefaultCommandControl(1);
                    taskdlg.SetMainIcon(TD_WARNING_ICON);
                    bUnversion = (taskdlg.DoModal(GetExplorerHWND()) == 1);
                }
                else
                {
                    bUnversion = (MessageBox(GetExplorerHWND(), msg, _T("TortoiseSVN"), MB_ICONQUESTION|MB_YESNO) == IDYES);
                }

                if (bUnversion)
                {
                    CProgressDlg progress;
                    progress.SetTitle(IDS_PROC_UNVERSION);
                    progress.SetAnimation(IDR_MOVEANI);
                    progress.FormatNonPathLine(1, IDS_SVNPROGRESS_EXPORTINGWAIT);
                    progress.SetTime(true);
                    progress.ShowModeless(GetExplorerHWND());
                    std::vector<CTSVNPath> removeVector;

                    CDirFileEnum lister(saveplace);
                    CString srcFile;
                    bool bFolder = false;
                    while (lister.NextFile(srcFile, &bFolder))
                    {
                        CTSVNPath item(srcFile);
                        if ((bFolder)&&(g_SVNAdminDir.IsAdminDirName(item.GetFileOrDirectoryName())))
                        {
                            removeVector.push_back(item);
                        }
                    }
                    DWORD count = 0;
                    for (std::vector<CTSVNPath>::iterator it = removeVector.begin(); (it != removeVector.end()) && (!progress.HasUserCancelled()); ++it)
                    {
                        progress.FormatPathLine(1, IDS_SVNPROGRESS_UNVERSION, (LPCTSTR)it->GetWinPath());
                        progress.SetProgress64(count, removeVector.size());
                        count++;
                        it->Delete(false);
                    }
                    progress.Stop();
                    bRet = true;
                }
                else
                    return false;
            }
            else
            {
                CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": export %s to %s\n"), (LPCTSTR)cmdLinePath.GetUIPathString(), (LPCTSTR)saveto);
                SVN svn;
                if (!svn.Export(cmdLinePath, CTSVNPath(saveplace), SVNRev::REV_WC,
                    SVNRev::REV_WC, false, !!folderBrowser.m_bCheck2, false, svn_depth_infinity,
                    GetExplorerHWND(), folderBrowser.m_bCheck ? SVN::SVNExportIncludeUnversioned : SVN::SVNExportNormal))
                {
                    svn.ShowErrorDialog(GetExplorerHWND(), cmdLinePath);
                    bRet = false;
                }
                else
                    bRet = true;
                regExtended = CBrowseFolder::m_bCheck;
            }
        }
    }
    return bRet;
}
bool DropExportCommand::Execute()
{
    bool bRet = true;
    CString droppath = parser.GetVal(L"droptarget");
    if (CTSVNPath(droppath).IsAdminDir())
        return false;
    SVN::SVNExportType exportType = SVN::SVNExportNormal;
    if (parser.HasKey(L"extended"))
    {
        exportType = SVN::SVNExportIncludeUnversioned;
        CString et = parser.GetVal(L"extended");
        if (et == L"localchanges")
            exportType = SVN::SVNExportOnlyLocalChanges;
        if (et == L"unversioned")
            exportType = SVN::SVNExportIncludeUnversioned;
    }
    SVN svn;
    if ((pathList.GetCount() == 1)&&
        (pathList[0].IsEquivalentTo(CTSVNPath(droppath))))
    {
        // exporting to itself:
        // remove all svn admin dirs, effectively unversion the 'exported' folder.
        CString msg;
        msg.Format(IDS_PROC_EXPORTUNVERSION, (LPCTSTR)droppath);
        CTaskDialog taskdlg(msg,
                            CString(MAKEINTRESOURCE(IDS_PROC_EXPORTUNVERSION_TASK2)),
                            L"TortoiseSVN",
                            0,
                            TDF_ENABLE_HYPERLINKS | TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
        taskdlg.AddCommandControl(1, CString(MAKEINTRESOURCE(IDS_PROC_EXPORTUNVERSION_TASK3)));
        taskdlg.AddCommandControl(2, CString(MAKEINTRESOURCE(IDS_PROC_EXPORTUNVERSION_TASK4)));
        taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
        taskdlg.SetDefaultCommandControl(1);
        taskdlg.SetMainIcon(TD_WARNING_ICON);
        if (taskdlg.DoModal(GetExplorerHWND()) != 1)
            return false;

        CProgressDlg progress;
        progress.SetTitle(IDS_PROC_UNVERSION);
        progress.FormatNonPathLine(1, IDS_SVNPROGRESS_EXPORTINGWAIT);
        progress.SetTime(true);
        progress.ShowModeless(GetExplorerHWND());
        std::vector<CTSVNPath> removeVector;

        CDirFileEnum lister(droppath);
        CString srcFile;
        bool bFolder = false;
        while (lister.NextFile(srcFile, &bFolder))
        {
            CTSVNPath item(srcFile);
            if ((bFolder)&&(g_SVNAdminDir.IsAdminDirName(item.GetFileOrDirectoryName())))
            {
                removeVector.push_back(item);
            }
        }
        DWORD count = 0;
        for (std::vector<CTSVNPath>::iterator it = removeVector.begin(); (it != removeVector.end()) && (!progress.HasUserCancelled()); ++it)
        {
            progress.FormatPathLine(1, IDS_SVNPROGRESS_UNVERSION, (LPCTSTR)it->GetWinPath());
            progress.SetProgress64(count, removeVector.size());
            count++;
            it->Delete(false);
        }
        progress.Stop();
    }
    else
    {
        bool bOverwrite = !!parser.HasKey(L"overwrite");
        bool bAutorename = !!parser.HasKey(L"autorename");
        UINT retDefault = bAutorename ? IDCUSTOM1 : 0;
        for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
        {
            CString dropper = droppath + L"\\" + pathList[nPath].GetFileOrDirectoryName();
            if ((!bOverwrite)&&(PathFileExists(dropper)))
            {
                CString renameddropper;
                renameddropper.FormatMessage(IDS_PROC_EXPORTFOLDERNAME, (LPCTSTR)droppath, (LPCTSTR)pathList[nPath].GetFileOrDirectoryName());
                int exportcount = 1;
                while (PathFileExists(renameddropper))
                {
                    renameddropper.FormatMessage(IDS_PROC_EXPORTFOLDERNAME2, (LPCTSTR)droppath, (LPCTSTR)pathList[nPath].GetFileOrDirectoryName(), exportcount++);
                }

                UINT ret = retDefault;
                if (ret == 0)
                {
                    CString sMsg;
                    sMsg.Format(IDS_PROC_OVERWRITEEXPORT, (LPCTSTR)dropper);
                    CTaskDialog taskdlg(sMsg,
                                        CString(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_TASK2)),
                                        L"TortoiseSVN",
                                        0,
                                        TDF_ENABLE_HYPERLINKS | TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
                    taskdlg.AddCommandControl(IDCUSTOM1, CString(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_TASK3)));
                    CString task4;
                    task4.Format(IDS_PROC_OVERWRITEEXPORT_TASK4, (LPCTSTR)renameddropper);
                    taskdlg.AddCommandControl(IDCUSTOM2, task4);
                    taskdlg.AddCommandControl(IDCUSTOM3, CString(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_TASK5)));
                    taskdlg.SetDefaultCommandControl(IDCUSTOM2);
                    taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
                    taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_TASK6)));
                    taskdlg.SetMainIcon(TD_WARNING_ICON);
                    ret = (UINT)taskdlg.DoModal(GetExplorerHWND());
                    if (taskdlg.GetVerificationCheckboxState())
                        retDefault = ret;
                }

                if (ret == IDCUSTOM3)
                    return false;
                if (ret==IDCUSTOM2)
                {
                    dropper = renameddropper;
                }
            }
            if (!svn.Export(pathList[nPath], CTSVNPath(dropper), SVNRev::REV_WC ,SVNRev::REV_WC, !!parser.HasKey(L"overwrite"), false, false, svn_depth_infinity, GetExplorerHWND(), exportType))
            {
                svn.ShowErrorDialog(GetExplorerHWND(), pathList[nPath]);
                bRet = false;
            }
        }
    }
    return bRet;
}