1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-28 15:35:08 +03:00

Showing overall synchronization progress on progress window and taskbar (2nd phase - with overall status - based on sizes)

Source commit: 119383f9b2c39a6924260e5ce8be13ebb46e6850
This commit is contained in:
Martin Prikryl
2018-08-22 16:19:10 +00:00
parent baee90fd02
commit ad4fb2091d
13 changed files with 335 additions and 146 deletions

View File

@@ -8,6 +8,34 @@
//---------------------------------------------------------------------------
#define TRANSFER_BUF_SIZE 32768
//---------------------------------------------------------------------------
TFileOperationProgressType::TPersistence::TPersistence()
{
Clear(true, true);
}
//---------------------------------------------------------------------------
bool TFileOperationProgressType::IsIndeterminateOperation(TFileOperation Operation)
{
return (Operation == foCalculateSize);
}
//---------------------------------------------------------------------------
void TFileOperationProgressType::TPersistence::Clear(bool Batch, bool Speed)
{
if (Batch)
{
TotalTransferred = 0;
StartTime = Now();
SkipToAll = false;
BatchOverwrite = boNo;
CPSLimit = 0;
CounterSet = false;
}
if (Speed)
{
Ticks.clear();
TotalTransferredThen.clear();
}
}
//---------------------------------------------------------------------------
__fastcall TFileOperationProgressType::TFileOperationProgressType()
{
FOnProgress = NULL;
@@ -41,6 +69,8 @@ void __fastcall TFileOperationProgressType::Init()
{
FSection = new TCriticalSection();
FUserSelectionsSection = new TCriticalSection();
FRestored = false;
FPersistence.Side = osCurrent; // = undefined value
}
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::Assign(const TFileOperationProgressType & Other)
@@ -62,7 +92,7 @@ void __fastcall TFileOperationProgressType::AssignButKeepSuspendState(const TFil
Assign(Other);
}
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::Clear()
void __fastcall TFileOperationProgressType::DoClear(bool Batch, bool Speed)
{
FFileName = L"";
FFullFileName = L"";
@@ -71,30 +101,28 @@ void __fastcall TFileOperationProgressType::Clear()
FCount = -1;
FFilesFinished = 0;
FFilesFinishedSuccessfully = 0;
FStartTime = Now();
FSuspended = false;
FSuspendTime = 0;
FInProgress = false;
FDone = false;
FFileInProgress = false;
FTotalTransferred = 0;
FTotalSkipped = 0;
FTotalSize = 0;
FSkippedSize = 0;
FTotalSizeSet = false;
FOperation = foNone;
FTemp = false;
FSkipToAll = false;
FBatchOverwrite = boNo;
FPersistence.Clear(Batch, Speed);
// to bypass check in ClearTransfer()
FTransferSize = 0;
FCPSLimit = 0;
FTicks.clear();
FTotalTransferredThen.clear();
FCounterSet = false;
ClearTransfer();
}
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::Clear()
{
DoClear(true, true);
}
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::ClearTransfer()
{
if ((TransferSize > 0) && (TransferredSize < TransferSize))
@@ -125,15 +153,16 @@ void __fastcall TFileOperationProgressType::Start(TFileOperation AOperation,
{
TGuard Guard(FSection); // not really needed, just for consistency
Clear();
DoClear(!FRestored, (FPersistence.Side != osCurrent) && (FPersistence.Side != ASide));
FTotalTransferBase = FPersistence.TotalTransferred;
FOperation = AOperation;
FSide = ASide;
FPersistence.Side = ASide;
FCount = ACount;
FInProgress = true;
FCancel = csContinue;
FDirectory = ADirectory;
FTemp = ATemp;
FCPSLimit = ACPSLimit;
FPersistence.CPSLimit = ACPSLimit;
}
try
@@ -194,9 +223,9 @@ void __fastcall TFileOperationProgressType::Resume()
// by the time the progress was suspended
unsigned long Stopped = (GetTickCount() - FSuspendTime);
size_t i = 0;
while (i < FTicks.size())
while (i < FPersistence.Ticks.size())
{
FTicks[i] += Stopped;
FPersistence.Ticks[i] += Stopped;
++i;
}
}
@@ -236,7 +265,15 @@ int __fastcall TFileOperationProgressType::TotalTransferProgress() const
{
TGuard Guard(FSection);
DebugAssert(TotalSizeSet);
int Result = FTotalSize > 0 ? (int)(((FTotalTransferred + FTotalSkipped) * 100)/FTotalSize) : 0;
int Result;
if (FTotalSize > 0)
{
Result = (int)(((FPersistence.TotalTransferred - FTotalTransferBase + FTotalSkipped) * 100)/FTotalSize);
}
else
{
Result = 0;
}
return Result < 100 ? Result : 100;
}
//---------------------------------------------------------------------------
@@ -328,9 +365,9 @@ bool __fastcall TFileOperationProgressType::IsLocallyDone()
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::SetSpeedCounters()
{
if ((CPSLimit > 0) && !FCounterSet)
if ((CPSLimit > 0) && !FPersistence.CounterSet)
{
FCounterSet = true;
FPersistence.CounterSet = true;
Configuration->Usage->Inc(L"SpeedLimitUses");
}
}
@@ -510,7 +547,7 @@ unsigned long __fastcall TFileOperationProgressType::GetCPSLimit()
else
{
TGuard Guard(FSection);
Result = FCPSLimit;
Result = FPersistence.CPSLimit;
}
return Result;
}
@@ -524,7 +561,7 @@ void __fastcall TFileOperationProgressType::SetCPSLimit(unsigned long ACPSLimit)
else
{
TGuard Guard(FSection);
FCPSLimit = ACPSLimit;
FPersistence.CPSLimit = ACPSLimit;
}
}
//---------------------------------------------------------------------------
@@ -538,7 +575,7 @@ TBatchOverwrite __fastcall TFileOperationProgressType::GetBatchOverwrite()
else
{
TGuard Guard(FSection); // not really needed
Result = FBatchOverwrite;
Result = FPersistence.BatchOverwrite;
}
return Result;
}
@@ -552,7 +589,7 @@ void __fastcall TFileOperationProgressType::SetBatchOverwrite(TBatchOverwrite AB
else
{
TGuard Guard(FSection); // not really needed
FBatchOverwrite = ABatchOverwrite;;
FPersistence.BatchOverwrite = ABatchOverwrite;;
}
}
//---------------------------------------------------------------------------
@@ -566,7 +603,7 @@ bool __fastcall TFileOperationProgressType::GetSkipToAll()
else
{
TGuard Guard(FSection); // not really needed
Result = FSkipToAll;
Result = FPersistence.SkipToAll;
}
return Result;
}
@@ -580,7 +617,7 @@ void __fastcall TFileOperationProgressType::SetSkipToAll()
else
{
TGuard Guard(FSection); // not really needed
FSkipToAll = true;
FPersistence.SkipToAll = true;
}
}
//---------------------------------------------------------------------------
@@ -600,11 +637,11 @@ void __fastcall TFileOperationProgressType::RollbackTransferFromTotals(__int64 A
{
TGuard Guard(FSection);
DebugAssert(ATransferredSize <= FTotalTransferred);
DebugAssert(ATransferredSize <= FPersistence.TotalTransferred - FTotalTransferBase);
DebugAssert(ASkippedSize <= FTotalSkipped);
FTotalTransferred -= ATransferredSize;
FTicks.clear();
FTotalTransferredThen.clear();
FPersistence.TotalTransferred -= ATransferredSize;
FPersistence.Ticks.clear();
FPersistence.TotalTransferredThen.clear();
FTotalSkipped -= ASkippedSize;
if (FParent != NULL)
@@ -627,27 +664,27 @@ void __fastcall TFileOperationProgressType::AddTransferredToTotals(__int64 ASize
{
TGuard Guard(FSection);
FTotalTransferred += ASize;
FPersistence.TotalTransferred += ASize;
if (ASize >= 0)
{
unsigned long Ticks = GetTickCount();
if (FTicks.empty() ||
(FTicks.back() > Ticks) || // ticks wrap after 49.7 days
((Ticks - FTicks.back()) >= MSecsPerSec))
if (FPersistence.Ticks.empty() ||
(FPersistence.Ticks.back() > Ticks) || // ticks wrap after 49.7 days
((Ticks - FPersistence.Ticks.back()) >= MSecsPerSec))
{
FTicks.push_back(Ticks);
FTotalTransferredThen.push_back(FTotalTransferred);
FPersistence.Ticks.push_back(Ticks);
FPersistence.TotalTransferredThen.push_back(FPersistence.TotalTransferred);
}
if (FTicks.size() > 10)
if (FPersistence.Ticks.size() > 10)
{
FTicks.erase(FTicks.begin());
FTotalTransferredThen.erase(FTotalTransferredThen.begin());
FPersistence.Ticks.erase(FPersistence.Ticks.begin());
FPersistence.TotalTransferredThen.erase(FPersistence.TotalTransferredThen.begin());
}
}
else
{
FTicks.clear();
FPersistence.Ticks.clear();
}
if (FParent != NULL)
@@ -762,7 +799,7 @@ unsigned int __fastcall TFileOperationProgressType::CPS()
unsigned int __fastcall TFileOperationProgressType::GetCPS()
{
unsigned int Result;
if (FTicks.empty())
if (FPersistence.Ticks.empty())
{
Result = 0;
}
@@ -770,14 +807,14 @@ unsigned int __fastcall TFileOperationProgressType::GetCPS()
{
unsigned long Ticks = (Suspended ? FSuspendTime : GetTickCount());
unsigned long TimeSpan;
if (Ticks < FTicks.front())
if (Ticks < FPersistence.Ticks.front())
{
// clocks has wrapped, guess 10 seconds difference
TimeSpan = 10000;
}
else
{
TimeSpan = (Ticks - FTicks.front());
TimeSpan = (Ticks - FPersistence.Ticks.front());
}
if (TimeSpan == 0)
@@ -786,7 +823,7 @@ unsigned int __fastcall TFileOperationProgressType::GetCPS()
}
else
{
__int64 Transferred = (FTotalTransferred - FTotalTransferredThen.front());
__int64 Transferred = (FPersistence.TotalTransferred - FPersistence.TotalTransferredThen.front());
Result = (unsigned int)(Transferred * MSecsPerSec / TimeSpan);
}
}
@@ -812,10 +849,10 @@ TDateTime __fastcall TFileOperationProgressType::TotalTimeLeft()
DebugAssert(FTotalSizeSet);
unsigned int CurCps = GetCPS();
// sanity check
if ((CurCps > 0) && (FTotalSize > FTotalSkipped + FTotalTransferred))
__int64 Processed = FTotalSkipped + FPersistence.TotalTransferred - FTotalTransferBase;
if ((CurCps > 0) && (FTotalSize > Processed))
{
return TDateTime((double)((double)(FTotalSize - FTotalSkipped - FTotalTransferred) / CurCps) /
SecsPerDay);
return TDateTime((double)((double)(FTotalSize - Processed) / CurCps) / SecsPerDay);
}
else
{
@@ -826,7 +863,7 @@ TDateTime __fastcall TFileOperationProgressType::TotalTimeLeft()
__int64 __fastcall TFileOperationProgressType::GetTotalTransferred()
{
TGuard Guard(FSection);
return FTotalTransferred;
return FPersistence.TotalTransferred;
}
//---------------------------------------------------------------------------
__int64 __fastcall TFileOperationProgressType::GetTotalSize()
@@ -879,3 +916,17 @@ UnicodeString __fastcall TFileOperationProgressType::GetLogStr(bool Done)
UnicodeString CPSStr = FormatSize(CPS());
return FORMAT(L"Transferred: %s, %s: %s, CPS: %s/s", (Transferred, TimeLabel, TimeStr, CPSStr));
}
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::Store(TPersistence & Persistence)
{
// in this current use, we do not need this to be guarded actually, as it's used only for a single-threaded synchronization
TGuard Guard(FSection);
Persistence = FPersistence;
}
//---------------------------------------------------------------------------
void __fastcall TFileOperationProgressType::Restore(TPersistence & Persistence)
{
TGuard Guard(FSection);
FPersistence = Persistence;
FRestored = true;
}

View File

@@ -22,9 +22,29 @@ typedef void __fastcall (__closure *TFileOperationFinished)
//---------------------------------------------------------------------------
class TFileOperationProgressType
{
public:
class TPersistence
{
friend class TFileOperationProgressType;
public:
TPersistence();
private:
void Clear(bool Batch, bool Speed);
TDateTime StartTime;
TBatchOverwrite BatchOverwrite;
bool SkipToAll;
unsigned long CPSLimit;
bool CounterSet;
std::vector<unsigned long> Ticks;
std::vector<__int64> TotalTransferredThen;
TOperationSide Side;
__int64 TotalTransferred;
};
private:
TFileOperation FOperation;
TOperationSide FSide;
UnicodeString FFileName;
UnicodeString FFullFileName;
UnicodeString FDirectory;
@@ -41,15 +61,12 @@ private:
bool FFileInProgress;
TCancelStatus FCancel;
int FCount;
TDateTime FStartTime;
__int64 FTotalTransferred;
__int64 FTotalTransferBase;
__int64 FTotalSkipped;
__int64 FTotalSize;
TBatchOverwrite FBatchOverwrite;
bool FSkipToAll;
unsigned long FCPSLimit;
bool FTotalSizeSet;
bool FSuspended;
bool FRestored;
TFileOperationProgressType * FParent;
// when it was last time suspended (to calculate suspend time in Resume())
@@ -63,9 +80,7 @@ private:
bool FReset;
unsigned int FLastSecond;
unsigned long FRemainingCPS;
bool FCounterSet;
std::vector<unsigned long> FTicks;
std::vector<__int64> FTotalTransferredThen;
TPersistence FPersistence;
TCriticalSection * FSection;
TCriticalSection * FUserSelectionsSection;
@@ -74,6 +89,8 @@ private:
unsigned long __fastcall GetCPSLimit();
TBatchOverwrite __fastcall GetBatchOverwrite();
bool __fastcall GetSkipToAll();
TDateTime __fastcall GetStartTime() const { return FPersistence.StartTime; };
TOperationSide __fastcall GetSide() const { return FPersistence.Side; };
protected:
void __fastcall ClearTransfer();
@@ -86,12 +103,13 @@ protected:
unsigned int __fastcall GetCPS();
void __fastcall Init();
static bool __fastcall PassCancelToParent(TCancelStatus ACancel);
void __fastcall DoClear(bool Batch, bool Speed);
public:
// common data
__property TFileOperation Operation = { read = FOperation };
// on what side if operation being processed (local/remote), source of copy
__property TOperationSide Side = { read = FSide };
__property TOperationSide Side = { read = GetSide };
__property int Count = { read = FCount };
__property UnicodeString FileName = { read = FFileName };
__property UnicodeString FullFileName = { read = FFullFileName };
@@ -112,7 +130,7 @@ public:
__property bool FileInProgress = { read = FFileInProgress };
__property TCancelStatus Cancel = { read = GetCancel };
// when operation started
__property TDateTime StartTime = { read = FStartTime };
__property TDateTime StartTime = { read = GetStartTime };
// bytes transferred
__property __int64 TotalTransferred = { read = GetTotalTransferred };
__property __int64 TotalSize = { read = GetTotalSize };
@@ -186,6 +204,10 @@ public:
void __fastcall SetBatchOverwrite(TBatchOverwrite ABatchOverwrite);
void __fastcall SetSkipToAll();
UnicodeString __fastcall GetLogStr(bool Done);
void __fastcall Store(TPersistence & Persistence);
void __fastcall Restore(TPersistence & Persistence);
static bool IsIndeterminateOperation(TFileOperation Operation);
};
//---------------------------------------------------------------------------
class TSuspendFileOperationProgress

View File

@@ -1252,9 +1252,7 @@ void __fastcall TFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Alg
TCalculatedChecksumEvent OnCalculatedChecksum)
{
TFileOperationProgressType Progress(&FTerminal->DoProgress, &FTerminal->DoFinished);
Progress.Start(foCalculateChecksum, osRemote, FileList->Count);
FTerminal->FOperationProgress = &Progress;
FTerminal->OperationStart(Progress, foCalculateChecksum, osRemote, FileList->Count);
try
{
@@ -1282,8 +1280,7 @@ void __fastcall TFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Alg
}
__finally
{
FTerminal->FOperationProgress = NULL;
Progress.Stop();
FTerminal->OperationStop(Progress);
}
}
//---------------------------------------------------------------------------

View File

@@ -2903,23 +2903,108 @@ bool __fastcall TSynchronizeChecklist::IsItemSizeIrrelevant(TAction Action)
//---------------------------------------------------------------------------
TSynchronizeProgress::TSynchronizeProgress(const TSynchronizeChecklist * Checklist)
{
for (int Index = 0; Index < Checklist->Count; Index++)
FTotalSize = -1;
FProcessedSize = 0;
FChecklist = Checklist;
}
//---------------------------------------------------------------------------
__int64 TSynchronizeProgress::ItemSize(const TSynchronizeChecklist::TItem * ChecklistItem) const
{
__int64 Result;
switch (ChecklistItem->Action)
{
const TSynchronizeChecklist::TItem * ChecklistItem = Checklist->Item[Index];
if (ChecklistItem->Checked)
case TSynchronizeChecklist::saDeleteRemote:
case TSynchronizeChecklist::saDeleteLocal:
Result = ChecklistItem->IsDirectory ? 1024*1024 : 100*1024;
break;
default:
if (ChecklistItem->HasSize())
{
Result = ChecklistItem->GetSize();
}
else
{
DebugAssert(ChecklistItem->IsDirectory);
Result = 1024*1024;
}
break;
}
return Result;
}
//---------------------------------------------------------------------------
void TSynchronizeProgress::ItemProcessed(const TSynchronizeChecklist::TItem * ChecklistItem)
{
DebugAssert(FChecklist->Item[FCurrentItem] == ChecklistItem);
FProcessedSize += ItemSize(ChecklistItem);
do
{
FCurrentItem++;
}
while ((FCurrentItem < FChecklist->Count) && !FChecklist->Item[FCurrentItem]->Checked);
if (FCurrentItem >= FChecklist->Count)
{
FCurrentItem = -1;
}
}
//---------------------------------------------------------------------------
__int64 TSynchronizeProgress::GetProcessed(const TFileOperationProgressType * CurrentItemOperationProgress) const
{
DebugAssert(!TFileOperationProgressType::IsIndeterminateOperation(CurrentItemOperationProgress->Operation));
// Need to calculate the total size on the first call only,
// as at the time the contrusctor it called, we usually do not have sizes of folders caculated yet.
if (FTotalSize < 0)
{
FTotalSize = 0;
FCurrentItem = -1;
for (int Index = 0; Index < FChecklist->Count; Index++)
{
FItems.insert(std::make_pair(ChecklistItem, TItemData()));
const TSynchronizeChecklist::TItem * ChecklistItem = FChecklist->Item[Index];
if (ChecklistItem->Checked)
{
FTotalSize += ItemSize(ChecklistItem);
if (FCurrentItem < 0)
{
FCurrentItem = Index;
}
}
}
}
FItemsProcessed = 0;
DebugAssert(FCurrentItem >= 0);
__int64 CurrentItemSize = ItemSize(FChecklist->Item[FCurrentItem]);
// For (single-item-)delete operation, this should return 0
int CurrentItemProgress = CurrentItemOperationProgress->OverallProgress();
__int64 CurrentItemProcessedSize = (CurrentItemSize * CurrentItemProgress) / 100;
return (FProcessedSize + CurrentItemProcessedSize);
}
//---------------------------------------------------------------------------
void TSynchronizeProgress::ItemProcessed(const TSynchronizeChecklist::TItem * /*ChecklistItem*/)
int TSynchronizeProgress::Progress(const TFileOperationProgressType * CurrentItemOperationProgress) const
{
FItemsProcessed++;
__int64 Processed = GetProcessed(CurrentItemOperationProgress);
int Result;
if (FTotalSize > 0)
{
Result = (Processed * 100) / FTotalSize;
}
else
{
Result = 0;
}
return Result;
}
//---------------------------------------------------------------------------
int TSynchronizeProgress::Progress() const
TDateTime TSynchronizeProgress::TimeLeft(const TFileOperationProgressType * CurrentItemOperationProgress) const
{
return (FItemsProcessed * 100) / FItems.size();
TDateTime Result;
__int64 Processed = GetProcessed(CurrentItemOperationProgress);
if (Processed > 0)
{
Result = TDateTime(double(Now() - CurrentItemOperationProgress->StartTime) / Processed * (FTotalSize - Processed));
}
return Result;
}

View File

@@ -517,23 +517,25 @@ private:
static int __fastcall Compare(void * Item1, void * Item2);
};
//---------------------------------------------------------------------------
class TFileOperationProgressType;
//---------------------------------------------------------------------------
class TSynchronizeProgress
{
public:
TSynchronizeProgress(const TSynchronizeChecklist * Checklist);
void ItemProcessed(const TSynchronizeChecklist::TItem * ChecklistItem);
int Progress() const;
int Progress(const TFileOperationProgressType * CurrentItemOperationProgress) const;
TDateTime TimeLeft(const TFileOperationProgressType * CurrentItemOperationProgress) const;
private:
TSynchronizeChecklist * FChecklist;
int FItemsProcessed;
const TSynchronizeChecklist * FChecklist;
mutable __int64 FTotalSize;
mutable int FCurrentItem;
__int64 FProcessedSize;
struct TItemData
{
};
std::map<const TSynchronizeChecklist::TItem *, TItemData> FItems;
__int64 ItemSize(const TSynchronizeChecklist::TItem * ChecklistItem) const;
__int64 GetProcessed(const TFileOperationProgressType * CurrentItemOperationProgress) const;
};
//---------------------------------------------------------------------------
bool __fastcall IsUnixStyleWindowsPath(const UnicodeString & Path);

View File

@@ -3947,9 +3947,7 @@ bool __fastcall TSFTPFileSystem::LoadFilesProperties(TStrings * FileList)
if (FSupport->Loaded || (FSecureShell->SshImplementation == sshiBitvise))
{
TFileOperationProgressType Progress(&FTerminal->DoProgress, &FTerminal->DoFinished);
Progress.Start(foGetProperties, osRemote, FileList->Count);
FTerminal->FOperationProgress = &Progress;
FTerminal->OperationStart(Progress, foGetProperties, osRemote, FileList->Count);
static int LoadFilesPropertiesQueueLen = 5;
TSFTPLoadFilesPropertiesQueue Queue(this);
@@ -3985,8 +3983,7 @@ bool __fastcall TSFTPFileSystem::LoadFilesProperties(TStrings * FileList)
__finally
{
Queue.DisposeSafe();
FTerminal->FOperationProgress = NULL;
Progress.Stop();
FTerminal->OperationStop(Progress);
}
// queue is discarded here
}
@@ -4134,7 +4131,6 @@ void __fastcall TSFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Al
TCalculatedChecksumEvent OnCalculatedChecksum)
{
TFileOperationProgressType Progress(&FTerminal->DoProgress, &FTerminal->DoFinished);
Progress.Start(foCalculateChecksum, osRemote, FileList->Count);
UnicodeString NormalizedAlg = FindIdent(Alg, FChecksumAlgs.get());
UnicodeString SftpAlg;
@@ -4149,8 +4145,7 @@ void __fastcall TSFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Al
SftpAlg = NormalizedAlg;
}
FTerminal->FOperationProgress = &Progress;
FTerminal->OperationStart(Progress, foCalculateChecksum, osRemote, FileList->Count);
try
{
DoCalculateFilesChecksum(NormalizedAlg, SftpAlg, FileList, Checksums, OnCalculatedChecksum,
@@ -4158,8 +4153,7 @@ void __fastcall TSFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Al
}
__finally
{
FTerminal->FOperationProgress = NULL;
Progress.Stop();
FTerminal->OperationStop(Progress);
}
}
//---------------------------------------------------------------------------

View File

@@ -932,6 +932,7 @@ __fastcall TTerminal::TTerminal(TSessionData * SessionData,
FOnCustomCommand = NULL;
FOnClose = NULL;
FOnFindingFile = NULL;
FOperationProgressPersistence = NULL;
FUseBusyCursor = True;
FLockDirectory = L"";
@@ -3658,6 +3659,36 @@ void __fastcall TTerminal::OperationFinish(
Progress->Finish(FileName, Success, OnceDoneOperation);
}
//---------------------------------------------------------------------------
void __fastcall TTerminal::OperationStart(
TFileOperationProgressType & Progress, TFileOperation Operation, TOperationSide Side, int Count)
{
OperationStart(Progress, Operation, Side, Count, false, UnicodeString(), 0);
}
//---------------------------------------------------------------------------
void __fastcall TTerminal::OperationStart(
TFileOperationProgressType & Progress, TFileOperation Operation, TOperationSide Side, int Count,
bool Temp, const UnicodeString & Directory, unsigned long CPSLimit)
{
if (FOperationProgressPersistence != NULL)
{
Progress.Restore(*FOperationProgressPersistence);
}
Progress.Start(Operation, Side, Count, Temp, Directory, CPSLimit);
DebugAssert(FOperationProgress == NULL);
FOperationProgress = &Progress;
}
//---------------------------------------------------------------------------
void __fastcall TTerminal::OperationStop(TFileOperationProgressType & Progress)
{
DebugAssert(FOperationProgress == &Progress);
if (FOperationProgressPersistence != NULL)
{
Progress.Store(*FOperationProgressPersistence);
}
FOperationProgress = NULL;
Progress.Stop();
}
//---------------------------------------------------------------------------
bool __fastcall TTerminal::ProcessFiles(TStrings * FileList,
TFileOperation Operation, TProcessFileEvent ProcessFile, void * Param,
TOperationSide Side, bool Ex)
@@ -3670,9 +3701,8 @@ bool __fastcall TTerminal::ProcessFiles(TStrings * FileList,
try
{
TFileOperationProgressType Progress(&DoProgress, &DoFinished);
Progress.Start(Operation, Side, FileList->Count);
OperationStart(Progress, Operation, Side, FileList->Count);
FOperationProgress = &Progress;
try
{
if (Side == osRemote)
@@ -3738,8 +3768,7 @@ bool __fastcall TTerminal::ProcessFiles(TStrings * FileList,
}
__finally
{
FOperationProgress = NULL;
Progress.Stop();
OperationStop(Progress);
}
}
catch (...)
@@ -5212,7 +5241,7 @@ bool __fastcall TTerminal::CalculateLocalFilesSize(TStrings * FileList,
bool Result = false;
TFileOperationProgressType OperationProgress(&DoProgress, &DoFinished);
TOnceDoneOperation OnceDoneOperation = odoIdle;
OperationProgress.Start(foCalculateSize, osLocal, FileList->Count);
OperationStart(OperationProgress, foCalculateSize, osLocal, FileList->Count);
try
{
TCalculateSizeParams Params;
@@ -5222,8 +5251,6 @@ bool __fastcall TTerminal::CalculateLocalFilesSize(TStrings * FileList,
Params.Files = NULL;
Params.Result = true;
DebugAssert(!FOperationProgress);
FOperationProgress = &OperationProgress;
UnicodeString LastDirPath;
for (int Index = 0; Params.Result && (Index < FileList->Count); Index++)
{
@@ -5269,8 +5296,7 @@ bool __fastcall TTerminal::CalculateLocalFilesSize(TStrings * FileList,
}
__finally
{
FOperationProgress = NULL;
OperationProgress.Stop();
OperationStop(OperationProgress);
}
if (OnceDoneOperation != odoIdle)
@@ -5916,6 +5942,9 @@ void __fastcall TTerminal::SynchronizeApply(
}
BeginTransaction();
TValueRestorer<TFileOperationProgressType::TPersistence *> OperationProgressPersistenceRestorer(FOperationProgressPersistence);
TFileOperationProgressType::TPersistence OperationProgressPersistence;
FOperationProgressPersistence = &OperationProgressPersistence;
try
{
@@ -6597,10 +6626,10 @@ bool __fastcall TTerminal::CopyToRemote(
FLastProgressLogged = GetTickCount();
TFileOperationProgressType OperationProgress(&DoProgress, &DoFinished);
OperationProgress.Start((Params & cpDelete ? foMove : foCopy), osLocal,
OperationStart(
OperationProgress, (Params & cpDelete ? foMove : foCopy), osLocal,
FilesToCopy->Count, Params & cpTemporary, TargetDir, CopyParam->CPSLimit);
FOperationProgress = &OperationProgress;
bool CollectingUsage = false;
try
{
@@ -6661,8 +6690,7 @@ bool __fastcall TTerminal::CopyToRemote(
Configuration->Usage->Inc(L"UploadTime", CounterTime);
Configuration->Usage->SetMax(L"MaxUploadTime", CounterTime);
}
OperationProgress.Stop();
FOperationProgress = NULL;
OperationStop(OperationProgress);
}
}
catch (Exception &E)
@@ -7047,10 +7075,9 @@ bool __fastcall TTerminal::CopyToLocal(
}
}
OperationProgress.Start((Params & cpDelete ? foMove : foCopy), osRemote,
OperationStart(OperationProgress, (Params & cpDelete ? foMove : foCopy), osRemote,
FilesToCopy->Count, Params & cpTemporary, TargetDir, CopyParam->CPSLimit);
FOperationProgress = &OperationProgress;
bool CollectingUsage = false;
try
{
@@ -7116,8 +7143,7 @@ bool __fastcall TTerminal::CopyToLocal(
Configuration->Usage->Inc(L"DownloadTime", CounterTime);
Configuration->Usage->SetMax(L"MaxDownloadTime", CounterTime);
}
FOperationProgress = NULL;
OperationProgress.Stop();
OperationStop(OperationProgress);
}
}
__finally

View File

@@ -226,6 +226,7 @@ private:
TEncryptedFileNames FEncryptedFileNames;
std::set<UnicodeString> FFoldersScannedForEncryptedFiles;
RawByteString FEncryptKey;
TFileOperationProgressType::TPersistence * FOperationProgressPersistence;
void __fastcall CommandError(Exception * E, const UnicodeString Msg);
unsigned int __fastcall CommandError(Exception * E, const UnicodeString Msg,
@@ -382,7 +383,12 @@ protected:
void __fastcall OperationFinish(
TFileOperationProgressType * Progress, const void * Item, const UnicodeString & FileName,
bool Success, TOnceDoneOperation & OnceDoneOperation);
void __fastcall OperationStart(
TFileOperationProgressType & Progress, TFileOperation Operation, TOperationSide Side, int Count);
void __fastcall OperationStart(
TFileOperationProgressType & Progress, TFileOperation Operation, TOperationSide Side, int Count,
bool Temp, const UnicodeString & Directory, unsigned long CPSLimit);
void __fastcall OperationStop(TFileOperationProgressType & Progress);
virtual void __fastcall Information(const UnicodeString & Str, bool Status);
virtual unsigned int __fastcall QueryUser(const UnicodeString Query,
TStrings * MoreMessages, unsigned int Answers, const TQueryParams * Params,

View File

@@ -832,7 +832,7 @@ void __fastcall TCustomScpExplorerForm::SetTaskbarListProgressValue(TFileOperati
int OverallProgress;
if (DebugAlwaysTrue(FProgressForm != NULL) && (FProgressForm->SynchronizeProgress != NULL))
{
OverallProgress = FProgressForm->SynchronizeProgress->Progress();
OverallProgress = FProgressForm->SynchronizeProgress->Progress(ProgressData);
}
else
{
@@ -1513,18 +1513,12 @@ void __fastcall TCustomScpExplorerForm::OperationProgress(
FileOperationProgress(ProgressData);
}
//---------------------------------------------------------------------------
UnicodeString __fastcall TCustomScpExplorerForm::GetProgressTitle(const TFileOperationProgressType & ProgressData)
UnicodeString __fastcall TCustomScpExplorerForm::GetProgressTitle()
{
UnicodeString Result;
if (ProgressData.InProgress)
if (FProgressForm != NULL)
{
TSynchronizeProgress * SynchronizeProgress = NULL;
if (FProgressForm != NULL)
{
SynchronizeProgress = FProgressForm->SynchronizeProgress;
}
Result = TProgressForm::ProgressStr(SynchronizeProgress, &ProgressData);
Result = FProgressForm->ProgressStr();
}
return Result;
}

View File

@@ -696,7 +696,7 @@ public:
void __fastcall OperationFinished(TFileOperation Operation, TOperationSide Side,
bool Temp, const UnicodeString & FileName, bool Success, TOnceDoneOperation & OnceDoneOperation);
void __fastcall OperationProgress(TFileOperationProgressType & ProgressData);
UnicodeString __fastcall GetProgressTitle(const TFileOperationProgressType & ProgressData);
UnicodeString __fastcall GetProgressTitle();
void __fastcall ShowExtendedException(TTerminal * Terminal, Exception * E);
void __fastcall InactiveTerminalException(TTerminal * Terminal, Exception * E);
void __fastcall TerminalReady();

View File

@@ -29,11 +29,6 @@
#pragma resource "*.dfm"
#endif
//---------------------------------------------------------------------
bool __fastcall TProgressForm::IsIndeterminateOperation(TFileOperation Operation)
{
return (Operation == foCalculateSize);
}
//---------------------------------------------------------------------
UnicodeString __fastcall TProgressForm::ProgressStr(
const TSynchronizeProgress * SynchronizeProgress, const TFileOperationProgressType * ProgressData)
{
@@ -55,11 +50,20 @@ UnicodeString __fastcall TProgressForm::ProgressStr(
UnicodeString Result = LoadStr(Id);
if (SynchronizeProgress != NULL)
{
Result = FORMAT(L"%d%% %s - %s", (SynchronizeProgress->Progress(), LoadStr(SYNCHRONIZE_PROGRESS_SYNCHRONIZE2), Result));
Result = FORMAT(L"%s - %s", (LoadStr(SYNCHRONIZE_PROGRESS_SYNCHRONIZE2), Result));
}
else if (!IsIndeterminateOperation(ProgressData->Operation))
if (!TFileOperationProgressType::IsIndeterminateOperation(ProgressData->Operation))
{
Result = FORMAT(L"%d%% %s", (ProgressData->OverallProgress(), Result));
int OverallProgress;
if (SynchronizeProgress != NULL)
{
OverallProgress = SynchronizeProgress->Progress(ProgressData);
}
else
{
OverallProgress = ProgressData->OverallProgress();
}
Result = FORMAT(L"%d%% %s", (OverallProgress, Result));
}
return Result;
}
@@ -118,6 +122,11 @@ __fastcall TProgressForm::~TProgressForm()
ReleaseAsModal(this, FShowAsModalStorage);
}
//---------------------------------------------------------------------
UnicodeString __fastcall TProgressForm::ProgressStr()
{
return FProgressStr;
}
//---------------------------------------------------------------------
void __fastcall TProgressForm::UpdateControls()
{
DebugAssert((FData.Operation >= foCopy) && (FData.Operation <= foUnlock) &&
@@ -210,7 +219,7 @@ void __fastcall TProgressForm::UpdateControls()
CancelItem->Caption = CancelCaption;
OperationProgress->Style = IsIndeterminateOperation(FData.Operation) ? pbstMarquee : pbstNormal;
OperationProgress->Style = TFileOperationProgressType::IsIndeterminateOperation(FData.Operation) ? pbstMarquee : pbstNormal;
if (SynchronizeProgress != NULL)
{
@@ -279,15 +288,17 @@ void __fastcall TProgressForm::UpdateControls()
}
int OverallProgress;
if (SynchronizeProgress != NULL)
// as a side effect this prevents calling TSynchronizeProgress::Progress when we do not know total size yet
// (what would cache wrong values forever)
if (TFileOperationProgressType::IsIndeterminateOperation(FData.Operation))
{
OverallProgress = SynchronizeProgress->Progress();
OverallProgress = -1;
}
else
{
if (IsIndeterminateOperation(FData.Operation))
if (SynchronizeProgress != NULL)
{
OverallProgress = -1;
OverallProgress = SynchronizeProgress->Progress(&FData);
}
else
{
@@ -296,7 +307,8 @@ void __fastcall TProgressForm::UpdateControls()
}
OperationProgress->Position = std::max(0, OverallProgress);
OperationProgress->Hint = (OverallProgress < 0) ? UnicodeString() : FORMAT(L"%d%%", (OverallProgress));
Caption = FormatFormCaption(this, ProgressStr(SynchronizeProgress, &FData));
FProgressStr = ProgressStr(SynchronizeProgress, &FData);
Caption = FormatFormCaption(this, FProgressStr);
if (TransferOperation)
{
@@ -312,8 +324,16 @@ void __fastcall TProgressForm::UpdateControls()
StartTimeLabel->Caption = FData.StartTime.TimeString();
if (FData.TotalSizeSet)
{
TimeLeftLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat,
FData.TotalTimeLeft());
TDateTime TimeLeft;
if (SynchronizeProgress != NULL)
{
TimeLeft = SynchronizeProgress->TimeLeft(&FData);
}
else
{
TimeLeft = FData.TotalTimeLeft();
}
TimeLeftLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat, TimeLeft);
}
TimeElapsedLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat, FData.TimeElapsed());
BytesTransferredLabel->Caption = FormatBytes(FData.TotalTransferred);

View File

@@ -112,6 +112,7 @@ private:
TOnceDoneItems FOnceDoneItems;
bool FAllowSkip;
TSynchronizeProgress * FSynchronizeProgress;
UnicodeString FProgressStr;
void __fastcall SetOnceDoneOperation(TOnceDoneOperation value);
TTBCustomItem * __fastcall CurrentOnceDoneItem();
@@ -133,8 +134,6 @@ protected:
virtual void __fastcall Dispatch(void * Message);
void __fastcall SetCancelLower(TCancelStatus ACancel);
static bool __fastcall IsIndeterminateOperation(TFileOperation Operation);
public:
static UnicodeString __fastcall ProgressStr(
const TSynchronizeProgress * SynchronizeProgress, const TFileOperationProgressType * ProgressData);
@@ -144,6 +143,7 @@ public:
virtual __fastcall ~TProgressForm();
void __fastcall SetProgressData(TFileOperationProgressType & AData);
void __fastcall ClearCancel();
UnicodeString __fastcall ProgressStr();
__property TCancelStatus Cancel = { read = FCancel };
__property bool MoveToQueue = { read = FMoveToQueue };
__property TOnceDoneOperation OnceDoneOperation = { read=GetOnceDoneOperation, write=SetOnceDoneOperation };

View File

@@ -680,13 +680,14 @@ void __fastcall TTerminalManager::UpdateAppTitle()
UnicodeString NewTitle = FormatMainFormCaption(GetActiveTerminalTitle(false));
UnicodeString QueueProgressTitle;
UnicodeString ProgressTitle = !FProgressTitle.IsEmpty() ? FProgressTitle : ScpExplorer->GetProgressTitle();
if (!FForegroundProgressTitle.IsEmpty())
{
NewTitle = FForegroundProgressTitle + L" - " + NewTitle;
}
else if (!FProgressTitle.IsEmpty() && !ForegroundTask())
else if (!ProgressTitle.IsEmpty() && !ForegroundTask())
{
NewTitle = FProgressTitle + L" - " + NewTitle;
NewTitle = ProgressTitle + L" - " + NewTitle;
}
else if (ShouldDisplayQueueStatusOnAppTitle() &&
!(QueueProgressTitle = ScpExplorer->GetQueueProgressTitle()).IsEmpty())
@@ -1191,15 +1192,6 @@ void __fastcall TTerminalManager::OperationFinished(::TFileOperation Operation,
void __fastcall TTerminalManager::OperationProgress(
TFileOperationProgressType & ProgressData)
{
if (ProgressData.InProgress)
{
FProgressTitle = ScpExplorer->GetProgressTitle(ProgressData);
}
else
{
FProgressTitle = L"";
}
UpdateAppTitle();
DebugAssert(ScpExplorer);
ScpExplorer->OperationProgress(ProgressData);