Index: src/ch/task.cpp =================================================================== diff -u -N -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529 -rb42450e5a25470c399e04cfbb7a368519aa455f2 --- src/ch/task.cpp (.../task.cpp) (revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529) +++ src/ch/task.cpp (.../task.cpp) (revision b42450e5a25470c399e04cfbb7a368519aa455f2) @@ -1151,8 +1151,8 @@ } // don't add folder contents when moving inside one disk boundary - if(bIgnoreDirs || !bMove || iDestDrvNumber == -1 - || iDestDrvNumber != spFileInfo->GetDriveNumber() || CFileInfo::Exist(spFileInfo->GetDestinationPath(m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1)) ) + if(bIgnoreDirs || !bMove || iDestDrvNumber == -1 || iDestDrvNumber != spFileInfo->GetDriveNumber() || + CFileInfo::Exist(GetDestinationPath(spFileInfo, m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1)) ) { // log fmt.SetFormat(_T("Recursing folder %path")); @@ -1177,7 +1177,7 @@ else { if(bMove && iDestDrvNumber != -1 && iDestDrvNumber == spFileInfo->GetDriveNumber() && - !CFileInfo::Exist(spFileInfo->GetDestinationPath(m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1)) ) + !CFileInfo::Exist(GetDestinationPath(spFileInfo, m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1)) ) { // if moving within one partition boundary set the file size to 0 so the overall size will // be ok @@ -2113,7 +2113,7 @@ CFileInfoPtr spFileInfo = m_files.GetAt(m_tTaskBasicProgressInfo.GetCurrentIndex()); // set dest path with filename - ccp.strDstFile = spFileInfo->GetDestinationPath((PCTSTR)m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); + ccp.strDstFile = GetDestinationPath(spFileInfo, m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); // are the files/folders lie on the same partition ? int iDstDriveNumber = 0; @@ -2595,6 +2595,81 @@ } } +// finds another name for a copy of src file(folder) in dest location +void CTask::FindFreeSubstituteName(chcore::TSmartPath pathSrcPath, chcore::TSmartPath pathDstPath, CString* pstrResult) const +{ + // get the name from srcpath + pathSrcPath.CutIfExists(_T("\\"), false); + pathDstPath.AppendIfNotExists(_T("\\"), false); + + chcore::TSmartPath spLastComponent = pathSrcPath.GetLastComponent(_T("\\"), false); + + // set the dest path + CString strCheckPath; + ictranslate::CFormat fmt(GetTaskPropValue(m_tTaskDefinition.GetConfiguration())); + fmt.SetParam(_t("%name"), (PCTSTR)spLastComponent); + chcore::TSmartPath pathCheckPath((PCTSTR)fmt); + + // when adding to strDstPath check if the path already exists - if so - try again + int iCounter=1; + CString strFmt = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + while(CFileInfo::Exist(pathDstPath + pathCheckPath)) + { + fmt.SetFormat(strFmt); + fmt.SetParam(_t("%name"), (PCTSTR)spLastComponent); + fmt.SetParam(_t("%count"), ++iCounter); + pathCheckPath = (PCTSTR)fmt; + } + + *pstrResult = pathCheckPath; +} + + +chcore::TSmartPath CTask::GetDestinationPath(const CFileInfoPtr& spFileInfo, chcore::TSmartPath pathDst, int iFlags) const +{ + if(!spFileInfo) + THROW(_T("Invalid pointer"), 0, 0, 0); + + // add '\\' + pathDst.AppendIfNotExists(_T("\\"), false); + + // iFlags: bit 0-ignore folders; bit 1-force creating directories + if (iFlags & 0x02) + { + // force create directories + TCHAR dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; + _tsplitpath(spFileInfo->GetFullFilePath(), NULL, dir, fname, ext); + + CString str(dir); + str.TrimLeft(_T("\\")); + + // force create directory + SHCreateDirectoryEx(NULL, pathDst + str, NULL); + + return pathDst + chcore::TSmartPath((PCTSTR)str) + chcore::TSmartPath(fname) + chcore::TSmartPath(ext); + } + else + { + size_t stSrcIndex = spFileInfo->GetSrcIndex(); + + if (!(iFlags & 0x01) && stSrcIndex != std::numeric_limits::max()) + { + // generate new dest name + if(!m_arrSourcePaths.GetAt(stSrcIndex)->IsDestinationPathSet()) + { + CString strNewPath; + FindFreeSubstituteName(chcore::TSmartPath((PCTSTR)spFileInfo->GetFullFilePath()), pathDst, &strNewPath); + m_arrSourcePaths.GetAt(stSrcIndex)->SetDestinationPath(strNewPath); + } + + CString strResultPath = pathDst + m_arrSourcePaths.GetAt(stSrcIndex)->GetDestinationPath() + spFileInfo->GetFilePath(); + return chcore::TSmartPath((PCTSTR)strResultPath); + } + else + return pathDst + chcore::TSmartPath(spFileInfo->GetFileName()); + } +} + //////////////////////////////////////////////////////////////////////////////// // CTaskArray members CTaskArray::CTaskArray() :