瀏覽代碼

Bug 1680: Synchronization summary

https://winscp.net/tracker/1680

Source commit: 5b294fd256dc9db49bae41a881d5b0c91582e16f
Martin Prikryl 7 年之前
父節點
當前提交
7b2f2ec2e1

+ 27 - 5
source/core/Common.cpp

@@ -2323,9 +2323,11 @@ int __fastcall TimeToMinutes(TDateTime T)
   return TimeToSeconds(T) / SecsPerMin;
 }
 //---------------------------------------------------------------------------
-static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool ToRecycleBin, UnicodeString & ErrorPath)
+static bool __fastcall DoRecursiveDeleteFile(
+  const UnicodeString FileName, bool ToRecycleBin, UnicodeString & ErrorPath, int & Deleted)
 {
   bool Result;
+  Deleted = 0;
 
   UnicodeString AErrorPath = FileName;
 
@@ -2338,6 +2340,10 @@ static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool
       if (!SearchRec.IsDirectory())
       {
         Result = DeleteFile(ApiPath(FileName));
+        if (Result)
+        {
+          Deleted++;
+        }
       }
       else
       {
@@ -2354,7 +2360,7 @@ static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool
               {
                 if (SearchRec.IsRealFile())
                 {
-                  Result = DoRecursiveDeleteFile(FileName2, DebugAlwaysFalse(ToRecycleBin), AErrorPath);
+                  Result = DoRecursiveDeleteFile(FileName2, DebugAlwaysFalse(ToRecycleBin), AErrorPath, Deleted);
                 }
               }
               else
@@ -2364,6 +2370,10 @@ static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool
                 {
                   AErrorPath = FileName2;
                 }
+                else
+                {
+                  Deleted++;
+                }
               }
             }
             while (Result && (FindNextUnchecked(SearchRec) == 0));
@@ -2376,6 +2386,10 @@ static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool
           if (Result)
           {
             Result = RemoveDir(ApiPath(FileName));
+            if (Result)
+            {
+              Deleted++;
+            }
           }
         }
       }
@@ -2415,6 +2429,11 @@ static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool
       }
       SetLastError(ErrorCode);
     }
+
+    if (Result)
+    {
+      Deleted = 1;
+    }
   }
 
   if (!Result)
@@ -2428,17 +2447,20 @@ static bool __fastcall DoRecursiveDeleteFile(const UnicodeString FileName, bool
 bool __fastcall RecursiveDeleteFile(const UnicodeString & FileName, bool ToRecycleBin)
 {
   UnicodeString ErrorPath; // unused
-  bool Result = DoRecursiveDeleteFile(FileName, ToRecycleBin, ErrorPath);
+  int Deleted;
+  bool Result = DoRecursiveDeleteFile(FileName, ToRecycleBin, ErrorPath, Deleted);
   return Result;
 }
 //---------------------------------------------------------------------------
-void __fastcall RecursiveDeleteFileChecked(const UnicodeString & FileName, bool ToRecycleBin)
+int __fastcall RecursiveDeleteFileChecked(const UnicodeString & FileName, bool ToRecycleBin)
 {
   UnicodeString ErrorPath;
-  if (!DoRecursiveDeleteFile(FileName, ToRecycleBin, ErrorPath))
+  int Deleted;
+  if (!DoRecursiveDeleteFile(FileName, ToRecycleBin, ErrorPath, Deleted))
   {
     throw EOSExtException(FMTLOAD(DELETE_LOCAL_FILE_ERROR, (ErrorPath)));
   }
+  return Deleted;
 }
 //---------------------------------------------------------------------------
 void __fastcall DeleteFileChecked(const UnicodeString & FileName)

+ 1 - 1
source/core/Common.h

@@ -116,7 +116,7 @@ UnicodeString __fastcall EncodeUrlPath(UnicodeString S);
 UnicodeString __fastcall AppendUrlParams(UnicodeString URL, UnicodeString Params);
 UnicodeString __fastcall ExtractFileNameFromUrl(const UnicodeString & Url);
 bool __fastcall RecursiveDeleteFile(const UnicodeString & FileName, bool ToRecycleBin);
-void __fastcall RecursiveDeleteFileChecked(const UnicodeString & FileName, bool ToRecycleBin);
+int __fastcall RecursiveDeleteFileChecked(const UnicodeString & FileName, bool ToRecycleBin);
 void __fastcall DeleteFileChecked(const UnicodeString & FileName);
 unsigned int __fastcall CancelAnswer(unsigned int Answers);
 unsigned int __fastcall AbortAnswer(unsigned int Answers);

+ 39 - 0
source/core/FileOperationProgress.cpp

@@ -8,8 +8,15 @@
 //---------------------------------------------------------------------------
 #define TRANSFER_BUF_SIZE 32768
 //---------------------------------------------------------------------------
+TFileOperationStatistics::TFileOperationStatistics()
+{
+  memset(this, 0, sizeof(*this));
+}
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
 TFileOperationProgressType::TPersistence::TPersistence()
 {
+  FStatistics = NULL;
   Clear(true, true);
 }
 //---------------------------------------------------------------------------
@@ -317,6 +324,38 @@ void __fastcall TFileOperationProgressType::Finish(UnicodeString FileName,
   DoProgress();
 }
 //---------------------------------------------------------------------------
+void __fastcall TFileOperationProgressType::Succeeded(int Count)
+{
+  if (FPersistence.Statistics != NULL)
+  {
+    if ((Operation == foCopy) || (Operation == foMove))
+    {
+      __int64 Transferred = FTransferredSize - FSkippedSize;
+      if (Side == osLocal)
+      {
+        FPersistence.Statistics->FilesUploaded += Count;
+        FPersistence.Statistics->TotalUploaded += Transferred;
+      }
+      else
+      {
+        FPersistence.Statistics->FilesDownloaded += Count;
+        FPersistence.Statistics->TotalDownloaded += Transferred;
+      }
+    }
+    else if (Operation == foDelete)
+    {
+      if (Side == osLocal)
+      {
+        FPersistence.Statistics->FilesDeletedLocal += Count;
+      }
+      else
+      {
+        FPersistence.Statistics->FilesDeletedRemote += Count;
+      }
+    }
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TFileOperationProgressType::SetFile(UnicodeString AFileName, bool AFileInProgress)
 {
   FFullFileName = AFileName;

+ 16 - 0
source/core/FileOperationProgress.h

@@ -20,6 +20,19 @@ typedef void __fastcall (__closure *TFileOperationFinished)
   (TFileOperation Operation, TOperationSide Side, bool Temp,
     const UnicodeString & FileName, bool Success, TOnceDoneOperation & OnceDoneOperation);
 //---------------------------------------------------------------------------
+class TFileOperationStatistics
+{
+public:
+  TFileOperationStatistics();
+
+  int FilesUploaded;
+  int FilesDownloaded;
+  int FilesDeletedLocal;
+  int FilesDeletedRemote;
+  __int64 TotalUploaded;
+  __int64 TotalDownloaded;
+};
+//---------------------------------------------------------------------------
 class TFileOperationProgressType
 {
 public:
@@ -28,6 +41,7 @@ public:
   friend class TFileOperationProgressType;
   public:
     TPersistence();
+    __property TFileOperationStatistics * Statistics = { read = FStatistics, write = FStatistics };
 
   private:
     void Clear(bool Batch, bool Speed);
@@ -41,6 +55,7 @@ public:
     std::vector<__int64> TotalTransferredThen;
     TOperationSide Side;
     __int64 TotalTransferred;
+    TFileOperationStatistics * FStatistics;
   };
 
 private:
@@ -161,6 +176,7 @@ public:
   unsigned int __fastcall CPS();
   void __fastcall Finish(UnicodeString FileName, bool Success,
     TOnceDoneOperation & OnceDoneOperation);
+  void __fastcall Succeeded(int Count = 1);
   void __fastcall Progress();
   unsigned long __fastcall LocalBlockSize();
   bool __fastcall IsLocallyDone();

+ 2 - 2
source/core/Script.cpp

@@ -1977,7 +1977,7 @@ void __fastcall TScript::SynchronizeProc(TScriptProcParams * Parameters)
         {
           PrintLine(LoadStr(SCRIPT_SYNCHRONIZE_SYNCHRONIZING));
           FTerminal->SynchronizeApply(
-            Checklist, &CopyParam, SynchronizeParams, OnTerminalSynchronizeDirectory, NULL, NULL, NULL);
+            Checklist, &CopyParam, SynchronizeParams, OnTerminalSynchronizeDirectory, NULL, NULL, NULL, NULL);
         }
       }
       else
@@ -2012,7 +2012,7 @@ void __fastcall TScript::Synchronize(const UnicodeString LocalDirectory,
       if (AChecklist->Count > 0)
       {
         FTerminal->SynchronizeApply(
-          AChecklist, &CopyParam, SynchronizeParams, OnTerminalSynchronizeDirectory, NULL, NULL, NULL);
+          AChecklist, &CopyParam, SynchronizeParams, OnTerminalSynchronizeDirectory, NULL, NULL, NULL, NULL);
       }
     }
     __finally

+ 18 - 3
source/core/Terminal.cpp

@@ -3949,6 +3949,10 @@ void __fastcall TTerminal::DoDeleteFile(const UnicodeString FileName,
       DebugAssert(FFileSystem);
       // 'File' parameter: SFTPFileSystem needs to know if file is file or directory
       FFileSystem->DeleteFile(FileName, File, Params, Action);
+      if ((OperationProgress != NULL) && (OperationProgress->Operation == foDelete))
+      {
+        OperationProgress->Succeeded();
+      }
     }
     catch(Exception & E)
     {
@@ -3973,13 +3977,18 @@ void __fastcall TTerminal::DeleteLocalFile(UnicodeString FileName,
   const TRemoteFile * /*File*/, void * Params)
 {
   StartOperationWithFile(FileName, foDelete);
+  int Deleted;
   if (OnDeleteLocalFile == NULL)
   {
-    RecursiveDeleteFileChecked(FileName, false);
+    Deleted = RecursiveDeleteFileChecked(FileName, false);
   }
   else
   {
-    OnDeleteLocalFile(FileName, FLAGSET(*((int*)Params), dfAlternative));
+    OnDeleteLocalFile(FileName, FLAGSET(*((int*)Params), dfAlternative), Deleted);
+  }
+  if (DebugAlwaysTrue((OperationProgress != NULL) && (OperationProgress->Operation == foDelete)))
+  {
+    OperationProgress->Succeeded(Deleted);
   }
 }
 //---------------------------------------------------------------------------
@@ -5913,7 +5922,8 @@ void __fastcall TTerminal::SynchronizeApply(
   TSynchronizeChecklist * Checklist,
   const TCopyParamType * CopyParam, int Params,
   TSynchronizeDirectory OnSynchronizeDirectory, TProcessedSynchronizationChecklistItem OnProcessedItem,
-  TUpdatedSynchronizationChecklistItems OnUpdatedSynchronizationChecklistItems, void * Token)
+  TUpdatedSynchronizationChecklistItems OnUpdatedSynchronizationChecklistItems, void * Token,
+  TFileOperationStatistics * Statistics)
 {
   TSynchronizeData Data;
 
@@ -5959,6 +5969,7 @@ void __fastcall TTerminal::SynchronizeApply(
   TValueRestorer<TFileOperationProgressType::TPersistence *> OperationProgressPersistenceRestorer(FOperationProgressPersistence);
   TValueRestorer<TOnceDoneOperation> OperationProgressOnceDoneOperationRestorer(FOperationProgressOnceDoneOperation);
   TFileOperationProgressType::TPersistence OperationProgressPersistence;
+  OperationProgressPersistence.Statistics = Statistics;
   FOperationProgressPersistence = &OperationProgressPersistence;
 
   try
@@ -6064,6 +6075,8 @@ void __fastcall TTerminal::SynchronizeApply(
 
   if (FOperationProgressOnceDoneOperation != odoIdle)
   {
+    // Otherwise CloseOnCompletion would have no effect
+    OperationProgressPersistenceRestorer.Release();
     CloseOnCompletion(FOperationProgressOnceDoneOperation);
   }
 
@@ -7047,6 +7060,7 @@ void __fastcall TTerminal::Source(
       Handle, TargetDir, DestFileName, CopyParam, Params, OperationProgress, Flags, Action, ChildError);
 
     LogFileDone(OperationProgress, AbsolutePath(TargetDir + DestFileName, true));
+    OperationProgress->Succeeded();
   }
 
   Handle.Release();
@@ -7420,6 +7434,7 @@ void __fastcall TTerminal::Sink(
       FileName, File, TargetDir, DestFileName, Attrs, CopyParam, Params, OperationProgress, Flags, Action);
 
     LogFileDone(OperationProgress, ExpandUNCFileName(DestFullName));
+    OperationProgress->Succeeded();
   }
 }
 //---------------------------------------------------------------------------

+ 3 - 2
source/core/Terminal.h

@@ -60,7 +60,7 @@ typedef void __fastcall (__closure *TUpdatedSynchronizationChecklistItems)(
 typedef void __fastcall (__closure *TProcessedSynchronizationChecklistItem)(
   void * Token, const TSynchronizeChecklist::TItem * Item);
 typedef void __fastcall (__closure *TDeleteLocalFileEvent)(
-  const UnicodeString FileName, bool Alternative);
+  const UnicodeString FileName, bool Alternative, int & Deleted);
 typedef int __fastcall (__closure *TDirectoryModifiedEvent)
   (TTerminal * Terminal, const UnicodeString Directory, bool SubDirs);
 typedef void __fastcall (__closure *TInformationEvent)
@@ -571,7 +571,8 @@ public:
     TSynchronizeChecklist * Checklist,
     const TCopyParamType * CopyParam, int Params,
     TSynchronizeDirectory OnSynchronizeDirectory, TProcessedSynchronizationChecklistItem OnProcessedItem,
-    TUpdatedSynchronizationChecklistItems OnUpdatedSynchronizationChecklistItems, void * Token);
+    TUpdatedSynchronizationChecklistItems OnUpdatedSynchronizationChecklistItems, void * Token,
+    TFileOperationStatistics * Statistics);
   void __fastcall SynchronizeChecklistCalculateSize(
     TSynchronizeChecklist * Checklist, const TSynchronizeChecklist::TItemList & Items,
     const TCopyParamType * CopyParam);

+ 42 - 2
source/forms/CustomScpExplorer.cpp

@@ -5294,7 +5294,7 @@ void __fastcall TCustomScpExplorerForm::Synchronize(const UnicodeString LocalDir
       {
         Terminal->SynchronizeApply(
           AChecklist, &CopyParam, Params | TTerminal::spNoConfirmation, TerminalSynchronizeDirectory,
-          SynchronizeProcessedItem, NULL, NULL);
+          SynchronizeProcessedItem, NULL, NULL, NULL);
       }
       __finally
       {
@@ -5413,6 +5413,9 @@ void __fastcall TCustomScpExplorerForm::FullSynchronize(
   BatchStart(BatchStorage);
   FAutoOperation = true;
 
+  TFileOperationStatistics Statistics;
+  TDateTime Start = Now();
+
   try
   {
     Params.OnProcessedItem = OnProcessedItem;
@@ -5422,7 +5425,8 @@ void __fastcall TCustomScpExplorerForm::FullSynchronize(
 
     Terminal->SynchronizeApply(
       Params.Checklist, Params.CopyParam, Params.Params | TTerminal::spNoConfirmation,
-      TerminalSynchronizeDirectory, SynchronizeProcessedItem, OnUpdatedSynchronizationChecklistItems, &Params);
+      TerminalSynchronizeDirectory, SynchronizeProcessedItem, OnUpdatedSynchronizationChecklistItems, &Params,
+      &Statistics);
   }
   __finally
   {
@@ -5432,6 +5436,42 @@ void __fastcall TCustomScpExplorerForm::FullSynchronize(
     BatchEnd(BatchStorage);
     ReloadLocalDirectory();
   }
+
+  if (WinConfiguration->SynchronizeSummary)
+  {
+    UnicodeString Message = MainInstructions(LoadStr(SYNCHRONIZE_COMPLETE)) + L"\n";
+
+    // The statistics should be 0 anyway in this case
+    if (FLAGCLEAR(Params.Params, TTerminal::spTimestamp))
+    {
+      Message += L"\n";
+      if (Statistics.FilesUploaded > 0)
+      {
+        Message += FORMAT(LoadStrPart(SYNCHRONIZE_SUMMARY, 1), (FormatNumber(Statistics.FilesUploaded), FormatBytes(Statistics.TotalUploaded))) + L"\n";
+      }
+      if (Statistics.FilesDownloaded > 0)
+      {
+        Message += FORMAT(LoadStrPart(SYNCHRONIZE_SUMMARY, 2), (FormatNumber(Statistics.FilesDownloaded), FormatBytes(Statistics.TotalDownloaded))) + L"\n";
+      }
+      if (Statistics.FilesDeletedLocal > 0)
+      {
+        Message += FORMAT(LoadStrPart(SYNCHRONIZE_SUMMARY, 3), (FormatNumber(Statistics.FilesDeletedLocal))) + L"\n";
+      }
+      if (Statistics.FilesDeletedRemote > 0)
+      {
+        Message += FORMAT(LoadStrPart(SYNCHRONIZE_SUMMARY, 4), (FormatNumber(Statistics.FilesDeletedRemote))) + L"\n";
+      }
+    }
+
+    TDateTime Elapsed = (Now() - Start);
+    Message += L"\n" + FORMAT(LoadStrPart(SYNCHRONIZE_SUMMARY, 5), (FormatDateTimeSpan(Configuration->TimeFormat, Elapsed)));
+    TMessageParams Params(mpNeverAskAgainCheck);
+    unsigned int Result = MessageDialog(Message, qtInformation, qaOK, HELP_NONE, &Params);
+    if (Result == qaNeverAskAgain)
+    {
+      WinConfiguration->SynchronizeSummary = false;
+    }
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::SynchronizeProcessedItem(void * Token, const TSynchronizeChecklist::TItem * ChecklistItem)

+ 2 - 0
source/forms/Preferences.cpp

@@ -262,6 +262,7 @@ void __fastcall TPreferencesDialog::LoadConfiguration()
     BOOLPROP(ConfirmExitOnCompletion);
     BOOLPROP(ConfirmCommandSession);
     BOOLPROP(ContinueOnError);
+    BOOLPROP(SynchronizeSummary);
     BOOLPROP(DDAllowMoveInit);
     BOOLPROP(BeepOnFinish);
     BOOLPROP(TemporaryDirectoryAppendSession);
@@ -645,6 +646,7 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
     BOOLPROP(ConfirmExitOnCompletion);
     BOOLPROP(ConfirmCommandSession);
     BOOLPROP(ContinueOnError);
+    BOOLPROP(SynchronizeSummary);
     BOOLPROP(DDAllowMoveInit);
     BOOLPROP(BeepOnFinish);
     BOOLPROP(TemporaryDirectoryAppendSession);

+ 15 - 5
source/forms/Preferences.dfm

@@ -76,13 +76,23 @@ object PreferencesDialog: TPreferencesDialog
           Left = 8
           Top = 8
           Width = 389
-          Height = 272
+          Height = 295
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Confirmations'
           TabOrder = 0
           DesignSize = (
             389
-            272)
+            295)
+          object SynchronizeSummaryCheck: TCheckBox
+            Left = 16
+            Top = 244
+            Width = 357
+            Height = 17
+            Anchors = [akLeft, akTop, akRight]
+            Caption = 'Sync&hronization summary'
+            TabOrder = 10
+            OnClick = ControlChange
+          end
           object ConfirmOverwritingCheck: TCheckBox
             Left = 16
             Top = 44
@@ -125,12 +135,12 @@ object PreferencesDialog: TPreferencesDialog
           end
           object ContinueOnErrorCheck: TCheckBox
             Left = 16
-            Top = 244
+            Top = 267
             Width = 357
             Height = 17
             Anchors = [akLeft, akTop, akRight]
             Caption = 'Continue on &error (advanced users)'
-            TabOrder = 10
+            TabOrder = 11
             OnClick = ControlChange
           end
           object ConfirmExitOnCompletionCheck: TCheckBox
@@ -198,7 +208,7 @@ object PreferencesDialog: TPreferencesDialog
         end
         object NotificationsGroup: TGroupBox
           Left = 8
-          Top = 286
+          Top = 309
           Width = 389
           Height = 73
           Anchors = [akLeft, akTop, akRight]

+ 1 - 0
source/forms/Preferences.h

@@ -321,6 +321,7 @@ __published:
   TPathLabel *AutomaticIniFileStorageLabel;
   TCheckBox *NaturalOrderNumericalSortingCheck;
   TLabel *DragExtStatusLabel;
+  TCheckBox *SynchronizeSummaryCheck;
   void __fastcall FormShow(TObject *Sender);
   void __fastcall ControlChange(TObject *Sender);
   void __fastcall EditorFontButtonClick(TObject *Sender);

+ 2 - 0
source/resource/TextsWin.h

@@ -615,6 +615,8 @@
 #define COPY_PARAM_SAVE_PRESET  6013
 #define RENAME_SESSION_TITLE    6014
 #define RENAME_SESSION_PROMPT   6015
+#define SYNCHRONIZE_COMPLETE    6016
+#define SYNCHRONIZE_SUMMARY     6017
 
 // 2xxx is reserved for TextsFileZilla.h
 

+ 2 - 0
source/resource/TextsWin1.rc

@@ -618,6 +618,8 @@ BEGIN
         COPY_PARAM_SAVE_PRESET, "Save as &Preset..."
         RENAME_SESSION_TITLE, "Rename session"
         RENAME_SESSION_PROMPT, "&New session name:"
+        SYNCHRONIZE_COMPLETE, "Synchronization was completed."
+        SYNCHRONIZE_SUMMARY, "Files uploaded: %s (%s)|Files downloaded: %s (%s)|Local files deleted: %s|Remote files deleted: %s|Total time: %s"
 
         WIN_VARIABLE_STRINGS, "WIN_VARIABLE"
         WINSCP_COPYRIGHT, "Copyright © 2000-2018 Martin Prikryl"

+ 7 - 0
source/windows/CustomWinConfiguration.cpp

@@ -118,6 +118,7 @@ void __fastcall TCustomWinConfiguration::Default()
   FLoginDialog.WindowSize = FormatDefaultWindowSize(640, 430);
   FLoginDialog.SiteSearch = ssSiteName;
   FConfirmExitOnCompletion = true;
+  FSynchronizeSummary = true;
   FSessionColors = L"";
   FCopyShortCutHintShown = false;
   FHttpForWebDAV = false;
@@ -147,6 +148,7 @@ void __fastcall TCustomWinConfiguration::Saved()
   BLOCK(L"Interface", CANCREATE, \
     KEY(Integer,  Interface); \
     KEY(Bool,     ConfirmExitOnCompletion); \
+    KEY(Bool,     SynchronizeSummary); \
     KEY(String,   SessionColors); \
     KEY(Bool,     CopyShortCutHintShown); \
     KEY(Bool,     HttpForWebDAV); \
@@ -497,6 +499,11 @@ void __fastcall TCustomWinConfiguration::SetConfirmExitOnCompletion(bool value)
   SET_CONFIG_PROPERTY(ConfirmExitOnCompletion);
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomWinConfiguration::SetSynchronizeSummary(bool value)
+{
+  SET_CONFIG_PROPERTY(SynchronizeSummary);
+}
+//---------------------------------------------------------------------------
 UnicodeString __fastcall TCustomWinConfiguration::GetDefaultFixedWidthFontName()
 {
   // These are defaults for respective version of Windows Notepad

+ 3 - 0
source/windows/CustomWinConfiguration.h

@@ -56,6 +56,7 @@ private:
   TInterface FDefaultInterface;
   bool FCanApplyInterfaceImmediately;
   bool FConfirmExitOnCompletion;
+  bool FSynchronizeSummary;
   UnicodeString FSessionColors;
   bool FCopyShortCutHintShown;
   bool FHttpForWebDAV;
@@ -69,6 +70,7 @@ private:
   void __fastcall SetConsoleWin(TConsoleWinConfiguration value);
   void __fastcall SetLoginDialog(TLoginDialogConfiguration value);
   void __fastcall SetConfirmExitOnCompletion(bool value);
+  void __fastcall SetSynchronizeSummary(bool value);
   UnicodeString __fastcall GetDefaultFixedWidthFontName();
   int __fastcall GetDefaultFixedWidthFontSize();
 
@@ -101,6 +103,7 @@ public:
   __property TConsoleWinConfiguration ConsoleWin = { read = FConsoleWin, write = SetConsoleWin };
   __property TLoginDialogConfiguration LoginDialog = { read = FLoginDialog, write = SetLoginDialog };
   __property bool ConfirmExitOnCompletion  = { read=FConfirmExitOnCompletion, write=SetConfirmExitOnCompletion };
+  __property bool SynchronizeSummary  = { read = FSynchronizeSummary, write = SetSynchronizeSummary };
   __property UnicodeString SessionColors  = { read=FSessionColors, write=FSessionColors };
   __property bool CopyShortCutHintShown  = { read=FCopyShortCutHintShown, write=FCopyShortCutHintShown };
   __property bool UseMasterPassword = { read = GetUseMasterPassword };

+ 2 - 2
source/windows/TerminalManager.cpp

@@ -927,9 +927,9 @@ void __fastcall TTerminalManager::UpdateTaskbarList()
   ScpExplorer->UpdateTaskbarList(FTaskbarList);
 }
 //---------------------------------------------------------------------------
-void __fastcall TTerminalManager::DeleteLocalFile(const UnicodeString FileName, bool Alternative)
+void __fastcall TTerminalManager::DeleteLocalFile(const UnicodeString FileName, bool Alternative, int & Deleted)
 {
-  RecursiveDeleteFileChecked(FileName, (WinConfiguration->DeleteToRecycleBin != Alternative));
+  Deleted = RecursiveDeleteFileChecked(FileName, (WinConfiguration->DeleteToRecycleBin != Alternative));
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminalManager::TerminalQueryUser(TObject * Sender,

+ 1 - 1
source/windows/TerminalManager.h

@@ -148,7 +148,7 @@ private:
     bool Temp, const UnicodeString & FileName, bool Success,
     TOnceDoneOperation & OnceDoneOperation);
   void __fastcall OperationProgress(TFileOperationProgressType & ProgressData);
-  void __fastcall DeleteLocalFile(const UnicodeString FileName, bool Alternative);
+  void __fastcall DeleteLocalFile(const UnicodeString FileName, bool Alternative, int & Deleted);
   void __fastcall QueueEvent(TTerminalQueue * Queue, TQueueEvent Event);
   TAuthenticateForm * __fastcall MakeAuthenticateForm(TTerminal * Terminal);
   void __fastcall MasterPasswordPrompt();

+ 4 - 18
source/windows/WinMain.cpp

@@ -225,26 +225,12 @@ void __fastcall FullSynchronize(TTerminal * Terminal, TCustomScpExplorerForm * S
   TSynchronizeMode Mode = (TSynchronizeMode)GUIConfiguration->SynchronizeMode;
   int Result =
     ScpExplorer->DoFullSynchronizeDirectories(LocalDirectory, RemoteDirectory, Mode, SaveMode, UseDefaults);
-  if (Result >= 0)
+  if ((Result >= 0) && SaveMode)
   {
-    if (SaveMode)
-    {
-      GUIConfiguration->SynchronizeMode = Mode;
-    }
-
-    if (Result > 0)
-    {
-      Terminal->CloseOnCompletion();
-    }
-    else
-    {
-      Abort();
-    }
-  }
-  else
-  {
-    Abort();
+    GUIConfiguration->SynchronizeMode = Mode;
   }
+
+  Abort();
 }
 //---------------------------------------------------------------------------
 void __fastcall Synchronize(TTerminal * Terminal, TCustomScpExplorerForm * ScpExplorer,