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:
@@ -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'
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -57,6 +57,7 @@ void __fastcall TSynchronizeController::StartStop(TObject * Sender,
|
||||
}
|
||||
|
||||
FCopyParam = CopyParam;
|
||||
FCopyParam.IncludeFileMask.SetRoots(Params.LocalDirectory, Params.RemoteDirectory);
|
||||
FSynchronizeParams = Params;
|
||||
|
||||
DebugAssert(OnAbort);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user