فهرست منبع

Size of directories can be calculated on Synchronization checklist window

Source commit: 0586532ab65d5a134b9295f8e8e6d8121e9d48f0
Martin Prikryl 7 سال پیش
والد
کامیت
14a6e25248

+ 45 - 3
source/core/Terminal.cpp

@@ -140,7 +140,7 @@ TOverwriteFileParams::TOverwriteFileParams()
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 TSynchronizeChecklist::TItem::TItem() :
-  Action(saNone), IsDirectory(false), RemoteFile(NULL), Checked(true), ImageIndex(-1)
+  Action(saNone), IsDirectory(false), RemoteFile(NULL), Checked(true), ImageIndex(-1), FDirectoryHasSize(false)
 {
   Local.ModificationFmt = mfFull;
   Local.Modification = 0;
@@ -237,6 +237,31 @@ void __fastcall TSynchronizeChecklist::Update(const TItem * Item, bool Check, TA
   MutableItem->Action = Action;
 }
 //---------------------------------------------------------------------------
+void __fastcall TSynchronizeChecklist::UpdateDirectorySize(const TItem * Item, __int64 Size)
+{
+  // See comment in Update
+  TItem * MutableItem = const_cast<TItem *>(Item);
+  DebugAssert(FList->IndexOf(MutableItem) >= 0);
+  if (DebugAlwaysTrue(Item->IsDirectory))
+  {
+    MutableItem->FDirectoryHasSize = true;
+
+    if (Item->IsRemoteOnly())
+    {
+      MutableItem->Remote.Size = Size;
+    }
+    else if (Item->IsLocalOnly())
+    {
+      MutableItem->Local.Size = Size;
+    }
+    else
+    {
+      // "update" actions are not relevant for directories
+      DebugFail();
+    }
+  }
+}
+//---------------------------------------------------------------------------
 TSynchronizeChecklist::TAction __fastcall TSynchronizeChecklist::Reverse(TSynchronizeChecklist::TAction Action)
 {
   switch (Action)
@@ -4293,6 +4318,7 @@ bool __fastcall TTerminal::LoadFilesProperties(TStrings * FileList)
 void __fastcall TTerminal::DoCalculateFileSize(UnicodeString FileName,
   const TRemoteFile * File, void * Param)
 {
+  // This is called for top-level entries only
   TCalculateSizeParams * AParams = static_cast<TCalculateSizeParams*>(Param);
 
   if (AParams->Stats->FoundFiles != NULL)
@@ -4307,7 +4333,14 @@ void __fastcall TTerminal::DoCalculateFileSize(UnicodeString FileName,
     }
   }
 
+  __int64 PrevSize = AParams->Size;
   CalculateFileSize(FileName, File, Param);
+
+  if (AParams->Stats->CalculatedSizes != NULL)
+  {
+    __int64 Size = AParams->Size - PrevSize;
+    AParams->Stats->CalculatedSizes->push_back(Size);
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::CalculateFileSize(UnicodeString FileName,
@@ -5332,7 +5365,8 @@ void __fastcall TTerminal::CalculateLocalFileSize(
 }
 //---------------------------------------------------------------------------
 bool __fastcall TTerminal::CalculateLocalFilesSize(TStrings * FileList,
-  __int64 & Size, const TCopyParamType * CopyParam, bool AllowDirs, TStrings * Files)
+  __int64 & Size, const TCopyParamType * CopyParam, bool AllowDirs, TStrings * Files,
+  TCalculatedSizes * CalculatedSizes)
 {
   bool Result = false;
   TFileOperationProgressType OperationProgress(&DoProgress, &DoFinished);
@@ -5374,8 +5408,16 @@ bool __fastcall TTerminal::CalculateLocalFilesSize(TStrings * FileList,
             }
           }
 
+          __int64 PrevSize = Params.Size;
+
           CalculateLocalFileSize(FileName, Rec, &Params);
 
+          if (CalculatedSizes != NULL)
+          {
+            __int64 Size = Params.Size - PrevSize;
+            CalculatedSizes->push_back(Size);
+          }
+
           OperationFinish(&OperationProgress, FileList->Objects[Index], FileName, true, OnceDoneOperation);
         }
       }
@@ -6643,7 +6685,7 @@ bool __fastcall TTerminal::CopyToRemote(TStrings * FilesToCopy,
       Files->OwnsObjects = true;
     }
     bool CalculatedSize =
-      CalculateLocalFilesSize(FilesToCopy, Size, CopyParam, CopyParam->CalculateSize, Files.get());
+      CalculateLocalFilesSize(FilesToCopy, Size, CopyParam, CopyParam->CalculateSize, Files.get(), NULL);
 
     FLastProgressLogged = GetTickCount();
     TFileOperationProgressType OperationProgress(&DoProgress, &DoFinished);

+ 10 - 2
source/core/Terminal.h

@@ -31,6 +31,7 @@ class TCallbackGuard;
 class TParallelOperation;
 class TCollectedFileList;
 struct TLocalFileHandle;
+typedef std::vector<__int64> TCalculatedSizes;
 //---------------------------------------------------------------------------
 typedef void __fastcall (__closure *TQueryUserEvent)
   (TObject * Sender, const UnicodeString Query, TStrings * MoreMessages, unsigned int Answers,
@@ -316,8 +317,6 @@ protected:
   bool __fastcall DoCalculateDirectorySize(const UnicodeString & FileName, TCalculateSizeParams * Params);
   void __fastcall CalculateLocalFileSize(
     const UnicodeString & FileName, const TSearchRecSmart & Rec, /*__int64*/ void * Size);
-  bool __fastcall CalculateLocalFilesSize(TStrings * FileList, __int64 & Size,
-    const TCopyParamType * CopyParam, bool AllowDirs, TStrings * Files);
   TBatchOverwrite __fastcall EffectiveBatchOverwrite(
     const UnicodeString & SourceFullFileName, const TCopyParamType * CopyParam, int Params,
     TFileOperationProgressType * OperationProgress, bool Special);
@@ -546,6 +545,8 @@ public:
   bool __fastcall CalculateFilesSize(TStrings * FileList, __int64 & Size,
     int Params, const TCopyParamType * CopyParam, bool AllowDirs,
     TCalculateSizeStats & Stats);
+  bool __fastcall CalculateLocalFilesSize(TStrings * FileList, __int64 & Size,
+    const TCopyParamType * CopyParam, bool AllowDirs, TStrings * Files, TCalculatedSizes * CalculatedSizes);
   void __fastcall CalculateFilesChecksum(const UnicodeString & Alg, TStrings * FileList,
     TStrings * Checksums, TCalculatedChecksumEvent OnCalculatedChecksum);
   void __fastcall ClearCaches();
@@ -697,6 +698,7 @@ struct TCalculateSizeStats
   int Directories;
   int SymLinks;
   TStrings * FoundFiles;
+  TCalculatedSizes * CalculatedSizes;
 };
 //---------------------------------------------------------------------------
 struct TCalculateSizeParams
@@ -758,6 +760,7 @@ public:
   class TItem
   {
   friend class TTerminal;
+  friend class TSynchronizeChecklist;
 
   public:
     struct TFileInfo
@@ -778,11 +781,15 @@ public:
     TRemoteFile * RemoteFile;
 
     const UnicodeString& GetFileName() const;
+    bool IsRemoteOnly() const { return (Action == saDownloadNew) || (Action == saDeleteRemote); }
+    bool IsLocalOnly() const { return (Action == saUploadNew) || (Action == saDeleteLocal); }
+    bool HasSize() const { return !IsDirectory || FDirectoryHasSize; }
 
     ~TItem();
 
   private:
     FILETIME FLocalLastWriteTime;
+    bool FDirectoryHasSize;
 
     TItem();
   };
@@ -790,6 +797,7 @@ public:
   ~TSynchronizeChecklist();
 
   void __fastcall Update(const TItem * Item, bool Check, TAction Action);
+  void __fastcall UpdateDirectorySize(const TItem * Item, __int64 Size);
 
   static TAction __fastcall Reverse(TAction Action);
 

+ 97 - 1
source/forms/CustomScpExplorer.cpp

@@ -5374,6 +5374,102 @@ void __fastcall TCustomScpExplorerForm::DoFullSynchronize(void * Token, TProcess
   FullSynchronize(Params, OnProcessedItem);
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::DoSynchronizeChecklistCalculateSize(
+  TSynchronizeChecklist * Checklist, const TSynchronizeChecklistItemList & Items, void * Token)
+{
+  // terminal can be already closed (e.g. dropped connection)
+  if (Terminal != NULL)
+  {
+    TSynchronizeParams & Params = *static_cast<TSynchronizeParams *>(Token);
+    std::unique_ptr<TStrings> RemoteFileList(new TStringList());
+    std::unique_ptr<TStrings> LocalFileList(new TStringList());
+
+    for (size_t Index = 0; Index < Items.size(); Index++)
+    {
+      const TSynchronizeChecklist::TItem * ChecklistItem = Items[Index];
+      if (ChecklistItem->IsDirectory)
+      {
+        if (ChecklistItem->IsRemoteOnly())
+        {
+          RemoteFileList->AddObject(ChecklistItem->RemoteFile->FullFileName, ChecklistItem->RemoteFile);
+        }
+        else if (ChecklistItem->IsLocalOnly())
+        {
+          LocalFileList->Add(IncludeTrailingBackslash(ChecklistItem->Local.Directory) + ChecklistItem->Local.FileName);
+        }
+        else
+        {
+          // "update" actions are not relevant for directories
+          DebugFail();
+        }
+      }
+    }
+
+    TCalculatedSizes RemoteCalculatedSizes;
+    TCalculatedSizes LocalCalculatedSizes;
+
+    try
+    {
+      bool Result = true;
+      if (LocalFileList->Count > 0)
+      {
+        __int64 LocalSize = 0;
+        Result = Terminal->CalculateLocalFilesSize(LocalFileList.get(), LocalSize, Params.CopyParam, true, NULL, &LocalCalculatedSizes);
+      }
+      if (Result && (RemoteFileList->Count > 0))
+      {
+        __int64 RemoteSize = 0;
+        TCalculateSizeStats RemoteStats;
+        RemoteStats.CalculatedSizes = &RemoteCalculatedSizes;
+        Terminal->CalculateFilesSize(RemoteFileList.get(), RemoteSize, 0, Params.CopyParam, true, RemoteStats);
+      }
+    }
+    __finally
+    {
+      size_t LocalIndex = 0;
+      size_t RemoteIndex = 0;
+
+      for (size_t Index = 0; Index < Items.size(); Index++)
+      {
+        const TSynchronizeChecklist::TItem * ChecklistItem = Items[Index];
+        if (ChecklistItem->IsDirectory)
+        {
+          __int64 Size = -1;
+          if (ChecklistItem->IsRemoteOnly())
+          {
+            if (RemoteIndex < RemoteCalculatedSizes.size())
+            {
+              Size = RemoteCalculatedSizes[RemoteIndex];
+            }
+            RemoteIndex++;
+          }
+          else if (ChecklistItem->IsLocalOnly())
+          {
+            if (LocalIndex < LocalCalculatedSizes.size())
+            {
+              Size = LocalCalculatedSizes[LocalIndex];
+            }
+            LocalIndex++;
+          }
+          else
+          {
+            // "update" actions are not relevant for directories
+            DebugFail();
+          }
+
+          if (Size >= 0)
+          {
+            Checklist->UpdateDirectorySize(ChecklistItem, Size);
+          }
+        }
+      }
+
+      DebugAssert(RemoteIndex >= RemoteCalculatedSizes.size());
+      DebugAssert(LocalIndex >= LocalCalculatedSizes.size());
+    }
+  }
+}
+//---------------------------------------------------------------------------
 bool __fastcall TCustomScpExplorerForm::DoFullSynchronizeDirectories(
   UnicodeString & LocalDirectory, UnicodeString & RemoteDirectory,
   TSynchronizeMode & Mode, bool & SaveMode, bool UseDefaults)
@@ -5452,7 +5548,7 @@ bool __fastcall TCustomScpExplorerForm::DoFullSynchronizeDirectories(
           Result =
             DoSynchronizeChecklistDialog(
               Checklist, Mode, Params, LocalDirectory, RemoteDirectory, CustomCommandMenu, DoFullSynchronize,
-              &SynchronizeParams);
+              DoSynchronizeChecklistCalculateSize, &SynchronizeParams);
         }
         else
         {

+ 2 - 0
source/forms/CustomScpExplorer.h

@@ -606,6 +606,8 @@ protected:
   void __fastcall CopyPopup(TControl * DestControl, TControl * SourceControl);
   void __fastcall CreateRemoteDirectory(const UnicodeString & Path, TRemoteProperties & Properties);
   void __fastcall DoFullSynchronize(void * Token, TProcessedItem OnProcessedItem);
+  void __fastcall DoSynchronizeChecklistCalculateSize(
+    TSynchronizeChecklist * Checklist, const TSynchronizeChecklistItemList & Items, void * Token);
   void __fastcall FullSynchronize(TSynchronizeParams & Params, TProcessedItem OnProcessedItem);
   void __fastcall CreateOpenDirMenuList(TTBCustomItem * Menu, TOperationSide Side, TBookmarkList * BookmarkList);
   void __fastcall CreateOpenDirMenu(TTBCustomItem * Menu, TOperationSide Side);

+ 64 - 7
source/forms/SynchronizeChecklist.cpp

@@ -30,17 +30,21 @@ const int ImageColumnIndex = 4;
 bool __fastcall DoSynchronizeChecklistDialog(TSynchronizeChecklist * Checklist,
   TSynchronizeMode Mode, int Params,
   const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
-  TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize, void * Token)
+  TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize,
+  TSynchronizeChecklistCalculateSize OnSynchronizeChecklistCalculateSize, void * Token)
 {
   std::unique_ptr<TSynchronizeChecklistDialog> Dialog(
-    new TSynchronizeChecklistDialog(Application, Mode, Params, LocalDirectory, RemoteDirectory, OnCustomCommandMenu, OnSynchronize, Token));
+    new TSynchronizeChecklistDialog(
+      Application, Mode, Params, LocalDirectory, RemoteDirectory, OnCustomCommandMenu, OnSynchronize,
+      OnSynchronizeChecklistCalculateSize, Token));
   return Dialog->Execute(Checklist);
 }
 //---------------------------------------------------------------------
 __fastcall TSynchronizeChecklistDialog::TSynchronizeChecklistDialog(
   TComponent * AOwner, TSynchronizeMode Mode, int Params,
-  const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
-  TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize, void * Token)
+  const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
+  TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize,
+  TSynchronizeChecklistCalculateSize OnSynchronizeChecklistCalculateSize, void * Token)
   : TForm(AOwner)
 {
   FFormRestored = false;
@@ -49,6 +53,7 @@ __fastcall TSynchronizeChecklistDialog::TSynchronizeChecklistDialog(
   FLocalDirectory = ExcludeTrailingBackslash(LocalDirectory);
   FRemoteDirectory = UnixExcludeTrailingBackslash(RemoteDirectory);
   FOnCustomCommandMenu = OnCustomCommandMenu;
+  FOnSynchronizeChecklistCalculateSize = OnSynchronizeChecklistCalculateSize;
   DebugAssert(OnSynchronize != NULL);
   FOnSynchronize = OnSynchronize;
   FToken = Token;
@@ -123,10 +128,12 @@ void __fastcall TSynchronizeChecklistDialog::UpdateControls()
   bool AllUnchecked = true;
   bool AnyBoth = false;
   bool AnyNonBoth = false;
+  bool AnyDirectory = false;
   TListItem * Item = ListView->Selected;
   while (Item != NULL)
   {
-    TSynchronizeChecklist::TAction Action = GetChecklistItemAction(GetChecklistItem(Item));
+    const TSynchronizeChecklist::TItem * ChecklistItem = GetChecklistItem(Item);
+    TSynchronizeChecklist::TAction Action = GetChecklistItemAction(ChecklistItem);
     if ((Action == TSynchronizeChecklist::saUploadUpdate) ||
         (Action == TSynchronizeChecklist::saDownloadUpdate))
     {
@@ -145,6 +152,10 @@ void __fastcall TSynchronizeChecklistDialog::UpdateControls()
     {
       AllChecked = false;
     }
+    if (ChecklistItem->IsDirectory)
+    {
+      AnyDirectory = true;
+    }
     Item = ListView->GetNextItem(Item, sdAll, TItemStates() << isSelected);
   }
 
@@ -157,6 +168,7 @@ void __fastcall TSynchronizeChecklistDialog::UpdateControls()
   UncheckAllAction->Enabled = (FChecked[0] > 0) && !FSynchronizing;
   CustomCommandsAction->Enabled = AnyBoth && !AnyNonBoth && DebugAlwaysTrue(!FSynchronizing);
   ReverseAction->Enabled = (ListView->SelCount > 0) && DebugAlwaysTrue(!FSynchronizing);
+  CalculateSizeAction->Enabled = (ListView->SelCount > 0) && AnyDirectory && DebugAlwaysTrue(!FSynchronizing);
 
   SelectAllAction->Enabled = (ListView->SelCount < ListView->Items->Count) && !FSynchronizing;
 }
@@ -249,7 +261,7 @@ void __fastcall TSynchronizeChecklistDialog::LoadItem(TListItem * Item)
     }
     else
     {
-      if (ChecklistItem->IsDirectory)
+      if (!ChecklistItem->HasSize())
       {
         AddSubItem(Item, Index, L"");
       }
@@ -293,7 +305,7 @@ void __fastcall TSynchronizeChecklistDialog::LoadItem(TListItem * Item)
     }
     else
     {
-      if (ChecklistItem->IsDirectory)
+      if (!ChecklistItem->HasSize())
       {
         AddSubItem(Item, Index, L"");
       }
@@ -1124,3 +1136,48 @@ void __fastcall TSynchronizeChecklistDialog::OkButtonClick(TObject * /*Sender*/)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TSynchronizeChecklistDialog::CalculateSizeActionExecute(TObject * /*Sender*/)
+{
+  std::map<const TSynchronizeChecklist::TItem *, TListItem *> ChecklistToListViewMap;
+  TSynchronizeChecklistItemList Items;
+  TListItem * Item = ListView->Selected;
+  while (Item != NULL)
+  {
+    const TSynchronizeChecklist::TItem * ChecklistItem = GetChecklistItem(Item);
+    ChecklistToListViewMap.insert(std::make_pair(ChecklistItem, Item));
+    Items.push_back(ChecklistItem);
+    if (Item->Checked)
+    {
+      __int64 ItemSize = GetItemSize(ChecklistItem);
+      int ActionIndex = int(GetChecklistItemAction(ChecklistItem));
+      FCheckedSize[ActionIndex] -= ItemSize;
+      FCheckedSize[0] -= ItemSize;
+    }
+    Item = ListView->GetNextItem(Item, sdAll, TItemStates() << isSelected);
+  }
+
+  try
+  {
+    FOnSynchronizeChecklistCalculateSize(FChecklist, Items, FToken);
+  }
+  __finally
+  {
+    TSynchronizeChecklistItemList::const_iterator Iter = Items.begin();
+    while (Iter != Items.end())
+    {
+      const TSynchronizeChecklist::TItem * ChecklistItem = *Iter;
+      TListItem * Item = ChecklistToListViewMap[ChecklistItem];
+      LoadItem(Item);
+      if (Item->Checked)
+      {
+        __int64 ItemSize = GetItemSize(ChecklistItem);
+        int ActionIndex = int(GetChecklistItemAction(ChecklistItem));
+        FCheckedSize[ActionIndex] += ItemSize;
+        FCheckedSize[0] += ItemSize;
+      }
+      Iter++;
+    }
+    UpdateControls();
+  }
+}
+//---------------------------------------------------------------------------

+ 17 - 1
source/forms/SynchronizeChecklist.dfm

@@ -1443,7 +1443,7 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog
     end
     object CustomCommandsButton2: TButton
       Left = 8
-      Top = 292
+      Top = 322
       Width = 108
       Height = 25
       Action = CustomCommandsAction
@@ -1460,6 +1460,15 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog
       Anchors = [akLeft, akTop, akRight]
       TabOrder = 7
     end
+    object CalculateSizeButton: TButton
+      Left = 8
+      Top = 291
+      Width = 108
+      Height = 25
+      Action = CalculateSizeAction
+      Anchors = [akLeft, akTop, akRight]
+      TabOrder = 9
+    end
   end
   object ListView: TIEListView
     Left = 0
@@ -2323,6 +2332,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog
     object ReverseItem: TMenuItem
       Action = ReverseAction
     end
+    object Calculate1: TMenuItem
+      Action = CalculateSizeAction
+    end
     object TMenuItem
       Action = CustomCommandsAction
       object TMenuItem
@@ -2374,6 +2386,10 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog
       Caption = '&Reverse'
       OnExecute = ReverseActionExecute
     end
+    object CalculateSizeAction: TAction
+      Caption = 'C&alculate'
+      OnExecute = CalculateSizeActionExecute
+    end
   end
   object ActionImages120: TPngImageList
     Height = 20

+ 10 - 5
source/forms/SynchronizeChecklist.h

@@ -52,6 +52,9 @@ __published:
   TPngImageList *ActionImages120;
   TPngImageList *ActionImages144;
   TPngImageList *ActionImages192;
+  TAction *CalculateSizeAction;
+  TMenuItem *Calculate1;
+  TButton *CalculateSizeButton;
   void __fastcall HelpButtonClick(TObject * Sender);
   void __fastcall FormShow(TObject * Sender);
   void __fastcall StatusBarDrawPanel(TStatusBar *StatusBar,
@@ -85,13 +88,14 @@ __published:
   void __fastcall ReverseActionExecute(TObject *Sender);
   void __fastcall ListViewClick(TObject *Sender);
   void __fastcall OkButtonClick(TObject *Sender);
-
+  void __fastcall CalculateSizeActionExecute(TObject *Sender);
 
 public:
-  __fastcall TSynchronizeChecklistDialog(TComponent * AOwner,
-    TSynchronizeMode Mode, int Params, const UnicodeString LocalDirectory,
-    const UnicodeString RemoteDirectory, TCustomCommandMenuEvent OnCustomCommandMenu,
-    TFullSynchronizeEvent OnSynchronize, void * Token);
+  __fastcall TSynchronizeChecklistDialog(
+    TComponent * AOwner, TSynchronizeMode Mode, int Params,
+    const UnicodeString & LocalDirectory, const UnicodeString & RemoteDirectory,
+    TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize,
+    TSynchronizeChecklistCalculateSize OnSynchronizeChecklistCalculateSize, void * Token);
   virtual __fastcall ~TSynchronizeChecklistDialog();
 
   bool __fastcall Execute(TSynchronizeChecklist * Checklist);
@@ -113,6 +117,7 @@ protected:
   bool FChangingItemMass;
   UnicodeString FGeneralHint;
   TCustomCommandMenuEvent FOnCustomCommandMenu;
+  TSynchronizeChecklistCalculateSize FOnSynchronizeChecklistCalculateSize;
   typedef std::map<const TSynchronizeChecklist::TItem *, TSynchronizeChecklist::TAction> TActions;
   TActions FActions;
   TFullSynchronizeEvent FOnSynchronize;

+ 5 - 1
source/windows/WinInterface.h

@@ -352,10 +352,14 @@ class TSynchronizeChecklist;
 typedef void __fastcall (__closure *TCustomCommandMenuEvent)
   (TAction * Action, TStrings * LocalFileList, TStrings * RemoteFileList);
 typedef void __fastcall (__closure *TFullSynchronizeEvent)(void * Token, TProcessedItem OnProcessedItem);
+typedef std::vector<const TSynchronizeChecklist::TItem *> TSynchronizeChecklistItemList;
+typedef void __fastcall (__closure *TSynchronizeChecklistCalculateSize)
+  (TSynchronizeChecklist * Checklist, const TSynchronizeChecklistItemList & Items, void * Token);
 bool __fastcall DoSynchronizeChecklistDialog(TSynchronizeChecklist * Checklist,
   TSynchronizeMode Mode, int Params,
   const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory,
-  TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize, void * Token);
+  TCustomCommandMenuEvent OnCustomCommandMenu, TFullSynchronizeEvent OnSynchronize,
+  TSynchronizeChecklistCalculateSize OnSynchronizeChecklistCalculateSize, void * Token);
 
 // forms\Editor.cpp
 typedef void __fastcall (__closure *TFileClosedEvent)