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

Estimating time to finish directory comparison before synchronization based on previous comparisons of the same folders

Source commit: 01df1bed1a6df6d014df2151b6c9c08d3d860eb8
This commit is contained in:
Martin Prikryl
2019-06-26 11:59:50 +00:00
parent 8b7052b53a
commit a62f0274e4
14 changed files with 232 additions and 53 deletions

View File

@@ -13,6 +13,7 @@
#include "CoreMain.h"
#include "Security.h"
#include "FileMasks.h"
#include "CopyParam.h"
#include <shlobj.h>
#include <System.IOUtils.hpp>
#include <System.StrUtils.hpp>
@@ -1443,6 +1444,64 @@ void __fastcall TConfiguration::SetRandomSeedFile(UnicodeString value)
}
}
}
//---------------------------------------------------------------------------
UnicodeString __fastcall TConfiguration::GetDirectoryStatisticsCacheKey(
const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam)
{
std::unique_ptr<TStringList> RawOptions(new TStringList());
RawOptions->Add(SessionKey);
RawOptions->Add(UnixExcludeTrailingBackslash(Path));
TCopyParamType Defaults;
TCopyParamType FilterCopyParam;
FilterCopyParam.IncludeFileMask = CopyParam.IncludeFileMask;
FilterCopyParam.ExcludeHiddenFiles = CopyParam.ExcludeHiddenFiles;
FilterCopyParam.ExcludeEmptyDirectories = CopyParam.ExcludeEmptyDirectories;
std::unique_ptr<TOptionsStorage> OptionsStorage(new TOptionsStorage(RawOptions.get(), true));
FilterCopyParam.Save(OptionsStorage.get(), &Defaults);
UTF8String RawOptionsBuf(RawOptions->CommaText.LowerCase());
UnicodeString Result = Sha256(RawOptionsBuf.c_str(), RawOptionsBuf.Length());
return Result;
}
//---------------------------------------------------------------------------
THierarchicalStorage * TConfiguration::OpenDirectoryStatisticsCache(bool CanCreate)
{
std::unique_ptr<THierarchicalStorage> Storage(Configuration->CreateConfigStorage());
Storage->AccessMode = CanCreate ? smReadWrite : smRead;
if (!Storage->OpenSubKey(L"DirectoryStatisticsCache", CanCreate))
{
Storage.reset(NULL);
}
return Storage.release();
}
//---------------------------------------------------------------------------
TStrings * __fastcall TConfiguration::LoadDirectoryStatisticsCache(
const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam)
{
std::unique_ptr<THierarchicalStorage> Storage(OpenDirectoryStatisticsCache(false));
std::unique_ptr<TStringList> Result(new TStringList());
if (Storage.get() != NULL)
{
UnicodeString Key = GetDirectoryStatisticsCacheKey(SessionKey, Path, CopyParam);
UnicodeString Buf = Storage->ReadString(Key, UnicodeString());
Result->CommaText = Buf;
}
return Result.release();
}
//---------------------------------------------------------------------------
void __fastcall TConfiguration::SaveDirectoryStatisticsCache(
const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam, TStrings * DataList)
{
std::unique_ptr<THierarchicalStorage> Storage(OpenDirectoryStatisticsCache(true));
if (Storage.get() != NULL)
{
UnicodeString Key = GetDirectoryStatisticsCacheKey(SessionKey, Path, CopyParam);
UnicodeString Buf = DataList->CommaText;
Storage->WriteString(Key, Buf);
}
}
//---------------------------------------------------------------------
UnicodeString __fastcall TConfiguration::GetRandomSeedFileName()
{

View File

@@ -18,6 +18,7 @@ extern const wchar_t * NotAutoSwitchNames;
enum TAutoSwitch { asOn, asOff, asAuto }; // Has to match PuTTY FORCE_ON, FORCE_OFF, AUTO
//---------------------------------------------------------------------------
class TStoredSessionList;
class TCopyParamType;
//---------------------------------------------------------------------------
class TConfiguration : public TObject
{
@@ -169,6 +170,9 @@ protected:
static UnicodeString __fastcall PropertyToKey(const UnicodeString & Property);
virtual void __fastcall DoSave(bool All, bool Explicit);
UnicodeString __fastcall FormatFingerprintKey(const UnicodeString & SiteKey, const UnicodeString & FingerprintType);
THierarchicalStorage * OpenDirectoryStatisticsCache(bool CanCreate);
UnicodeString __fastcall GetDirectoryStatisticsCacheKey(
const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam);
virtual bool __fastcall GetConfirmOverwriting();
virtual void __fastcall SetConfirmOverwriting(bool value);
@@ -227,6 +231,10 @@ public:
TRemoteDirectoryChangesCache * DirectoryChangesCache);
void __fastcall SaveDirectoryChangesCache(const UnicodeString SessionKey,
TRemoteDirectoryChangesCache * DirectoryChangesCache);
TStrings * __fastcall LoadDirectoryStatisticsCache(
const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam);
void __fastcall SaveDirectoryStatisticsCache(
const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam, TStrings * DataList);
bool __fastcall ShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner, unsigned int & Params);
void __fastcall NeverShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner);
void __fastcall SetBannerParams(const UnicodeString & SessionKey, unsigned int Params);

View File

@@ -2394,8 +2394,8 @@ void __fastcall TManagementScript::TerminalOperationFinished(
}
//---------------------------------------------------------------------------
void __fastcall TManagementScript::TerminalSynchronizeDirectory(
const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
bool & Continue, bool Collect)
const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
bool & Continue, bool Collect, const TSynchronizeOptions *)
{
int SynchronizeMode = FSynchronizeMode;
if (FKeepingUpToDate)

View File

@@ -236,8 +236,9 @@ protected:
void __fastcall FreeTerminal(TTerminal * Terminal);
void __fastcall PrintProgress(bool First, const UnicodeString Str);
bool __fastcall QueryCancel();
void __fastcall TerminalSynchronizeDirectory(const UnicodeString LocalDirectory,
const UnicodeString RemoteDirectory, bool & Continue, bool Collect);
void __fastcall TerminalSynchronizeDirectory(
const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
bool & Continue, bool Collect, const TSynchronizeOptions * Options);
void __fastcall DoChangeLocalDirectory(UnicodeString Directory);
void __fastcall DoClose(TTerminal * Terminal);
virtual bool __fastcall HandleExtendedException(Exception * E,

View File

@@ -5760,6 +5760,11 @@ void __fastcall TTerminal::DoSynchronizeCollectFile(const UnicodeString FileName
{
TSynchronizeData * Data = static_cast<TSynchronizeData *>(Param);
if (Data->Options != NULL)
{
Data->Options->Files++;
}
UnicodeString LocalFileName = ChangeFileName(Data->CopyParam, File->FileName, osRemote, false);
UnicodeString FullRemoteFileName = UnixExcludeTrailingBackslash(File->FullFileName);
if (DoAllowRemoteFileTransfer(File, Data->CopyParam, true) &&
@@ -6211,8 +6216,8 @@ void __fastcall TTerminal::DoSynchronizeProgress(const TSynchronizeData & Data,
if (Data.OnSynchronizeDirectory != NULL)
{
bool Continue = true;
Data.OnSynchronizeDirectory(Data.LocalDirectory, Data.RemoteDirectory,
Continue, Collect);
Data.OnSynchronizeDirectory(
Data.LocalDirectory, Data.RemoteDirectory, Continue, Collect, Data.Options);
if (!Continue)
{

View File

@@ -53,8 +53,8 @@ typedef void __fastcall (__closure *TProcessFileEventEx)
typedef int __fastcall (__closure *TFileOperationEvent)
(void * Param1, void * Param2);
typedef void __fastcall (__closure *TSynchronizeDirectory)
(const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
bool & Continue, bool Collect);
(const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
bool & Continue, bool Collect, const TSynchronizeOptions * Options);
typedef void __fastcall (__closure *TUpdatedSynchronizationChecklistItems)(
const TSynchronizeChecklist::TItemList & Items);
typedef void __fastcall (__closure *TProcessedSynchronizationChecklistItem)(
@@ -763,6 +763,7 @@ struct TSynchronizeOptions
~TSynchronizeOptions();
TStringList * Filter;
int Files;
bool __fastcall FilterFind(const UnicodeString & FileName);
bool __fastcall MatchesFilter(const UnicodeString & FileName);

View File

@@ -850,23 +850,11 @@ void __fastcall TCustomScpExplorerForm::SetTaskbarListProgressState(TBPFLAG Flag
FTaskbarList->SetProgressState(GetMainForm()->Handle, Flags);
}
//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::SetTaskbarListProgressValue(TFileOperationProgressType * ProgressData)
void __fastcall TCustomScpExplorerForm::SetTaskbarListProgressValue(int Progress)
{
if (!TFileOperationProgressType::IsIndeterminateOperation(ProgressData->Operation))
if (Progress >= 0)
{
int OverallProgress;
// FProgressForm is null when this is called from SetQueueProgress
if ((FProgressForm != NULL) && (FProgressForm->SynchronizeProgress != NULL))
{
OverallProgress = FProgressForm->SynchronizeProgress->Progress(ProgressData);
}
else
{
OverallProgress = ProgressData->OverallProgress();
}
// implies TBPF_NORMAL
FTaskbarList->SetProgressValue(GetMainForm()->Handle, OverallProgress, 100);
FTaskbarList->SetProgressValue(GetMainForm()->Handle, Progress, 100);
}
else
{
@@ -874,6 +862,25 @@ void __fastcall TCustomScpExplorerForm::SetTaskbarListProgressValue(TFileOperati
}
}
//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::SetTaskbarListProgressValue(TFileOperationProgressType * ProgressData)
{
int OverallProgress;
// FProgressForm is null when this is called from SetQueueProgress
if ((FProgressForm != NULL) && (FProgressForm->SynchronizeProgress != NULL))
{
OverallProgress = FProgressForm->SynchronizeProgress->Progress(ProgressData);
}
else if (!TFileOperationProgressType::IsIndeterminateOperation(ProgressData->Operation))
{
OverallProgress = ProgressData->OverallProgress();
}
else
{
OverallProgress = -1;
}
SetTaskbarListProgressValue(OverallProgress);
}
//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::SetQueueProgress()
{
TTerminalManager::Instance()->QueueStatusUpdated();
@@ -5417,7 +5424,7 @@ void __fastcall TCustomScpExplorerForm::Synchronize(const UnicodeString LocalDir
TSynchronizeChecklist * AChecklist = NULL;
try
{
FSynchronizeProgressForm = new TSynchronizeProgressForm(Application, true);
FSynchronizeProgressForm = new TSynchronizeProgressForm(Application, true, -1);
if (FLAGCLEAR(Params, TTerminal::spDelayProgress))
{
FSynchronizeProgressForm->Start();
@@ -5771,13 +5778,32 @@ int __fastcall TCustomScpExplorerForm::DoFullSynchronizeDirectories(
try
{
FSynchronizeProgressForm = new TSynchronizeProgressForm(Application, true);
UnicodeString SessionKey = Terminal->SessionData->SessionKey;
std::unique_ptr<TStrings> DataList(Configuration->LoadDirectoryStatisticsCache(SessionKey, RemoteDirectory, CopyParam));
int Files = -1;
if (DataList->Count >= 1)
{
Files = StrToIntDef(DataList->Strings[0], Files);
}
else
{
DataList->Add(UnicodeString());
}
FSynchronizeProgressForm = new TSynchronizeProgressForm(Application, true, Files);
FSynchronizeProgressForm->Start();
Checklist = Terminal->SynchronizeCollect(LocalDirectory, RemoteDirectory,
static_cast<TTerminal::TSynchronizeMode>(Mode),
&CopyParam, Params | TTerminal::spNoConfirmation, TerminalSynchronizeDirectory,
&SynchronizeOptions);
if (Terminal->SessionData->CacheDirectories)
{
DataList->Strings[0] = IntToStr(SynchronizeOptions.Files);
Configuration->SaveDirectoryStatisticsCache(SessionKey, RemoteDirectory, CopyParam, DataList.get());
}
}
__finally
{
@@ -5834,8 +5860,8 @@ int __fastcall TCustomScpExplorerForm::DoFullSynchronizeDirectories(
}
//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::TerminalSynchronizeDirectory(
const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
bool & Continue, bool Collect)
const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
bool & Continue, bool Collect, const TSynchronizeOptions * Options)
{
if (Collect)
{
@@ -5844,7 +5870,8 @@ void __fastcall TCustomScpExplorerForm::TerminalSynchronizeDirectory(
{
FSynchronizeProgressForm->Start();
}
FSynchronizeProgressForm->SetData(LocalDirectory, RemoteDirectory, Continue);
int CompareProgress = FSynchronizeProgressForm->SetData(LocalDirectory, RemoteDirectory, Options->Files, Continue);
SetTaskbarListProgressValue(CompareProgress);
}
else
{

View File

@@ -438,8 +438,9 @@ protected:
DYNAMIC void __fastcall DoShow();
TStrings * __fastcall CreateVisitedDirectories(TOperationSide Side);
void __fastcall HandleErrorList(TStringList *& ErrorList);
void __fastcall TerminalSynchronizeDirectory(const UnicodeString LocalDirectory,
const UnicodeString RemoteDirectory, bool & Continue, bool Collect);
void __fastcall TerminalSynchronizeDirectory(
const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
bool & Continue, bool Collect, const TSynchronizeOptions * Options);
void __fastcall DoSynchronize(TSynchronizeController * Sender,
const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
const TCopyParamType & CopyParam, const TSynchronizeParamType & Params,
@@ -623,6 +624,7 @@ protected:
void __fastcall SetQueueProgress();
void __fastcall UpdateQueueLabel();
void __fastcall SetTaskbarListProgressState(TBPFLAG Flags);
void __fastcall SetTaskbarListProgressValue(int Progress);
void __fastcall SetTaskbarListProgressValue(TFileOperationProgressType * ProgressData);
TTerminal * __fastcall GetSessionTabTerminal(TTabSheet * TabSheet);
bool __fastcall SessionTabSwitched();

View File

@@ -325,7 +325,7 @@ void __fastcall TProgressForm::UpdateControls()
if (FData.TotalSizeSet)
{
UnicodeString TimeLeftCaption;
if (SecondsBetween(FData.StartTime, Now()) >= 3)
if (CanShowTimeEstimate(FData.StartTime))
{
TDateTime TimeLeft;
if (SynchronizeProgress != NULL)

View File

@@ -23,14 +23,20 @@
#endif
//---------------------------------------------------------------------------
// Used for comparing only
__fastcall TSynchronizeProgressForm::TSynchronizeProgressForm(TComponent * Owner, bool AllowMinimize)
__fastcall TSynchronizeProgressForm::TSynchronizeProgressForm(TComponent * Owner, bool AllowMinimize, int Files)
: TForm(Owner)
{
FStarted = false;
FCanceled = false;
FElapsed = EncodeTimeVerbose(0, 0, 0, 0);
FShowAsModalStorage = NULL;
FMinimizedByMe = false;
bool KnowsTotalFiles = (Files >= 0);
OperationProgress->Style = (KnowsTotalFiles ? pbstNormal : pbstMarquee);
OperationProgress->Max = (KnowsTotalFiles ? Files : 1);
TimeLeftLabelLabel->Visible = KnowsTotalFiles;
TimeLeftLabel->Visible = KnowsTotalFiles;
StartTimeLabelLabel->Visible = !KnowsTotalFiles;
StartTimeLabel->Visible = !KnowsTotalFiles;
UseSystemSettings(this);
HideComponentsPanel(this);
SelectScaledImageList(ImageList);
@@ -66,7 +72,8 @@ void __fastcall TSynchronizeProgressForm::Start()
FStartTime = Now();
UpdateTimer->Enabled = true;
StartTimeLabel->Caption = FStartTime.TimeString();
Caption = FormatFormCaption(this, LoadStr(SYNCHRONIZE_PROGRESS_COMPARE));
OperationProgress->Position = OperationProgress->Min;
UpdateControls();
if (!IsApplicationMinimized())
{
// Do not show the progress when the application is minimized,
@@ -82,25 +89,56 @@ void __fastcall TSynchronizeProgressForm::Start()
FFrameAnimation.Start();
}
//---------------------------------------------------------------------------
void __fastcall TSynchronizeProgressForm::SetData(const UnicodeString LocalDirectory,
const UnicodeString RemoteDirectory, bool & Continue)
int __fastcall TSynchronizeProgressForm::SetData(
const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory, int Progress, bool & Continue)
{
DebugAssert(FStarted);
LocalDirectoryLabel->Caption = LocalDirectory;
RemoteDirectoryLabel->Caption = RemoteDirectory;
OperationProgress->Position = Progress;
Continue = !FCanceled;
UpdateControls();
Application->ProcessMessages();
return CalculateProgress();
}
//---------------------------------------------------------------------------
int __fastcall TSynchronizeProgressForm::CalculateProgress()
{
return ((OperationProgress->Style == pbstMarquee) ? -1 : ((OperationProgress->Position * 100) / OperationProgress->Max));
}
//---------------------------------------------------------------------------
void __fastcall TSynchronizeProgressForm::UpdateControls()
{
TDateTime Elapsed;
UnicodeString ACaption = FormatFormCaption(this, LoadStr(SYNCHRONIZE_PROGRESS_COMPARE));
if (FStarted)
{
FElapsed = Now() - FStartTime;
Elapsed = Now() - FStartTime;
int Progress = CalculateProgress();
if (Progress >= 0)
{
ACaption = FORMAT(L"%d%% %s", (Progress, ACaption));
}
}
TimeElapsedLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat, FElapsed);
else
{
Elapsed = EncodeTimeVerbose(0, 0, 0, 0);
}
Caption = ACaption;
TimeElapsedLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat, Elapsed);
UnicodeString TimeLeftCaption;
int Position = OperationProgress->Position;
if (FStarted && CanShowTimeEstimate(FStartTime) && (Position > 0))
{
TDateTime TimeLeft = TDateTime(double(double(Elapsed) * (OperationProgress->Max - Position) / Position));
TimeLeftCaption = FormatDateTimeSpan(Configuration->TimeFormat, TimeLeft);
}
else
{
TimeLeftCaption = LoadStr(PROGRESS_TIME_LEFT_CALCULATING);
}
TimeLeftLabel->Caption = TimeLeftCaption;
CancelItem->Enabled = !FCanceled;
}
//---------------------------------------------------------------------------

View File

@@ -4,7 +4,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
BorderIcons = [biSystemMenu, biMinimize, biMaximize, biHelp]
BorderStyle = bsDialog
Caption = 'Synchronization X'
ClientHeight = 193
ClientHeight = 219
ClientWidth = 424
Color = clWindow
ParentFont = True
@@ -12,9 +12,26 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
Position = poOwnerFormCenter
DesignSize = (
424
193)
219)
PixelsPerInch = 96
TextHeight = 13
object TimeLeftLabel: TLabel
Left = 141
Top = 49
Width = 79
Height = 13
AutoSize = False
Caption = '00:00:00'
ShowAccelChar = False
end
object TimeLeftLabelLabel: TLabel
Left = 49
Top = 49
Width = 45
Height = 13
Caption = 'Time left:'
ShowAccelChar = False
end
object Label1: TLabel
Left = 49
Top = 9
@@ -63,7 +80,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
Caption = '00:00:00'
ShowAccelChar = False
end
object Label4: TLabel
object StartTimeLabelLabel: TLabel
Left = 49
Top = 49
Width = 51
@@ -96,7 +113,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
end
object ToolbarPanel: TPanel
Left = 49
Top = 92
Top = 115
Width = 185
Height = 28
Anchors = [akLeft, akBottom]
@@ -138,7 +155,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
end
object ComponentsPanel: TPanel
Left = 0
Top = 127
Top = 153
Width = 424
Height = 66
Align = alBottom
@@ -147,11 +164,21 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
BevelOuter = bvNone
TabOrder = 1
end
object OperationProgress: TProgressBar
Left = 49
Top = 88
Width = 365
Height = 16
Anchors = [akLeft, akTop, akRight]
ParentShowHint = False
ShowHint = True
TabOrder = 2
end
object UpdateTimer: TTimer
Enabled = False
OnTimer = UpdateTimerTimer
Left = 393
Top = 140
Top = 166
end
object ImageList: TPngImageList
PngImages = <
@@ -353,7 +380,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
574C0000000049454E44AE426082}
end>
Left = 40
Top = 140
Top = 166
Bitmap = {}
end
object ImageList120: TPngImageList
@@ -559,7 +586,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
02001CD843D9E9F4EAFC0000000049454E44AE426082}
end>
Left = 136
Top = 140
Top = 166
Bitmap = {}
end
object ImageList144: TPngImageList
@@ -765,7 +792,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
5ED71FD84ED953D17B83BCD30000000049454E44AE426082}
end>
Left = 224
Top = 140
Top = 166
Bitmap = {}
end
object ImageList192: TPngImageList
@@ -979,7 +1006,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm
82}
end>
Left = 312
Top = 140
Top = 166
Bitmap = {}
end
end

View File

@@ -15,6 +15,7 @@
#include "TBX.hpp"
#include <Vcl.ImgList.hpp>
#include <GUITools.h>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
class TSynchronizeProgressForm : public TForm
{
@@ -24,7 +25,7 @@ __published:
TPathLabel *RemoteDirectoryLabel;
TPathLabel *LocalDirectoryLabel;
TLabel *StartTimeLabel;
TLabel *Label4;
TLabel *StartTimeLabelLabel;
TLabel *Label3;
TLabel *TimeElapsedLabel;
TTimer *UpdateTimer;
@@ -39,26 +40,29 @@ __published:
TPngImageList *ImageList120;
TPngImageList *ImageList144;
TPngImageList *ImageList192;
TProgressBar *OperationProgress;
TLabel *TimeLeftLabelLabel;
TLabel *TimeLeftLabel;
void __fastcall UpdateTimerTimer(TObject *Sender);
void __fastcall MinimizeItemClick(TObject *Sender);
void __fastcall CancelItemClick(TObject *Sender);
public:
__fastcall TSynchronizeProgressForm(TComponent * Owner, bool AllowMinimize);
__fastcall TSynchronizeProgressForm(TComponent * Owner, bool AllowMinimize, int Files);
virtual __fastcall ~TSynchronizeProgressForm();
void __fastcall Start();
void __fastcall SetData(const UnicodeString LocalDirectory,
const UnicodeString RemoteDirectory, bool & Continue);
int __fastcall SetData(
const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory, int Progress, bool & Continue);
__property bool Started = { read = FStarted };
protected:
virtual void __fastcall Dispatch(void * Message);
int __fastcall CalculateProgress();
private:
TDateTime FStartTime;
TDateTime FElapsed;
bool FStarted;
bool FCanceled;
void * FShowAsModalStorage;

View File

@@ -27,6 +27,7 @@
#include <Vcl.ScreenTips.hpp>
#include <HistoryComboBox.hpp>
#include <vssym32.h>
#include <DateUtils.hpp>
#include "Animations96.h"
#include "Animations120.h"
@@ -2110,3 +2111,8 @@ void __fastcall FindComponentClass(
ComponentClass = __classid(TUIStateAwareComboBox);
}
}
//---------------------------------------------------------------------------
bool CanShowTimeEstimate(TDateTime StartTime)
{
return (SecondsBetween(StartTime, Now()) >= 3);
}

View File

@@ -61,6 +61,7 @@ void LoadBrowserDocument(TWebBrowserEx * WebBrowser, const UnicodeString & Docum
TComponent * __fastcall FindComponentRecursively(TComponent * Root, const UnicodeString & Name);
void __fastcall GetInstrutionsTheme(
TColor & MainInstructionColor, HFONT & MainInstructionFont, HFONT & InstructionFont);
bool CanShowTimeEstimate(TDateTime StartTime);
//---------------------------------------------------------------------------
class TLocalCustomCommand : public TFileCustomCommand
{