1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

Bug 2052: File masks relative to the root of an operation

https://winscp.net/tracker/2052
(cherry picked from commit c5a60526ed)

Source commit: d1db6dd6b43b56565709801383e235ce4c6a1005
This commit is contained in:
Martin Prikryl
2021-12-14 09:45:54 +00:00
parent 6065119808
commit 958a9949c6
8 changed files with 196 additions and 61 deletions

View File

@@ -17,6 +17,7 @@ static UnicodeString AllFileMasksDelimiters = FileMasksDelimiters + IncludeExclu
static UnicodeString DirectoryMaskDelimiters = L"/\\";
static UnicodeString FileMasksDelimiterStr = UnicodeString(FileMasksDelimiters[1]) + L' ';
UnicodeString AnyMask = L"*.*";
static UnicodeString MaskSymbols = L"?*[";
//---------------------------------------------------------------------------
__fastcall EFileMasksException::EFileMasksException(
UnicodeString Message, int AErrorStart, int AErrorLen) :
@@ -148,7 +149,25 @@ UnicodeString TFileMasks::TParams::ToString() const
//---------------------------------------------------------------------------
bool __fastcall TFileMasks::IsMask(const UnicodeString Mask)
{
return (Mask.LastDelimiter(L"?*[") > 0);
return (Mask.LastDelimiter(MaskSymbols) > 0);
}
//---------------------------------------------------------------------------
UnicodeString TFileMasks::EscapeMask(const UnicodeString & S)
{
UnicodeString Result = S;
if (Result.LastDelimiter(MaskSymbols) > 0) // optimization
{
for (int Index = 1; Index < Result.Length(); Index++)
{
if (MaskSymbols.Pos(Result[Index]) > 0)
{
Result.Insert(L"[", Index);
Index += 2;
Result.Insert(L"]", Index);
}
}
}
return Result;
}
//---------------------------------------------------------------------------
UnicodeString __fastcall TFileMasks::NormalizeMask(const UnicodeString & Mask, const UnicodeString & AnyMask)
@@ -266,6 +285,8 @@ void TFileMasks::DoCopy(const TFileMasks & Source)
FForceDirectoryMasks = Source.FForceDirectoryMasks;
FNoImplicitMatchWithDirExcludeMask = Source.FNoImplicitMatchWithDirExcludeMask;
FAllDirsAreImplicitlyIncluded = Source.FAllDirsAreImplicitlyIncluded;
FLocalRoot = Source.FLocalRoot;
FRemoteRoot = Source.FRemoteRoot;
SetStr(Source.Masks, false);
}
//---------------------------------------------------------------------------
@@ -274,6 +295,7 @@ void __fastcall TFileMasks::Init()
FForceDirectoryMasks = -1;
FNoImplicitMatchWithDirExcludeMask = false;
FAllDirsAreImplicitlyIncluded = false;
FAnyRelative = false;
DoInit(false);
}
@@ -305,15 +327,17 @@ void __fastcall TFileMasks::Clear(TMasks & Masks)
TMasks::iterator I = Masks.begin();
while (I != Masks.end())
{
ReleaseMaskMask((*I).FileNameMask);
ReleaseMaskMask((*I).DirectoryMask);
delete (*I).FileNameMask;
delete (*I).RemoteDirectoryMask;
delete (*I).LocalDirectoryMask;
I++;
}
Masks.clear();
}
//---------------------------------------------------------------------------
bool __fastcall TFileMasks::MatchesMasks(const UnicodeString FileName, bool Directory,
const UnicodeString Path, const TParams * Params, const TMasks & Masks, bool Recurse)
bool __fastcall TFileMasks::MatchesMasks(
const UnicodeString & FileName, bool Local, bool Directory,
const UnicodeString & Path, const TParams * Params, const TMasks & Masks, bool Recurse)
{
bool Result = false;
@@ -321,9 +345,10 @@ bool __fastcall TFileMasks::MatchesMasks(const UnicodeString FileName, bool Dire
while (!Result && (I != Masks.end()))
{
const TMask & Mask = *I;
Masks::TMask * DirectoryMask = Local ? Mask.LocalDirectoryMask : Mask.RemoteDirectoryMask;
Result =
MatchesMaskMask(Mask.DirectoryMask, Path) &&
MatchesMaskMask(Mask.FileNameMask, FileName);
MatchesMaskMask(Mask.DirectoryMaskKind, DirectoryMask, Path) &&
MatchesMaskMask(Mask.FileNameMaskKind, Mask.FileNameMask, FileName);
if (Result)
{
@@ -412,21 +437,25 @@ bool __fastcall TFileMasks::MatchesMasks(const UnicodeString FileName, bool Dire
// Currently it includes Size/Time only, what is not used for directories.
// So it depends on future use. Possibly we should make a copy
// and pass on only relevant fields.
Result = MatchesMasks(ParentFileName, true, ParentPath, Params, Masks, Recurse);
Result = MatchesMasks(ParentFileName, Local, true, ParentPath, Params, Masks, Recurse);
}
return Result;
}
//---------------------------------------------------------------------------
bool TFileMasks::DoMatches(
const UnicodeString & FileName, bool Directory, const UnicodeString & Path, const TParams * Params,
const UnicodeString & FileName, bool Local, bool Directory, const UnicodeString & Path, const TParams * Params,
bool RecurseInclude, bool & ImplicitMatch) const
{
if (FileName == L"aaa2.txt")
{
UnicodeString X;
}
bool ImplicitIncludeMatch = (FAllDirsAreImplicitlyIncluded && Directory) || FMasks[MASK_INDEX(Directory, true)].empty();
bool ExplicitIncludeMatch = MatchesMasks(FileName, Directory, Path, Params, FMasks[MASK_INDEX(Directory, true)], RecurseInclude);
bool ExplicitIncludeMatch = MatchesMasks(FileName, Local, Directory, Path, Params, FMasks[MASK_INDEX(Directory, true)], RecurseInclude);
bool Result =
(ImplicitIncludeMatch || ExplicitIncludeMatch) &&
!MatchesMasks(FileName, Directory, Path, Params, FMasks[MASK_INDEX(Directory, false)], false);
!MatchesMasks(FileName, Local, Directory, Path, Params, FMasks[MASK_INDEX(Directory, false)], false);
ImplicitMatch =
Result && ImplicitIncludeMatch && !ExplicitIncludeMatch &&
((Directory && FNoImplicitMatchWithDirExcludeMask) || FMasks[MASK_INDEX(Directory, false)].empty());
@@ -451,12 +480,12 @@ bool __fastcall TFileMasks::Matches(const UnicodeString FileName, bool Local,
{
Path = ToUnixPath(ExcludeTrailingBackslash(Path));
}
Result = DoMatches(ExtractFileName(FileName), Directory, Path, Params,
Result = DoMatches(ExtractFileName(FileName), Local, Directory, Path, Params,
RecurseInclude, ImplicitMatch);
}
else
{
Result = DoMatches(UnixExtractFileName(FileName), Directory,
Result = DoMatches(UnixExtractFileName(FileName), Local, Directory,
SimpleUnixExcludeTrailingBackslash(UnixExtractFilePath(FileName)), Params,
RecurseInclude, ImplicitMatch);
}
@@ -466,7 +495,7 @@ bool __fastcall TFileMasks::Matches(const UnicodeString FileName, bool Local,
bool TFileMasks::MatchesFileName(const UnicodeString & FileName, bool Directory, const TParams * Params) const
{
bool ImplicitMatch;
return DoMatches(FileName, Directory, EmptyStr, Params, true, ImplicitMatch);
return DoMatches(FileName, false, Directory, EmptyStr, Params, true, ImplicitMatch);
}
//---------------------------------------------------------------------------
bool __fastcall TFileMasks::operator ==(const TFileMasks & rhm) const
@@ -499,21 +528,26 @@ void __fastcall TFileMasks::ThrowError(int Start, int End)
Start, End - Start + 1);
}
//---------------------------------------------------------------------------
void __fastcall TFileMasks::CreateMaskMask(const UnicodeString & Mask, int Start, int End,
bool Ex, TMaskMask & MaskMask)
Masks::TMask * TFileMasks::DoCreateMaskMask(const UnicodeString & Str)
{
return new Masks::TMask(Str);
}
//---------------------------------------------------------------------------
void __fastcall TFileMasks::CreateMaskMask(
const UnicodeString & Mask, int Start, int End, bool Ex, TMask::TKind & MaskKind, Masks::TMask *& MaskMask)
{
try
{
DebugAssert(MaskMask.Mask == NULL);
DebugAssert(MaskMask == NULL);
if (Ex && !IsEffectiveFileNameMask(Mask))
{
MaskMask.Kind = TMaskMask::Any;
MaskMask.Mask = NULL;
MaskKind = TMask::TKind::Any;
MaskMask = NULL;
}
else
{
MaskMask.Kind = (Ex && (Mask == L"*.")) ? TMaskMask::NoExt : TMaskMask::Regular;
MaskMask.Mask = new Masks::TMask(Mask);
MaskKind = (Ex && (Mask == L"*.")) ? TMask::TKind::NoExt : TMask::TKind::Regular;
MaskMask = DoCreateMaskMask(Mask);
}
}
catch(...)
@@ -544,10 +578,11 @@ void __fastcall TFileMasks::CreateMask(
Mask.MaskStr = MaskStr;
Mask.UserStr = MaskStr;
Mask.FileNameMask.Kind = TMaskMask::Any;
Mask.FileNameMask.Mask = NULL;
Mask.DirectoryMask.Kind = TMaskMask::Any;
Mask.DirectoryMask.Mask = NULL;
Mask.FileNameMaskKind = TMask::TKind::Any;
Mask.FileNameMask = NULL;
Mask.DirectoryMaskKind = TMask::TKind::Any;
Mask.RemoteDirectoryMask = NULL;
Mask.LocalDirectoryMask = NULL;
Mask.HighSizeMask = TMask::None;
Mask.LowSizeMask = TMask::None;
Mask.HighModificationMask = TMask::None;
@@ -649,18 +684,53 @@ void __fastcall TFileMasks::CreateMask(
if (D > 0)
{
// make sure sole "/" (root dir) is preserved as is
UnicodeString DirectoryMaskStr = SimpleUnixExcludeTrailingBackslash(ToUnixPath(PartStr.SubString(1, D)));
UnicodeString RemoteDirectoryMaskStr = DirectoryMaskStr;
UnicodeString LocalDirectoryMaskStr = DirectoryMaskStr;
const UnicodeString RelativePrefix = L".";
const UnicodeString RelativePrefixWithSlash = RelativePrefix + L"/";
if (DirectoryMaskStr == RelativePrefix)
{
FAnyRelative = true;
if (!FRemoteRoot.IsEmpty())
{
RemoteDirectoryMaskStr = SimpleUnixExcludeTrailingBackslash(FRemoteRoot);
}
if (!FLocalRoot.IsEmpty())
{
LocalDirectoryMaskStr = SimpleUnixExcludeTrailingBackslash(FLocalRoot);
}
}
else if (StartsStr(RelativePrefixWithSlash, DirectoryMaskStr))
{
FAnyRelative = true;
DirectoryMaskStr.Delete(1, RelativePrefixWithSlash.Length());
if (!FRemoteRoot.IsEmpty())
{
RemoteDirectoryMaskStr = FRemoteRoot + DirectoryMaskStr;
}
if (!FLocalRoot.IsEmpty())
{
LocalDirectoryMaskStr = FLocalRoot + DirectoryMaskStr;
}
}
CreateMaskMask(
SimpleUnixExcludeTrailingBackslash(ToUnixPath(PartStr.SubString(1, D))),
PartStart, PartStart + D - 1, false,
Mask.DirectoryMask);
RemoteDirectoryMaskStr, PartStart, PartStart + D - 1, false,
Mask.DirectoryMaskKind, Mask.RemoteDirectoryMask);
if (Mask.RemoteDirectoryMask != NULL)
{
Mask.LocalDirectoryMask = DoCreateMaskMask(LocalDirectoryMaskStr);
}
CreateMaskMask(
PartStr.SubString(D + 1, PartStr.Length() - D),
PartStart + D, PartEnd, true,
Mask.FileNameMask);
Mask.FileNameMaskKind, Mask.FileNameMask);
}
else
{
CreateMaskMask(PartStr, PartStart, PartEnd, true, Mask.FileNameMask);
CreateMaskMask(PartStr, PartStart, PartEnd, true, Mask.FileNameMaskKind, Mask.FileNameMask);
}
}
}
@@ -684,11 +754,6 @@ TStrings * __fastcall TFileMasks::GetMasksStr(int Index) const
return FMasksStr[Index];
}
//---------------------------------------------------------------------------
void __fastcall TFileMasks::ReleaseMaskMask(TMaskMask & MaskMask)
{
delete MaskMask.Mask;
}
//---------------------------------------------------------------------------
void __fastcall TFileMasks::TrimEx(UnicodeString & Str, int & Start, int & End)
{
UnicodeString Buf = TrimLeft(Str);
@@ -697,20 +762,20 @@ void __fastcall TFileMasks::TrimEx(UnicodeString & Str, int & Start, int & End)
End -= Buf.Length() - Str.Length();
}
//---------------------------------------------------------------------------
bool __fastcall TFileMasks::MatchesMaskMask(const TMaskMask & MaskMask, const UnicodeString & Str)
bool TFileMasks::MatchesMaskMask(TMask::TKind MaskKind, Masks::TMask * MaskMask, const UnicodeString & Str)
{
bool Result;
if (MaskMask.Kind == TMaskMask::Any)
if (MaskKind == TMask::TKind::Any)
{
Result = true;
}
else if ((MaskMask.Kind == TMaskMask::NoExt) && (Str.Pos(L".") == 0))
else if ((MaskKind == TMask::TKind::NoExt) && (Str.Pos(L".") == 0))
{
Result = true;
}
else
{
Result = MaskMask.Mask->Matches(Str);
Result = MaskMask->Matches(Str);
}
return Result;
}
@@ -730,6 +795,7 @@ void __fastcall TFileMasks::SetMask(const UnicodeString & Mask)
//---------------------------------------------------------------------------
void __fastcall TFileMasks::SetStr(const UnicodeString Str, bool SingleMask)
{
FAnyRelative = false;
UnicodeString Backup = FStr;
try
{
@@ -785,6 +851,36 @@ void __fastcall TFileMasks::SetStr(const UnicodeString Str, bool SingleMask)
}
}
//---------------------------------------------------------------------------
void TFileMasks::SetRoots(const UnicodeString & LocalRoot, const UnicodeString & RemoteRoot)
{
if (FAnyRelative) // optimization
{
FLocalRoot = EscapeMask(UnixIncludeTrailingBackslash(ToUnixPath(LocalRoot)));
FRemoteRoot = EscapeMask(UnixIncludeTrailingBackslash(RemoteRoot));
SetStr(FStr, false);
}
}
//---------------------------------------------------------------------------
void TFileMasks::SetRoots(TStrings * LocalFileList, const UnicodeString & RemoteRoot)
{
if (FAnyRelative) // optimization
{
UnicodeString LocalRoot;
ExtractCommonPath(LocalFileList, LocalRoot);
SetRoots(LocalRoot, RemoteRoot);
}
}
//---------------------------------------------------------------------------
void TFileMasks::SetRoots(const UnicodeString & LocalRoot, TStrings * RemoteFileList)
{
if (FAnyRelative) // optimization
{
UnicodeString RemoteRoot;
UnixExtractCommonPath(RemoteFileList, RemoteRoot);
SetRoots(LocalRoot, RemoteRoot);
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#define TEXT_TOKEN L'\255'
//---------------------------------------------------------------------------

View File

@@ -29,6 +29,7 @@ public:
};
static bool __fastcall IsMask(const UnicodeString Mask);
static UnicodeString EscapeMask(const UnicodeString & S);
static UnicodeString __fastcall NormalizeMask(const UnicodeString & Mask, const UnicodeString & AnyMask = L"");
static UnicodeString __fastcall ComposeMaskStr(
TStrings * IncludeFileMasksStr, TStrings * ExcludeFileMasksStr,
@@ -53,6 +54,10 @@ public:
bool __fastcall Matches(const UnicodeString FileName, bool Local, bool Directory,
const TParams * Params, bool RecurseInclude, bool & ImplicitMatch) const;
void SetRoots(const UnicodeString & LocalRoot, const UnicodeString & RemoteRoot);
void SetRoots(TStrings * LocalFileList, const UnicodeString & RemoteRoot);
void SetRoots(const UnicodeString & LocalRoot, TStrings * RemoteFileList);
__property UnicodeString Masks = { read = FStr, write = SetMasks };
__property bool NoImplicitMatchWithDirExcludeMask = { read = FNoImplicitMatchWithDirExcludeMask, write = FNoImplicitMatchWithDirExcludeMask };
__property bool AllDirsAreImplicitlyIncluded = { read = FAllDirsAreImplicitlyIncluded, write = FAllDirsAreImplicitlyIncluded };
@@ -67,17 +72,19 @@ private:
UnicodeString FStr;
bool FNoImplicitMatchWithDirExcludeMask;
bool FAllDirsAreImplicitlyIncluded;
struct TMaskMask
{
enum { Any, NoExt, Regular } Kind;
TMask * Mask;
};
bool FAnyRelative;
UnicodeString FLocalRoot;
UnicodeString FRemoteRoot;
struct TMask
{
TMaskMask FileNameMask;
TMaskMask DirectoryMask;
enum TKind { Any, NoExt, Regular };
TKind FileNameMaskKind;
Masks::TMask * FileNameMask;
TKind DirectoryMaskKind;
Masks::TMask * RemoteDirectoryMask;
Masks::TMask * LocalDirectoryMask;
enum TMaskBoundary { None, Open, Close };
@@ -101,25 +108,26 @@ private:
void __fastcall SetStr(const UnicodeString value, bool SingleMask);
void __fastcall SetMasks(const UnicodeString value);
void __fastcall CreateMaskMask(const UnicodeString & Mask, int Start, int End,
bool Ex, TMaskMask & MaskMask);
void __fastcall CreateMaskMask(
const UnicodeString & Mask, int Start, int End, bool Ex, TMask::TKind & MaskKind, Masks::TMask *& MaskMask);
void __fastcall CreateMask(const UnicodeString & MaskStr, int MaskStart,
int MaskEnd, bool Include);
TStrings * __fastcall GetMasksStr(int Index) const;
static UnicodeString __fastcall MakeDirectoryMask(UnicodeString Str);
static inline void __fastcall ReleaseMaskMask(TMaskMask & MaskMask);
inline void __fastcall Init();
void __fastcall DoInit(bool Delete);
void DoCopy(const TFileMasks & Source);
void __fastcall Clear();
static void __fastcall Clear(TMasks & Masks);
static void __fastcall TrimEx(UnicodeString & Str, int & Start, int & End);
static bool __fastcall MatchesMasks(const UnicodeString FileName, bool Directory,
const UnicodeString Path, const TParams * Params, const TMasks & Masks, bool Recurse);
static inline bool __fastcall MatchesMaskMask(const TMaskMask & MaskMask, const UnicodeString & Str);
static bool __fastcall MatchesMasks(
const UnicodeString & FileName, bool Local, bool Directory,
const UnicodeString & Path, const TParams * Params, const TMasks & Masks, bool Recurse);
static inline bool MatchesMaskMask(TMask::TKind MaskKind, Masks::TMask * MaskMask, const UnicodeString & Str);
static Masks::TMask * DoCreateMaskMask(const UnicodeString & Str);
void __fastcall ThrowError(int Start, int End);
bool DoMatches(
const UnicodeString & FileName, bool Directory, const UnicodeString & Path, const TParams * Params,
const UnicodeString & FileName, bool Local, bool Directory, const UnicodeString & Path, const TParams * Params,
bool RecurseInclude, bool & ImplicitMatch) const;
};
//---------------------------------------------------------------------------

View File

@@ -171,18 +171,32 @@ bool __fastcall ExtractCommonPath(TStrings * Files, UnicodeString & Path)
return Result;
}
//---------------------------------------------------------------------------
static UnicodeString GetFileListItemPath(TStrings * Files, int Index)
{
UnicodeString Result;
if (Files->Objects[Index] != NULL)
{
Result = DebugNotNull(dynamic_cast<TRemoteFile *>(Files->Objects[Index]))->FullFileName;
}
else
{
Result = Files->Strings[Index];
}
return Result;
}
//---------------------------------------------------------------------------
bool __fastcall UnixExtractCommonPath(TStrings * Files, UnicodeString & Path)
{
DebugAssert(Files->Count > 0);
Path = UnixExtractFilePath(Files->Strings[0]);
Path = UnixExtractFilePath(GetFileListItemPath(Files, 0));
bool Result = !Path.IsEmpty();
if (Result)
{
for (int Index = 1; Index < Files->Count; Index++)
{
while (!Path.IsEmpty() &&
(Files->Strings[Index].SubString(1, Path.Length()) != Path))
(GetFileListItemPath(Files, Index).SubString(1, Path.Length()) != Path))
{
int PrevLen = Path.Length();
Path = UnixExtractFilePath(UnixExcludeTrailingBackslash(Path));

View File

@@ -1498,6 +1498,7 @@ void __fastcall TScript::GetProc(TScriptProcParams * Parameters)
}
CheckParams(Parameters);
CopyParam.IncludeFileMask.SetRoots(TargetDirectory, FileList);
FTerminal->CopyToLocal(FileList, TargetDirectory, &CopyParam, Params, NULL);
}
@@ -1569,6 +1570,7 @@ void __fastcall TScript::PutProc(TScriptProcParams * Parameters)
}
CheckParams(Parameters);
CopyParam.IncludeFileMask.SetRoots(FileList, TargetDirectory);
FTerminal->CopyToRemote(FileList, TargetDirectory, &CopyParam, Params, NULL);
}
@@ -1973,6 +1975,7 @@ void __fastcall TScript::SynchronizeProc(TScriptProcParams * Parameters)
UnicodeString RemoteDirectory;
SynchronizeDirectories(Parameters, LocalDirectory, RemoteDirectory, 2);
CopyParam.IncludeFileMask.SetRoots(LocalDirectory, RemoteDirectory);
CheckDefaultSynchronizeParams();
int SynchronizeParams = FSynchronizeParams | TTerminal::spNoConfirmation;

View File

@@ -1224,7 +1224,7 @@ void __fastcall TCustomScpExplorerForm::ClearTransferSourceSelection(TTransferDi
//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::AddQueueItem(
TTerminalQueue * Queue, TTransferDirection Direction, TStrings * FileList,
const UnicodeString TargetDirectory, const TGUICopyParamType & CopyParam,
const UnicodeString TargetDirectory, TGUICopyParamType & CopyParam,
int Params)
{
DebugAssert(Queue != NULL);
@@ -1247,11 +1247,13 @@ void __fastcall TCustomScpExplorerForm::AddQueueItem(
TQueueItem * QueueItem;
if (Direction == tdToRemote)
{
CopyParam.IncludeFileMask.SetRoots(FileList, TargetDirectory);
QueueItem = new TUploadQueueItem(Terminal, FileList, TargetDirectory,
&CopyParam, Params, SingleFile, CopyParam.QueueParallel);
}
else
{
CopyParam.IncludeFileMask.SetRoots(TargetDirectory, FileList);
QueueItem = new TDownloadQueueItem(Terminal, FileList, TargetDirectory,
&CopyParam, Params, SingleFile, CopyParam.QueueParallel);
}
@@ -2668,6 +2670,9 @@ bool __fastcall TCustomScpExplorerForm::ExecuteCopyMoveFileOperation(
PermanentFileList = FileList;
Params |= FLAGMASK(Param.Temp, cpTemporary);
CopyParam.IncludeFileMask.SetRoots(FileList, Param.TargetDirectory);
Terminal->CopyToRemote(FileList, Param.TargetDirectory, &CopyParam, Params, NULL);
if (Operation == foMove)
{
@@ -2690,6 +2695,8 @@ bool __fastcall TCustomScpExplorerForm::ExecuteCopyMoveFileOperation(
try
{
CopyParam.IncludeFileMask.SetRoots(Param.TargetDirectory, FileList);
Terminal->CopyToLocal(FileList, Param.TargetDirectory, &CopyParam, Params, NULL);
}
__finally
@@ -5978,6 +5985,7 @@ int __fastcall TCustomScpExplorerForm::DoFullSynchronizeDirectories(
if (Continue)
{
Configuration->Usage->Inc(L"Synchronizations");
CopyParam.IncludeFileMask.SetRoots(LocalDirectory, RemoteDirectory);
UpdateCopyParamCounters(CopyParam);
TSynchronizeOptions SynchronizeOptions;
@@ -7866,10 +7874,11 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDTargetDrop()
}
//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::DDDownload(
TStrings * FilesToCopy, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params)
TStrings * FilesToCopy, const UnicodeString & TargetDir, TCopyParamType * CopyParam, int Params)
{
DebugAssert(!IsLocalBrowserMode());
TAutoBatch AutoBatch(this);
CopyParam->IncludeFileMask.SetRoots(TargetDir, FilesToCopy);
UpdateCopyParamCounters(*CopyParam);
Terminal->CopyToLocal(FilesToCopy, TargetDir, CopyParam, Params, NULL);
if (FLAGSET(Params, cpDelete) && (DropSourceControl == RemoteDriveView))

View File

@@ -316,9 +316,10 @@ private:
void __fastcall SetDockAllowDrag(bool value);
void __fastcall QueueSplitterDblClick(TObject * Sender);
void __fastcall QueueFileListSplitterDblClick(TObject * Sender);
void __fastcall AddQueueItem(TTerminalQueue * Queue, TTransferDirection Direction,
void __fastcall AddQueueItem(
TTerminalQueue * Queue, TTransferDirection Direction,
TStrings * FileList, const UnicodeString TargetDirectory,
const TGUICopyParamType & CopyParam, int Params);
TGUICopyParamType & CopyParam, int Params);
void __fastcall AddQueueItem(TTerminalQueue * Queue, TQueueItem * QueueItem, TManagedTerminal * Terminal);
void __fastcall ClearTransferSourceSelection(TTransferDirection Direction);
void __fastcall SessionsDDDragOver(int KeyState, const TPoint & Point, int & Effect, int PreferredEffect);
@@ -530,7 +531,7 @@ protected:
bool __fastcall RemoteFileControlFileOperation(TObject * Sender,
TFileOperation Operation, bool NoConfirmation, void * Param);
void __fastcall DDDownload(
TStrings * FilesToCopy, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params);
TStrings * FilesToCopy, const UnicodeString & TargetDir, TCopyParamType * CopyParam, int Params);
bool __fastcall EnsureCommandSessionFallback(TFSCapability Capability);
bool __fastcall CommandSessionFallback();
void __fastcall FileTerminalRemoved(const UnicodeString FileName,

View File

@@ -57,6 +57,7 @@ void __fastcall TSynchronizeController::StartStop(TObject * Sender,
}
FCopyParam = CopyParam;
FCopyParam.IncludeFileMask.SetRoots(Params.LocalDirectory, Params.RemoteDirectory);
FSynchronizeParams = Params;
DebugAssert(OnAbort);

View File

@@ -118,6 +118,7 @@ void __fastcall Upload(TTerminal * Terminal, TStrings * FileList, int UseDefault
{
// Setting parameter overrides only now, otherwise the dialog would present the parametes as non-default
CopyParam.OnceDoneOperation = odoDisconnect;
CopyParam.IncludeFileMask.SetRoots(FileList, TargetDirectory);
Terminal->CopyToRemote(FileList, TargetDirectory, &CopyParam, 0, NULL);
}
@@ -180,6 +181,8 @@ void __fastcall Download(TTerminal * Terminal, const UnicodeString FileName, int
std::unique_ptr<TStrings> FileList(new TStringList());
FileList->AddObject(FileName, File);
CopyParam.IncludeFileMask.SetRoots(TargetDirectory, FileList.get());
Terminal->CopyToLocal(FileList.get(), TargetDirectory, &CopyParam, 0, NULL);
}