Martin Prikryl 12 years ago
parent
commit
0b4c19ead3
100 changed files with 1373 additions and 4257 deletions
  1. 7 1
      build.bat
  2. 1 1
      deployment/license.setup-chrome.txt
  3. 1 1
      deployment/license.setup.txt
  4. 0 0
      deployment/license.txt
  5. 23 5
      deployment/winscpsetup.iss
  6. 2 1
      dotnet/GlobalSuppressions.cs
  7. 8 7
      dotnet/internal/ExeSessionProcess.cs
  8. 30 15
      dotnet/internal/Job.cs
  9. 7 0
      dotnet/internal/Logger.cs
  10. 15 19
      dotnet/internal/UnsafeNativeMethods.cs
  11. 0 0
      dotnet/license-dotnet.txt
  12. 3 3
      dotnet/properties/AssemblyInfo.cs
  13. 0 525
      libs/mfc/source/borland.mak2
  14. 0 535
      libs/mfc/source/borland.mak2.bak
  15. 0 0
      license.txt
  16. 8 3
      readme.txt
  17. 2 2
      readme_mfc.txt
  18. 2 2
      source/Console.cbproj
  19. 1 1
      source/DragExt.cbproj
  20. 2 2
      source/DragExt64.rc
  21. 5 5
      source/WinSCP.cbproj
  22. 3 0
      source/WinSCP.cpp
  23. 26 1
      source/components/ThemePageControl.cpp
  24. 2 0
      source/components/ThemePageControl.h
  25. 18 31
      source/console/Main.cpp
  26. 40 12
      source/core/Common.cpp
  27. 11 11
      source/core/Common.h
  28. 57 33
      source/core/Configuration.cpp
  29. 3 2
      source/core/Configuration.h
  30. 25 9
      source/core/FtpFileSystem.cpp
  31. 2 0
      source/core/FtpFileSystem.h
  32. 1 8
      source/core/HierarchicalStorage.cpp
  33. 7 15
      source/core/Queue.cpp
  34. 0 1
      source/core/Queue.h
  35. 1 1
      source/core/ScpFileSystem.cpp
  36. 1 1
      source/core/SessionData.cpp
  37. 3 7
      source/core/SessionInfo.cpp
  38. 4 6
      source/core/SftpFileSystem.cpp
  39. 4 2
      source/core/Terminal.cpp
  40. 1 1
      source/core/WebDAVFileSystem.cpp
  41. 17 8
      source/filezilla/AsyncProxySocketLayer.cpp
  42. 11 67
      source/filezilla/AsyncSocketEx.cpp
  43. 0 6
      source/filezilla/AsyncSocketEx.h
  44. 27 12
      source/filezilla/AsyncSocketExLayer.cpp
  45. 82 81
      source/filezilla/AsyncSslSocketLayer.cpp
  46. 2 2
      source/filezilla/AsyncSslSocketLayer.h
  47. 17 10
      source/filezilla/FtpControlSocket.cpp
  48. 2 2
      source/filezilla/FtpListResult.cpp
  49. 2 0
      source/filezilla/MainThread.cpp
  50. 89 200
      source/filezilla/TransferSocket.cpp
  51. 4 0
      source/filezilla/TransferSocket.h
  52. 13 2
      source/forms/About.cpp
  53. 29 33
      source/forms/About.dfm
  54. 1 0
      source/forms/About.h
  55. 7 2
      source/forms/Authenticate.cpp
  56. 1 9
      source/forms/Authenticate.dfm
  57. 45 39
      source/forms/Cleanup.cpp
  58. 1 14
      source/forms/Cleanup.dfm
  59. 2 3
      source/forms/Cleanup.h
  60. 7 11
      source/forms/Console.cpp
  61. 7 11
      source/forms/Copy.cpp
  62. 3 7
      source/forms/Copy.dfm
  63. 1 1
      source/forms/Copy.h
  64. 2 2
      source/forms/CopyParamCustom.cpp
  65. 1 5
      source/forms/CopyParamCustom.dfm
  66. 2 2
      source/forms/CopyParamPreset.cpp
  67. 4 8
      source/forms/CopyParamPreset.dfm
  68. 4 4
      source/forms/CopyParams.dfm
  69. 2 2
      source/forms/CreateDirectory.cpp
  70. 13 10
      source/forms/Custom.cpp
  71. 2 2
      source/forms/CustomCommand.cpp
  72. 4 8
      source/forms/CustomCommand.dfm
  73. 167 62
      source/forms/CustomScpExplorer.cpp
  74. 6 6
      source/forms/CustomScpExplorer.dfm
  75. 10 4
      source/forms/CustomScpExplorer.h
  76. 3 3
      source/forms/EditMask.cpp
  77. 8 7
      source/forms/Editor.cpp
  78. 1 5
      source/forms/Editor.dfm
  79. 2 2
      source/forms/EditorPreferences.cpp
  80. 2 6
      source/forms/EditorPreferences.dfm
  81. 4 1
      source/forms/FileFind.cpp
  82. 11 9
      source/forms/FileFind.dfm
  83. 7 11
      source/forms/FullSynchronize.cpp
  84. 54 47
      source/forms/FullSynchronize.dfm
  85. 1 1
      source/forms/FullSynchronize.h
  86. 1 1
      source/forms/ImportSessions.cpp
  87. 1 1
      source/forms/ImportSessions.dfm
  88. 31 26
      source/forms/InputDlg.cpp
  89. 27 15
      source/forms/LocationProfiles.cpp
  90. 5 0
      source/forms/LocationProfiles.h
  91. 1 0
      source/forms/Log.cpp
  92. 1 5
      source/forms/Log.dfm
  93. 49 31
      source/forms/Login.cpp
  94. 13 13
      source/forms/Login.dfm
  95. 2 0
      source/forms/Login.h
  96. 201 65
      source/forms/MessageDlg.cpp
  97. 4 2
      source/forms/NonVisual.cpp
  98. 5 4
      source/forms/OpenDirectory.cpp
  99. 26 15
      source/forms/Preferences.cpp
  100. 0 2083
      source/forms/Preferences.cpp.LOCAL

+ 7 - 1
build.bat

@@ -2,6 +2,7 @@
 rem See 'readme' file
 set BDS=%ProgramFiles%\Embarcadero\RAD Studio\9.0
 set WITH_DRAGEXT64=0
+set WITH_DOTNET=1
 rem set DRAGEXT64CL=<path to x64 cl.exe>
 rem set DRAGEXT64INCL=<path to x64 includes>
 rem set DRAGEXT64LIB=<path to x64 libraries>
@@ -12,4 +13,9 @@ cd libs
 call buildlibs.bat
 
 cd ..\source
-C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe WinSCP.groupproj /t:%BUILD_TARGET% /p:RELEASE_TYPE=%RELEASE_TYPE%;CONFIG=%BUILD_CONFIG%;INTERM_PATH=.;FINAL_PATH=.
+%WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild.exe WinSCP.groupproj /t:%BUILD_TARGET% /p:RELEASE_TYPE=%RELEASE_TYPE%;CONFIG=%BUILD_CONFIG%;INTERM_PATH=.;FINAL_PATH=.
+
+if "%WITH_DOTNET%"=="0" goto SKIP_DOTNET
+cd ..\dotnet
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe WinSCPnet.csproj /t:Build "/p:Configuration=%BUILD_CONFIG%;Platform=AnyCPU;INTERM_PATH=.;FINAL_PATH=."
+:SKIP_DOTNET

+ 1 - 1
deployment/licence.setup-chrome.txt → deployment/license.setup-chrome.txt

@@ -1,4 +1,4 @@
-You can also review this licence and further details online at:
+You can also review this license and further details online at:
 http://winscp.net/eng/docs/license
 
   

+ 1 - 1
deployment/licence.setup.txt → deployment/license.setup.txt

@@ -1,4 +1,4 @@
-You can also review this licence and further details online at:
+You can also review this license and further details online at:
 http://winscp.net/eng/docs/license
 
   

+ 0 - 0
deployment/licence.txt → deployment/license.txt


+ 23 - 5
deployment/winscpsetup.iss

@@ -98,9 +98,9 @@ DefaultDirName={pf}\WinSCP
 DefaultGroupName=WinSCP
 AllowNoIcons=yes
 #ifdef Chrome
-LicenseFile=licence.setup-chrome.txt
+LicenseFile=license.setup-chrome.txt
 #else
-LicenseFile=licence.setup.txt
+LicenseFile=license.setup.txt
 #endif
 UninstallDisplayIcon={app}\WinSCP.exe
 OutputDir={#OutputDir}
@@ -239,7 +239,7 @@ Name: "{sendto}\{cm:SendToHookNew}"; Filename: "{app}\WinSCP.exe"; \
   Parameters: "/upload"; Tasks: sendtohook
 
 [InstallDelete]
-Type: files; Name: "{app}\licence"
+Type: files; Name: "{app}\license"
 Type: files; Name: "{group}\{cm:WebSite}.url"
 Type: files; Name: "{group}\{cm:SupportForum}.url"
 Type: files; Name: "{group}\{cm:DocumentationPage}.url"
@@ -301,7 +301,7 @@ Source: "{app}\WinSCP3.ini"; DestName: "WinSCP.ini"; DestDir: "{app}"; \
   Components: main; Flags: ignoreversion external skipifsourcedoesntexist onlyifdoesntexist
 Source: "{#ConsoleFileSource}"; DestDir: "{app}"; \
   Components: main; Flags: ignoreversion
-Source: "licence.txt"; DestDir: "{app}"; \
+Source: "license.txt"; DestDir: "{app}"; \
   Components: main; Flags: ignoreversion
 Source: "{#ShellExtFileSource}"; DestDir: "{app}"; \
   Components: shellext; \
@@ -757,6 +757,14 @@ end;
 
 #endif
 
+// WORKAROUND
+// Checkboxes and Radio buttons created on runtime do
+// not scale their height automatically
+procedure ScaleFixedHeightControl(Control: TButtonControl);
+begin
+  Control.Height := ScaleY(Control.Height);
+end;
+
 procedure InitializeWizard;
 var
   DefaultLang: Boolean;
@@ -806,7 +814,7 @@ begin
   WizardForm.TasksList.Height := WizardForm.TasksList.Height + ScaleY(8);
 
 #ifndef Chrome
-  // allow installation without requiring user to accept licence
+  // allow installation without requiring user to accept license
   WizardForm.LicenseAcceptedRadio.Checked := True;
   WizardForm.LicenseAcceptedRadio.Visible := False;
   WizardForm.LicenseLabel1.Visible := False;
@@ -861,6 +869,7 @@ begin
   TypicalTypeButton.Left := ScaleX(4);
   TypicalTypeButton.Width := SetupTypePage.SurfaceWidth -
     TypicalTypeButton.Left;
+  ScaleFixedHeightControl(TypicalTypeButton);
   TypicalTypeButton.Parent := SetupTypePage.Surface;
 
   Caption := TLabel.Create(SetupTypePage);
@@ -909,6 +918,7 @@ begin
   CustomTypeButton.Width := SetupTypePage.SurfaceWidth -
     CustomTypeButton.Left;
   CustomTypeButton.Top := Caption.Top + Caption.Height + ScaleY(10);
+  ScaleFixedHeightControl(CustomTypeButton);
   CustomTypeButton.Parent := SetupTypePage.Surface;
 
   Caption := TLabel.Create(SetupTypePage);
@@ -959,6 +969,7 @@ begin
   CommanderRadioButton.Width := InterfacePage.SurfaceWidth -
     CommanderRadioButton.Left;
   CommanderRadioButton.Top := Caption.Top + Caption.Height + ScaleY(6);
+  ScaleFixedHeightControl(CommanderRadioButton);
   CommanderRadioButton.Parent := InterfacePage.Surface;
 
   Image := TBitmapImage.Create(InterfacePage);
@@ -991,6 +1002,7 @@ begin
   ExplorerRadioButton.Width := InterfacePage.SurfaceWidth -
     ExplorerRadioButton.Left;
   ExplorerRadioButton.Top := Caption.Top + Caption.Height + ScaleY(10);
+  ScaleFixedHeightControl(ExplorerRadioButton);
   ExplorerRadioButton.Parent := InterfacePage.Surface;
 
   Image := TBitmapImage.Create(InterfacePage);
@@ -1028,12 +1040,14 @@ begin
   LaunchCheckbox.Checked := True;
   LaunchCheckbox.Left := WizardForm.YesRadio.Left;
   LaunchCheckbox.Width := WizardForm.YesRadio.Width;
+  ScaleFixedHeightControl(LaunchCheckbox);
   LaunchCheckbox.Parent := WizardForm.FinishedPage;
   OpenGettingStartedCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
   OpenGettingStartedCheckbox.Caption := ExpandConstant('{cm:OpenGettingStarted}');
   OpenGettingStartedCheckbox.Checked := True;
   OpenGettingStartedCheckbox.Left := WizardForm.YesRadio.Left;
   OpenGettingStartedCheckbox.Width := WizardForm.YesRadio.Width;
+  ScaleFixedHeightControl(OpenGettingStartedCheckbox);
   OpenGettingStartedCheckbox.Parent := WizardForm.FinishedPage;
 #ifdef Chrome
   LaunchChromeCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
@@ -1041,6 +1055,7 @@ begin
   LaunchChromeCheckbox.Checked := True;
   LaunchChromeCheckbox.Left := WizardForm.YesRadio.Left;
   LaunchChromeCheckbox.Width := WizardForm.YesRadio.Width;
+  ScaleFixedHeightControl(LaunchChromeCheckbox);
   LaunchChromeCheckbox.Parent := WizardForm.FinishedPage;
   LaunchChromeCheckbox.OnClick := @UpdatePostInstallRunCheckboxes;
 #endif
@@ -1151,6 +1166,7 @@ begin
       ChromePage.SurfaceWidth - ChromeCheckbox.Left;
     ChromeCheckbox.Caption := ExpandConstant('{cm:ChromeCheck}');
     ChromeCheckbox.Checked := True;
+    ScaleFixedHeightControl(ChromeCheckbox);
     ChromeCheckbox.Parent := ChromePage.Surface;
     ChromeCheckbox.OnClick := @ChromeCheckboxClick;
 
@@ -1160,6 +1176,8 @@ begin
     ChromeDefaultCheckbox.Left := ScaleX(4);
     ChromeDefaultCheckbox.Width :=
       ChromePage.SurfaceWidth - ChromeDefaultCheckbox.Left;
+    ChromeDefaultCheckbox.Height := ScaleY(ChromeDefaultCheckbox.Height);
+    ScaleFixedHeightControl(ChromeDefaultCheckbox);
     ChromeDefaultCheckbox.Caption := ExpandConstant('{cm:ChromeDefaultCheck}');
     ChromeDefaultCheckbox.Checked := True;
     ChromeDefaultCheckbox.Parent := ChromePage.Surface;

+ 2 - 1
dotnet/GlobalSuppressions.cs

@@ -129,7 +129,6 @@ using System.Diagnostics.CodeAnalysis;
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#CloseHandle(System.IntPtr)", Justification = "Warning is bogus.")]
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#CreateJobObject(System.IntPtr,System.String)", Justification = "Warning is bogus.")]
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#SetInformationJobObject(System.IntPtr,WinSCP.JobObjectInfoType,System.IntPtr,System.UInt32)", Justification = "Warning is bogus.")]
-[assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#AssignProcessToJobObject(System.IntPtr,System.IntPtr)", Justification = "Warning is bogus.")]
 [assembly: SuppressMessage("Microsoft.Interoperability", "CA1409:ComVisibleTypesShouldBeCreatable", Scope = "type", Target = "WinSCP.TransferResumeSupport")]
 [assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "WinSCP.Logger.#CreateCounters()")]
 [assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "WinSCP.Logger.#WriteCounters()")]
@@ -144,3 +143,5 @@ using System.Diagnostics.CodeAnalysis;
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#MapViewOfFile(Microsoft.Win32.SafeHandles.SafeFileHandle,WinSCP.FileMapAccess,System.UInt32,System.UInt32,System.UIntPtr)")]
 [assembly: SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Scope = "member", Target = "WinSCP.ExeSessionProcess.#InitializeConsole()")]
 [assembly: SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Scope = "member", Target = "WinSCP.ExeSessionProcess.#Dispose()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.Job.#.ctor(WinSCP.Logger,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.Logger.#LastWin32ErrorMessage()")]

+ 8 - 7
dotnet/internal/ExeSessionProcess.cs

@@ -128,12 +128,6 @@ namespace WinSCP
 
                 _logger.WriteLine("Started process {0}", _process.Id);
 
-                if (_session.GuardProcessWithJobInternal)
-                {
-                    _job = new Job();
-                    _job.AddProcess(_process.Handle);
-                }
-
                 _thread = new Thread(ProcessEvents);
                 _thread.IsBackground = true;
                 _thread.Start();
@@ -393,7 +387,7 @@ namespace WinSCP
 
                     int instanceNumber = random.Next(1000);
 
-                    _instanceName = string.Format(CultureInfo.InvariantCulture, "_{0}_{1}", process, instanceNumber);
+                    _instanceName = string.Format(CultureInfo.InvariantCulture, "_{0}_{1}_{2}", process, GetHashCode(), instanceNumber);
                     _logger.WriteLine("Trying event {0}", _instanceName);
                     if (!TryCreateEvent(ConsoleEventRequest + _instanceName, out _requestEvent))
                     {
@@ -425,6 +419,12 @@ namespace WinSCP
                 {
                     commStruct.InitHeader();
                 }
+
+                if (_session.GuardProcessWithJobInternal)
+                {
+                    string jobName = ConsoleJob + _instanceName;
+                    _job = new Job(_logger, jobName);
+                }
             }
         }
 
@@ -683,6 +683,7 @@ namespace WinSCP
         private const string ConsoleEventRequest = "WinSCPConsoleEventRequest";
         private const string ConsoleEventResponse = "WinSCPConsoleEventResponse";
         private const string ConsoleEventCancel = "WinSCPConsoleEventCancel";
+        private const string ConsoleJob = "WinSCPConsoleJob";
         private const string ExeExecutableFileName = "winscp.exe";
 
         private Process _process;

+ 30 - 15
dotnet/internal/Job.cs

@@ -1,25 +1,43 @@
 using System;
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 
 namespace WinSCP
 {
     internal class Job : IDisposable
     {
-        public Job()
+        public Job(Logger logger, string name)
         {
-            _handle = UnsafeNativeMethods.CreateJobObject(IntPtr.Zero, null);
+            _logger = logger;
+            _handle = UnsafeNativeMethods.CreateJobObject(IntPtr.Zero, name);
 
-            JobObjectBasicLimitInformation info = new JobObjectBasicLimitInformation();
-            info.LimitFlags = 0x2000;
+            if (_handle == IntPtr.Zero)
+            {
+                _logger.WriteLine("Cannot create job ({0})", Logger.LastWin32ErrorMessage());
+            }
+            else
+            {
+                _logger.WriteLine("Job created");
 
-            JobObjectExtendedLimitInformation extendedInfo = new JobObjectExtendedLimitInformation();
-            extendedInfo.BasicLimitInformation = info;
+                JobObjectBasicLimitInformation info = new JobObjectBasicLimitInformation();
+                info.LimitFlags = 0x2000; // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
 
-            int length = Marshal.SizeOf(typeof(JobObjectExtendedLimitInformation));
-            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
-            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
+                JobObjectExtendedLimitInformation extendedInfo = new JobObjectExtendedLimitInformation();
+                extendedInfo.BasicLimitInformation = info;
 
-            UnsafeNativeMethods.SetInformationJobObject(_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length);
+                int length = Marshal.SizeOf(typeof(JobObjectExtendedLimitInformation));
+                IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
+                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
+
+                if (UnsafeNativeMethods.SetInformationJobObject(_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
+                {
+                    _logger.WriteLine("Job set to kill all processes");
+                }
+                else
+                {
+                    _logger.WriteLine("Cannot set job to kill all processes ({0})", Logger.LastWin32ErrorMessage());
+                }
+            }
         }
 
         ~Job()
@@ -40,15 +58,12 @@ namespace WinSCP
 
         public void Close()
         {
+            _logger.WriteLine("Closing job");
             UnsafeNativeMethods.CloseHandle(_handle);
             _handle = IntPtr.Zero;
         }
 
-        public bool AddProcess(IntPtr handle)
-        {
-            return UnsafeNativeMethods.AssignProcessToJobObject(_handle, handle);
-        }
-
         private IntPtr _handle;
+        private Logger _logger;
     }
 }

+ 7 - 0
dotnet/internal/Logger.cs

@@ -5,6 +5,8 @@ using System.Threading;
 using System.Reflection;
 using System.Diagnostics;
 using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
 
 namespace WinSCP
 {
@@ -282,6 +284,11 @@ namespace WinSCP
             WriteLine("Working directory: {0}", Environment.CurrentDirectory);
         }
 
+        public static string LastWin32ErrorMessage()
+        {
+            return new Win32Exception(Marshal.GetLastWin32Error()).Message;
+        }
+
         private StreamWriter _writter;
         private string _logPath;
         private readonly Dictionary<int, int> _indents = new Dictionary<int, int>();

+ 15 - 19
dotnet/internal/UnsafeNativeMethods.cs

@@ -18,9 +18,9 @@ namespace WinSCP
     [StructLayout(LayoutKind.Sequential)]
     internal struct SecurityAttributes
     {
-        public int nLength;
+        public UInt32 nLength;
         public IntPtr lpSecurityDescriptor;
-        public int bInheritHandle;
+        public Int32 bInheritHandle;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -28,13 +28,13 @@ namespace WinSCP
     {
         public Int64 PerProcessUserTimeLimit;
         public Int64 PerJobUserTimeLimit;
-        public Int16 LimitFlags;
-        public UInt32 MinimumWorkingSetSize;
-        public UInt32 MaximumWorkingSetSize;
-        public Int16 ActiveProcessLimit;
-        public Int64 Affinity;
-        public Int16 PriorityClass;
-        public Int16 SchedulingClass;
+        public UInt32 LimitFlags;
+        public UIntPtr MinimumWorkingSetSize;
+        public UIntPtr MaximumWorkingSetSize;
+        public UInt32 ActiveProcessLimit;
+        public UIntPtr Affinity;
+        public UInt32 PriorityClass;
+        public UInt32 SchedulingClass;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -53,10 +53,10 @@ namespace WinSCP
     {
         public JobObjectBasicLimitInformation BasicLimitInformation;
         public IOCounters IoInfo;
-        public UInt32 ProcessMemoryLimit;
-        public UInt32 JobMemoryLimit;
-        public UInt32 PeakProcessMemoryUsed;
-        public UInt32 PeakJobMemoryUsed;
+        public UIntPtr ProcessMemoryLimit;
+        public UIntPtr JobMemoryLimit;
+        public UIntPtr PeakProcessMemoryUsed;
+        public UIntPtr PeakJobMemoryUsed;
     }
 
     [Flags]
@@ -100,15 +100,11 @@ namespace WinSCP
         [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
         public static extern int CloseHandle(IntPtr hObject);
 
-        [DllImport("kernel32", CharSet = CharSet.Unicode)]
+        [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
         public static extern IntPtr CreateJobObject(IntPtr a, string lpName);
 
-        [DllImport("kernel32")]
-        [return: MarshalAs(UnmanagedType.Bool)]
-        public static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
-
         [DllImport("kernel32", SetLastError = true)]
         [return: MarshalAs(UnmanagedType.Bool)]
-        public static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
+        public static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
     }
 }

+ 0 - 0
dotnet/licence-dotnet.txt → dotnet/license-dotnet.txt


+ 3 - 3
dotnet/properties/AssemblyInfo.cs

@@ -19,9 +19,9 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a0b93468-d98a-4845-a234-8076229ad93f")]
 
-[assembly: AssemblyVersion("1.1.3.0")]
-[assembly: AssemblyFileVersion("1.1.3.0")]
-[assembly: AssemblyInformationalVersionAttribute("5.2.3.0")]
+[assembly: AssemblyVersion("1.1.4.0")]
+[assembly: AssemblyFileVersion("1.1.4.0")]
+[assembly: AssemblyInformationalVersionAttribute("5.2.4.0")]
 
 [assembly: CLSCompliant(true)]
 

+ 0 - 525
libs/mfc/source/borland.mak2

@@ -1,525 +0,0 @@
-# BORLAND.MAK: Borland makefile for MFC variants
-#
-# Usage: MAKE -F BORLAND.MAK CLEAN        (removes all intermediary files)
-#    or: MAKE -F BORLAND.MAK options      (builds library variant (see below))
-# Note that an MAKE CLEAN should be performed before building a new variant.
-#
-# 'Options' are one of each of:
-#   "DLL"              (defaults to 0)
-#           If this item is 0, then a normal library is generated.
-#                       DLL=1 is obsolete and not supported by this release.
-#           If this item is 2, objects suitable for the shared DLL version
-#           of MFC are created.  Note: DLL=2 is to be used only from
-#           MFCDLL.MAK, MFCOLE.MAK, or MFCDB.MAK
-#
-#   "DEBUG"             (defaults to 1)
-#           If this item is 1, diagnostic support is compiled into
-#           the library.  If this item is 0, then diagnostic support
-#           is disabled. Diagnostic support does not include debug info
-#           information.
-#
-#   "OBJ=.\obj"         (defaults to '$$(MODEL)$(BASE)$(DEBUG)')
-#           This optional specification specifies where temporary OBJ files
-#           are stored during the build process.  The directory is created or
-#           removed as necessary.
-#
-#   "OPT="              (no default value)
-#           This allows additional compiler options to be added to the build.
-#           If more than one switch is desired, put double-quotes around the
-#           whole OPT= argument, e.g., "OPT=/J /W3".
-#
-#   "NO_PCH=1"
-#           Set this item to override the default use of precompiled headers.
-#
-#   "BROWSE=1"          (defaults to 0)
-#           Set this option to build browse info
-#
-#   "MT=0"              (defaults to 1)
-#           To build a non-multithreaded library instead of the default
-#           (which enables multitheading and uses the multithread
-#           C-runtimes) you can use MT=0.
-#
-#=============================================================================
-# Borland Additional flags
-#=============================================================================
-#
-#   "NO_CLEAN_PCH"      (defaults to off)
-#           To prevent deleting an existing PCH (.csm) file
-#
-#   "DBGINFO"           (defaults to 0)
-#           If this item is 1, Turbo Debugger debug info is compiled into
-#           the library.  If it's 0, then no debugger info is added.
-#
-#   "LIBDIR=..\..\lib"
-#           Directory for libraries that are created
-#
-#   "MFCINCL=..\..\include\mfc"
-#           MFC Include directory base
-#
-#   "BCINCL=..\..\include"
-#           BC++ Include directory
-#
-#############################################################################
-# Define defaults if not defined
-UNICODE=1
-# Default to DEBUG mode
-!ifndef DEBUG
-DEBUG=0
-!endif
-
-# Default to No Debug Info mode
-!ifndef DBGINFO
-DBGINFO=0
-!endif
-
-# Check for MS syntax
-!ifdef CODEVIEW
-DBGINFO=$(CODEVIEW)
-!endif
-
-# Default to NOT DLL
-!ifndef DLL
-DLL=0
-!endif
-
-# Default to no BROWSE info
-!ifndef BROWSE
-BROWSE=0
-!endif
-
-# Default to no precompiled headers
-#!ifndef NO_PCH
-#NO_PCH=1
-#!endif
-
-# Default to _MBCS build
-MBCS=1
-
-# Default to multithreading support
-!ifndef MT
-MT=1
-!endif
-
-# Default to not enable Borland CodeGuard
-!ifndef CG
-CG=0
-!endif
-
-# Lib directory
-!ifndef LIBDIR
-LIBDIR=..\..\LIB
-!endif
-
-# Lib Path
-!ifndef LPATH
-LPATH=..\..\LIB;..\..\LIB\PSDK
-!endif
-
-# MFC Include directory base
-!ifndef MFCINCL
-MFCINCL=..\..\include\mfc
-!endif
-
-# BC Include directory
-!ifndef BCINCL
-BCINCL=..\..\include;..\..\include\atl
-!endif
-
-# Disable Warnings
-!ifndef NO_WARNINGS
-NO_WARNINGS=0
-!endif
-
-
-# Clean up PCH file
-!ifndef NO_CLEAN_PCH
-NO_CLEAN_PCH=0
-!endif
-
-BASE=W
-MODEL=U
-TARGDEFS=/D_UNICODE /DUNICODE /D_AFX_NO_OLEDB_SUPPORT /D_AFX_NO_OCC_SUPPORT
-!if "$(MBCS)" != "0"
-TARGDEFS=$(TARGDEFS) /D_MBCS
-!endif
-PLATFORM=INTEL
-
-LFLAGS=$(LFLAGS) /j$(LPATH) /L$(LPATH)
-!if "$(NO_WARNINGS)" == "1"
-LFLAGS=$(LFLAGS) /w-
-!endif
-
-#
-# DEBUG OPTIONS
-#
-!if "$(DEBUG)" != "0"
-
-DEBUGSUF=D
-DEBDEFS=/D_DEBUG
-DEBOPTS=
-
-!endif
-
-#
-# NON-DEBUG OPTIONS
-#
-!if "$(DEBUG)" == "0"
-
-DEBUGSUF=
-DEBDEFS=
-DEBOPTS=/O1
-
-!endif
-
-!if "$(DBGINFO)" == "1"
-DEBOPTS=/Od /v /vi
-!endif
-
-!if "$(CG)" == "1"
-DEBOPTS=$(DEBOPTS) -vG
-!endif
-
-#
-# PLATFORM options
-#
-CC=bcc32
-LIB32=tlib
-!ifndef LINK32
-LINK32=ilink32 /Gn
-!endif
-CL_MODEL=/D_X86_
-GENDEFS=perl -w $(MAKEDIR)\gendefs.pl
-
-# TYPE = Library Type Designator
-#       c = normal C library
-#       d = DLL library
-TYPE=c
-
-!if "$(DEXT)" == ""
-DEXT=
-!endif
-
-#
-# Object File Directory
-#
-!if "$(OBJ)" == ""
-D=$$$(MODEL)$(BASE)$(DEBUGSUF)$(DEXT)    # subdirectory specific to variant
-!else
-D=$(OBJ)                                 # User specified directory
-!endif
-
-#
-# _AFXDLL DLL Variant
-#
-!if "$(DLL)" == "2"
-!if "$(TARG)" == ""
-!error DLL=2 is used only from BFCDLL.MAK, BFCOLE.MAK, or BFCDB.MAK
-!endif
-GOAL=$(TARG)
-TYPE=e
-!if "$(OBJ)" == ""
-D=DLL$(DEBUGSUF).$(BASE)
-!if "$(UNICODE)" == "1"
-D=$(MODEL)$(D)
-!endif
-D=$$$(D)
-!endif
-TARGDEFS=$(TARGDEFS) /D_WINDLL /D_AFXDLL
-!else
-GOAL=$(MODEL)afx$(TYPE)$(BASE)$(DEBUGSUF)
-!endif
-
-#
-# Threaded-ness
-#
-!if "$(MT)" != "0"
-TARGOPTS=$(TARGOPTS) /WM /D_MT=1
-!else
-!error This makefile only builds multi-threaded libraries, not single threaded.
-!endif
-
-#
-# Import libraries for the DLL builds
-#
-IMPORT_LIBS=import32.lib inet.lib odbc32.lib
-
-#
-# COMPILER OPTIONS
-#
-
-DEFS=$(DEFS)  -D_declspec=__declspec /D_WCHAR_T_DEFINED /D__MSC /D_ANONYMOUS_STRUCT -D_MSC_VER=1200 -D_WINDOWS
-!if "$(DLL)" == "2"
-DEFS=$(DEFS) /D_RTLDLL /D_DLL
-!endif
-CL_OPT= -a8 -g0 -j2 -jb -VF4 $(INCROPTS) $(DEBOPTS) $(CVOPTS) $(TARGOPTS)
-
-#
-# Internal debugging switch for the compiler (-=xx)
-#
-!ifdef COMPILER_DIAG
-CL_OPT= $(CL_OPT) -=o
-!endif
-
-!if "$(BROWSE)" != "0"
-CL_OPT=-R $(CL_OPT)
-!endif
-
-CL_OPT=-n$(D) $(CL_OPT)
-
-!if "$(NO_WARNINGS)" == "1"
-CL_OPT=$(CL_OPT) -w-
-!endif
-
-!if "$(DEVBUILD)" != "0"
-CL_OPT=$(CL_OPT) /D_AFX_DEVBUILD
-!endif
-
-DEFS=$(DEFS) $(DEBDEFS) $(TARGDEFS)
-
-#############################################################################
-# Library Components
-
-OBJECT=objcore.obj except.obj \
-	validadd.obj dumpcont.obj dumpflt.obj \
-	arccore.obj arcobj.obj arcex.obj arcstrm.obj
-
-# non-shared diagnostics
-OBJDIAG=dumpinit.obj dumpout.obj \
-	afxasert.obj afxmem.obj afxabort.obj
-
-FILES=filecore.obj filetxt.obj filemem.obj fileshrd.obj \
-	filex.obj filest.obj
-
-COLL1=array_b.obj array_d.obj array_p.obj array_o.obj \
-	array_s.obj array_u.obj array_w.obj \
-	list_o.obj list_p.obj list_s.obj
-
-COLL2=map_pp.obj map_pw.obj map_so.obj \
-	map_sp.obj map_ss.obj map_wo.obj map_wp.obj plex.obj
-
-MISC=\
-	strcore.obj strex.obj timecore.obj \
-	afxdbcs.obj afxstate.obj afxtls.obj fixalloc.obj \
-        mtcore.obj mtex.obj
-
-WINDOWS=winhand.obj
-
-DIALOG=
-
-WINMISC=afxcrit.obj winstr.obj winutil.obj auxdata.obj wingdi.obj
-
-DOCVIEW=
-
-INTERNET=inet.obj filefind.obj
-!if "$(UNICODE)" == "1"
-#INTERNET=$(INTERNET) isapimix.obj
-!endif
-
-APPLICATION=appterm.obj appui1.obj appinit.obj apphelp.obj thrdcore.obj
-
-!if "$(DLL)" != "2"
-#APPLICATION=$(APPLICATION) app3ds.obj \
-#	nolib.obj appmodul.obj dllmodul.obj oleexp.obj dumpstak.obj
-!endif
-
-# ODBC components:
-DB=\
-	dbcore.obj dbrfx.obj dbview.obj dbflt.obj \
-	dblong.obj dbvar.obj
-
-#
-# DAO is not supported under Borland C++
-#
-#DB= $(DB) daocore.obj daodfx.obj daoview.obj viewoled.obj
-#
-
-SOCKETS=sockcore.obj
-
-OLEREQ=olelock.obj
-
-OLE=\
-	oleinit.obj olecli1.obj olecli2.obj \
-	olecli3.obj olecnvrt.obj oledobj1.obj oledobj2.obj \
-	oledisp1.obj oledisp2.obj oledlgs1.obj oledlgs2.obj \
-	oledlgs3.obj oledata.obj olevar.obj olevar1.obj \
-	oledoc1.obj oledoc2.obj oledrop1.obj oledrop2.obj \
-	olemsgf.obj oleenum.obj olefact.obj oleipfrm.obj \
-	olelink.obj olemisc.obj olestrm.obj olesvr1.obj \
-	olesvr2.obj olereg.obj oletsvr.obj oleui1.obj \
-	oleui2.obj oleunk.obj oleverb.obj olecall.obj \
-	viewrich.obj oledll.obj oletyplb.obj \
-	olemon.obj winctrl5.obj viewhtml.obj \
-	occmgr.obj occevent.obj occcont.obj occsite.obj \
-	occlock.obj occddx.obj occddxf.obj occdlg.obj \
-	oledocvw.obj oledocob.obj oledoctg.obj oledocip.obj \
-	oledoccl.obj oleasmon.obj olebar.obj
-
-OLECTL=
-
-!if "$(DEBUG)" == "1"
-OLECTL=$(OLECTL) ctlinl.obj
-!endif
-
-# Borland enhancement:
-!if "$(DEBUG)" == "1" && "$(MONOLITHIC)" == "1"
-OLE=$(OLE) dllole.obj
-!endif
-
-OLEDLL=$(OLE) $(OLECTL) $(OLEASM)
-
-!if "$(DEBUG)" == "1"
-INLINES = afxinl1.obj afxinl2.obj afxinl3.obj
-!else
-INLINES =
-!endif
-
-CPP_OBJS=$(OBJECT) $(OBJDIAG) $(INLINES) $(FILES) $(COLL1) $(COLL2) $(MISC) \
-	$(WINDOWS) $(DIALOG) $(WINMISC) $(DOCVIEW) $(APPLICATION) \
-	$(SOCKETS) $(OLEREQ) $(OLE) $(DAO) $(DB) $(INTERNET) $(OLECTL)
-
-
-OBJS=$(CPP_OBJS) $(OLEASM)
-
-
-#############################################################################
-# Standard tools
-
-#############################################################################
-# Set CPPFLAGS for use with .cpp.obj and .c.obj rules
-# Define rule for use with OBJ directory
-# C++ uses a PCH file
-
-CPPFLAGS=$(CPPFLAGS) $(CL_MODEL) $(CL_OPT) $(PDBOPTS) $(DEFS) $(OPT)
-BORRSP=bor.rsp
-
-!ifndef NO_PCH
-!ifndef PCH_FILE
-# put the PCH file in the OBJ directory for easy cleanup later
-PCH_FILE=$(D)\stdafx
-!if "$(BROWSE)" != "0"
-PCH_FILE=$(PCH_FILE)b
-!endif
-PCH_FILE=$(PCH_FILE).csm
-!endif
-!ifndef PCH_CPP
-PCH_CPP=objcore
-!endif
-PCH_CMD=-Hc -H=$(PCH_FILE)
-!else
-PCH_CMD=-H-
-PCH_FILE=
-!endif
-CPPFLAGS=$(CPPFLAGS) $(PCH_CMD)
-
-!ifdef JOHNS_CPP32
-PREPROCFLAGS=-Sd -Sk -Sr -P-
-!else
-PREPROCFLAGS=-Sd -Sk -Ss -P
-!endif
-
-.SUFFIXES: .cpp
-
-.path.obj = $(D)
-
-
-.cpp.i:
-	cpp32 @$(BORRSP) $(PREPROCFLAGS) $<
-
-.cpp.obj:
-!if $d(FORCE_CPP32)
-	cpp32 @$(BORRSP) $(PREPROCFLAGS) $<
-!else
-	$(CC) @$(BORRSP) /c { $< }
-!endif
-
-!ifndef NO_PCH
-PCH_TARGETS=$(PCH_FILE) $(D)\$(PCH_CPP).obj
-!endif
-
-#############################################################################
-# Goals to build
-
-GOALS=log.mode create.dir create.rsp
-!ifndef NO_PCH
-GOALS=$(GOALS) $(PCH_TARGETS)
-!endif
-GOALS=$(GOALS) $(LIBDIR)\$(GOAL).lib
-
-goal: $(GOALS)
-
-log.mode:
-  @-echo BORLAND.MAK: 
-  @-echo              GOAL=$(GOAL), DLL=$(DLL),  DEBUG=$(DEBUG), 
-  @-echo              DBGINFO=$(DBGINFO), RCDEFINES=$(RCDEFINES), 
-  @-echo              CL_OPT=$(CL_OPT), DEFS=$(DEFS),
-  @-echo              CPPFLAGS=$(CPPFLAGS)	 
-  @-echo              D=$(D)
-  @-echo              STATICLINK_OBJS=$(STATICLINK_OBJS)
-
-create.rsp:
-!ifndef NO_PCH
-!if "$(NO_CLEAN_PCH)" == "0"
-    @-if exist $(PCH_FILE) echo Erasing PCH file: $(PCH_FILE) for a fresh build
-    @-if exist $(PCH_FILE) erase $(PCH_FILE) > nul 
-!endif
-!endif
-    @-if exist $(BORRSP) erase $(BORRSP) > nul
-    copy &&|
-$(CPPFLAGS) -I$(BCINCL);$(MFCINCL)
-| $(BORRSP)
-
-create.dir:
-	@-if not exist $(D) mkdir $(D)
-	@-if not exist $(LIBDIR) mkdir $(LIBDIR)
-
-clean:
-	@-if exist *.map erase *.map
-	@-if exist *.dll erase *.dll
-	@-if exist *.cfg erase *.cfg
-	@-if exist *.rsp erase *.rsp
-	@-if exist *.tds erase *.tds
-!if $d(INTEGRATION_BUILD)
-	@-if exist $(PLATFORM)\*.def erase $(PLATFORM)\*.def
-!endif
-	@-if exist $$DLLD.W  rmdir $$DLLD.W /s
-	@-if exist $$DLL.W rmdir $$DLL.W /s
-	@-if exist $$NW rmdir $$NW /s
-	@-if exist $$NWD rmdir $$NWD /s
-
-
-#############################################################################
-# Precompiled header file
-
-!ifndef NO_PCH
-
-!if "$(DEBUG)" == "1"
-HDRS =$(MFCINCL)\*.h
-!else
-HDRS =$(MFCINCL)\*.h $(MFCINCL)\*.inl
-!endif
-
-!if "$(DLL)" != "2"
-$(PCH_TARGETS): $(PCH_CPP).cpp
-	$(CC) @&&!
-$(CPPFLAGS) -I$(BCINCL);$(MFCINCL) /c $(PCH_CPP).cpp
-!
-
-!endif # DLL != 2
-!endif # NO_PCH
-
-
-#############################################################################
-# Build the library from the up-to-date objs
-
-!if "$(DLL)" != "2"
-# Build final library
-$(LIBDIR)\$(GOAL).lib: $(OBJS)
-	@-if exist $@ erase $@
-	@$(LIB32) $@ /P2048 @&&!
-+-$(**: = &^
-+-)
-!
-
-!endif #DLL!=2
-
-#############################################################################

+ 0 - 535
libs/mfc/source/borland.mak2.bak

@@ -1,535 +0,0 @@
-# BORLAND.MAK: Borland makefile for MFC variants
-#
-# Usage: MAKE -F BORLAND.MAK CLEAN        (removes all intermediary files)
-#    or: MAKE -F BORLAND.MAK options      (builds library variant (see below))
-# Note that an MAKE CLEAN should be performed before building a new variant.
-#
-# 'Options' are one of each of:
-#   "DLL"              (defaults to 0)
-#           If this item is 0, then a normal library is generated.
-#                       DLL=1 is obsolete and not supported by this release.
-#           If this item is 2, objects suitable for the shared DLL version
-#           of MFC are created.  Note: DLL=2 is to be used only from
-#           MFCDLL.MAK, MFCOLE.MAK, or MFCDB.MAK
-#
-#   "DEBUG"             (defaults to 1)
-#           If this item is 1, diagnostic support is compiled into
-#           the library.  If this item is 0, then diagnostic support
-#           is disabled. Diagnostic support does not include debug info
-#           information.
-#
-#   "OBJ=.\obj"         (defaults to '$$(MODEL)$(BASE)$(DEBUG)')
-#           This optional specification specifies where temporary OBJ files
-#           are stored during the build process.  The directory is created or
-#           removed as necessary.
-#
-#   "OPT="              (no default value)
-#           This allows additional compiler options to be added to the build.
-#           If more than one switch is desired, put double-quotes around the
-#           whole OPT= argument, e.g., "OPT=/J /W3".
-#
-#   "NO_PCH=1"
-#           Set this item to override the default use of precompiled headers.
-#
-#   "BROWSE=1"          (defaults to 0)
-#           Set this option to build browse info
-#
-#   "MT=0"              (defaults to 1)
-#           To build a non-multithreaded library instead of the default
-#           (which enables multitheading and uses the multithread
-#           C-runtimes) you can use MT=0.
-#
-#=============================================================================
-# Borland Additional flags
-#=============================================================================
-#
-#   "NO_CLEAN_PCH"      (defaults to off)
-#           To prevent deleting an existing PCH (.csm) file
-#
-#   "DBGINFO"           (defaults to 0)
-#           If this item is 1, Turbo Debugger debug info is compiled into
-#           the library.  If it's 0, then no debugger info is added.
-#
-#   "LIBDIR=..\..\lib"
-#           Directory for libraries that are created
-#
-#   "MFCINCL=..\..\include\mfc"
-#           MFC Include directory base
-#
-#   "BCINCL=..\..\include"
-#           BC++ Include directory
-#
-#############################################################################
-# Define defaults if not defined
-UNICODE=1
-# Default to DEBUG mode
-!ifndef DEBUG
-DEBUG=0
-!endif
-
-# Default to No Debug Info mode
-!ifndef DBGINFO
-DBGINFO=0
-!endif
-
-# Check for MS syntax
-!ifdef CODEVIEW
-DBGINFO=$(CODEVIEW)
-!endif
-
-# Default to NOT DLL
-!ifndef DLL
-DLL=0
-!endif
-
-# Default to no BROWSE info
-!ifndef BROWSE
-BROWSE=0
-!endif
-
-# Default to no precompiled headers
-#!ifndef NO_PCH
-#NO_PCH=1
-#!endif
-
-# Default to _MBCS build
-MBCS=1
-
-# Default to multithreading support
-!ifndef MT
-MT=1
-!endif
-
-# Default to not enable Borland CodeGuard
-!ifndef CG
-CG=0
-!endif
-
-# Lib directory
-!ifndef LIBDIR
-LIBDIR=..\..\LIB
-!endif
-
-# Lib Path
-!ifndef LPATH
-LPATH=..\..\LIB;..\..\LIB\PSDK
-!endif
-
-# MFC Include directory base
-!ifndef MFCINCL
-MFCINCL=..\..\include\mfc
-!endif
-
-# BC Include directory
-!ifndef BCINCL
-BCINCL=..\..\include;..\..\include\atl
-!endif
-
-# Disable Warnings
-!ifndef NO_WARNINGS
-NO_WARNINGS=0
-!endif
-
-
-# Clean up PCH file
-!ifndef NO_CLEAN_PCH
-NO_CLEAN_PCH=0
-!endif
-
-BASE=W
-MODEL=U
-TARGDEFS=/D_UNICODE /DUNICODE /D_AFX_NO_OLEDB_SUPPORT /D_AFX_NO_OCC_SUPPORT
-!if "$(MBCS)" != "0"
-TARGDEFS=$(TARGDEFS) /D_MBCS
-!endif
-PLATFORM=INTEL
-
-LFLAGS=$(LFLAGS) /j$(LPATH) /L$(LPATH)
-!if "$(NO_WARNINGS)" == "1"
-LFLAGS=$(LFLAGS) /w-
-!endif
-
-#
-# DEBUG OPTIONS
-#
-!if "$(DEBUG)" != "0"
-
-DEBUGSUF=D
-DEBDEFS=/D_DEBUG
-DEBOPTS=
-
-!endif
-
-#
-# NON-DEBUG OPTIONS
-#
-!if "$(DEBUG)" == "0"
-
-DEBUGSUF=
-DEBDEFS=
-DEBOPTS=/O1
-
-!endif
-
-!if "$(DBGINFO)" == "1"
-DEBOPTS=/Od /v /vi
-!endif
-
-!if "$(CG)" == "1"
-DEBOPTS=$(DEBOPTS) -vG
-!endif
-
-#
-# PLATFORM options
-#
-CC=bcc32
-LIB32=tlib
-!ifndef LINK32
-LINK32=ilink32 /Gn
-!endif
-CL_MODEL=/D_X86_
-GENDEFS=perl -w $(MAKEDIR)\gendefs.pl
-
-# TYPE = Library Type Designator
-#       c = normal C library
-#       d = DLL library
-TYPE=c
-
-!if "$(DEXT)" == ""
-DEXT=
-!endif
-
-#
-# Object File Directory
-#
-!if "$(OBJ)" == ""
-D=$$$(MODEL)$(BASE)$(DEBUGSUF)$(DEXT)    # subdirectory specific to variant
-!else
-D=$(OBJ)                                 # User specified directory
-!endif
-
-#
-# _AFXDLL DLL Variant
-#
-!if "$(DLL)" == "2"
-!if "$(TARG)" == ""
-!error DLL=2 is used only from BFCDLL.MAK, BFCOLE.MAK, or BFCDB.MAK
-!endif
-GOAL=$(TARG)
-TYPE=e
-!if "$(OBJ)" == ""
-D=DLL$(DEBUGSUF).$(BASE)
-!if "$(UNICODE)" == "1"
-D=$(MODEL)$(D)
-!endif
-D=$$$(D)
-!endif
-TARGDEFS=$(TARGDEFS) /D_WINDLL /D_AFXDLL
-!else
-GOAL=$(MODEL)afx$(TYPE)$(BASE)$(DEBUGSUF)
-!endif
-
-#
-# Threaded-ness
-#
-!if "$(MT)" != "0"
-TARGOPTS=$(TARGOPTS) /WM /D_MT=1
-!else
-!error This makefile only builds multi-threaded libraries, not single threaded.
-!endif
-
-#
-# Import libraries for the DLL builds
-#
-IMPORT_LIBS=import32.lib inet.lib odbc32.lib
-
-#
-# COMPILER OPTIONS
-#
-
-DEFS=$(DEFS)  -D_declspec=__declspec /D_WCHAR_T_DEFINED /D__MSC /D_ANONYMOUS_STRUCT -D_MSC_VER=1200 -D_WINDOWS
-!if "$(DLL)" == "2"
-DEFS=$(DEFS) /D_RTLDLL /D_DLL
-!endif
-CL_OPT= -a8 -g0 -j2 -jb -VF4 $(INCROPTS) $(DEBOPTS) $(CVOPTS) $(TARGOPTS)
-
-#
-# Internal debugging switch for the compiler (-=xx)
-#
-!ifdef COMPILER_DIAG
-CL_OPT= $(CL_OPT) -=o
-!endif
-
-!if "$(BROWSE)" != "0"
-CL_OPT=-R $(CL_OPT)
-!endif
-
-CL_OPT=-n$(D) $(CL_OPT)
-
-!if "$(NO_WARNINGS)" == "1"
-CL_OPT=$(CL_OPT) -w-
-!endif
-
-!if "$(DEVBUILD)" != "0"
-CL_OPT=$(CL_OPT) /D_AFX_DEVBUILD
-!endif
-
-DEFS=$(DEFS) $(DEBDEFS) $(TARGDEFS)
-
-#############################################################################
-# Library Components
-
-OBJECT=objcore.obj except.obj \
-	validadd.obj dumpcont.obj dumpflt.obj \
-	arccore.obj arcobj.obj arcex.obj arcstrm.obj
-
-# non-shared diagnostics
-OBJDIAG=dumpinit.obj dumpout.obj \
-	afxasert.obj afxmem.obj afxabort.obj
-
-FILES=filecore.obj filetxt.obj filemem.obj fileshrd.obj \
-	filex.obj filest.obj
-
-COLL1=array_b.obj array_d.obj array_p.obj array_o.obj \
-	array_s.obj array_u.obj array_w.obj \
-	list_o.obj list_p.obj list_s.obj
-
-COLL2=map_pp.obj map_pw.obj map_so.obj \
-	map_sp.obj map_ss.obj map_wo.obj map_wp.obj plex.obj
-
-MISC=\
-	strcore.obj strex.obj timecore.obj \
-	afxdbcs.obj afxstate.obj afxtls.obj fixalloc.obj \
-        mtcore.obj mtex.obj
-
-WINDOWS=winhand.obj
-
-DIALOG=
-
-WINMISC=afxcrit.obj winstr.obj winutil.obj auxdata.obj wingdi.obj
-
-DOCVIEW=
-
-INTERNET=inet.obj filefind.obj
-!if "$(UNICODE)" == "1"
-INTERNET=$(INTERNET) isapimix.obj
-!endif
-
-APPLICATION=appterm.obj appui1.obj appinit.obj apphelp.obj thrdcore.obj
-
-!if "$(DLL)" != "2"
-APPLICATION=$(APPLICATION) app3ds.obj \
-	nolib.obj appmodul.obj dllmodul.obj oleexp.obj dumpstak.obj
-!endif
-
-# ODBC components:
-DB=\
-	dbcore.obj dbrfx.obj dbview.obj dbflt.obj \
-	dblong.obj dbvar.obj
-
-#
-# DAO is not supported under Borland C++
-#
-#DB= $(DB) daocore.obj daodfx.obj daoview.obj viewoled.obj
-#
-
-SOCKETS=sockcore.obj
-
-OLEREQ=olelock.obj
-
-OLE=\
-	oleinit.obj olecli1.obj olecli2.obj \
-	olecli3.obj olecnvrt.obj oledobj1.obj oledobj2.obj \
-	oledisp1.obj oledisp2.obj oledlgs1.obj oledlgs2.obj \
-	oledlgs3.obj oledata.obj olevar.obj olevar1.obj \
-	oledoc1.obj oledoc2.obj oledrop1.obj oledrop2.obj \
-	olemsgf.obj oleenum.obj olefact.obj oleipfrm.obj \
-	olelink.obj olemisc.obj olestrm.obj olesvr1.obj \
-	olesvr2.obj olereg.obj oletsvr.obj oleui1.obj \
-	oleui2.obj oleunk.obj oleverb.obj olecall.obj \
-	viewrich.obj oledll.obj oletyplb.obj \
-	olemon.obj winctrl5.obj viewhtml.obj \
-	occmgr.obj occevent.obj occcont.obj occsite.obj \
-	occlock.obj occddx.obj occddxf.obj occdlg.obj \
-	oledocvw.obj oledocob.obj oledoctg.obj oledocip.obj \
-	oledoccl.obj oleasmon.obj olebar.obj
-
-OLECTL=\
-	ctlcache.obj ctlcore.obj ctlconn.obj \
-	ctldata.obj ctlevent.obj ctlmodul.obj \
-	ctlframe.obj ctlfont.obj ctlinplc.obj \
-	ctllic.obj oleconn.obj ctlobj.obj ctlpict.obj \
-	ctlpropx.obj ctlppg.obj ctlprop.obj \
-	ctlpset.obj ctlpstg.obj ctlpstm.obj \
-	ctlrefl.obj ctlreg.obj ctltrack.obj \
-	ctlview.obj olepset.obj ctlpbag.obj \
-	ctlquick.obj ctlnownd.obj \
-	ppgcolor.obj ppgfont.obj ppgpict.obj ppgstock.obj
-
-!if "$(DEBUG)" == "1"
-OLECTL=$(OLECTL) ctlinl.obj
-!endif
-
-# Borland enhancement:
-!if "$(DEBUG)" == "1" && "$(MONOLITHIC)" == "1"
-OLE=$(OLE) dllole.obj
-!endif
-
-OLEDLL=$(OLE) $(OLECTL) $(OLEASM)
-
-!if "$(DEBUG)" == "1"
-INLINES = afxinl1.obj afxinl2.obj afxinl3.obj
-!else
-INLINES =
-!endif
-
-CPP_OBJS=$(OBJECT) $(OBJDIAG) $(INLINES) $(FILES) $(COLL1) $(COLL2) $(MISC) \
-	$(WINDOWS) $(DIALOG) $(WINMISC) $(DOCVIEW) $(APPLICATION) \
-	$(SOCKETS) $(OLEREQ) $(OLE) $(DAO) $(DB) $(INTERNET) $(OLECTL)
-
-
-OBJS=$(CPP_OBJS) $(OLEASM)
-
-
-#############################################################################
-# Standard tools
-
-#############################################################################
-# Set CPPFLAGS for use with .cpp.obj and .c.obj rules
-# Define rule for use with OBJ directory
-# C++ uses a PCH file
-
-CPPFLAGS=$(CPPFLAGS) $(CL_MODEL) $(CL_OPT) $(PDBOPTS) $(DEFS) $(OPT)
-BORRSP=bor.rsp
-
-!ifndef NO_PCH
-!ifndef PCH_FILE
-# put the PCH file in the OBJ directory for easy cleanup later
-PCH_FILE=$(D)\stdafx
-!if "$(BROWSE)" != "0"
-PCH_FILE=$(PCH_FILE)b
-!endif
-PCH_FILE=$(PCH_FILE).csm
-!endif
-!ifndef PCH_CPP
-PCH_CPP=objcore
-!endif
-PCH_CMD=-Hc -H=$(PCH_FILE)
-!else
-PCH_CMD=-H-
-PCH_FILE=
-!endif
-CPPFLAGS=$(CPPFLAGS) $(PCH_CMD)
-
-!ifdef JOHNS_CPP32
-PREPROCFLAGS=-Sd -Sk -Sr -P-
-!else
-PREPROCFLAGS=-Sd -Sk -Ss -P
-!endif
-
-.SUFFIXES: .cpp
-
-.path.obj = $(D)
-
-
-.cpp.i:
-	cpp32 @$(BORRSP) $(PREPROCFLAGS) $<
-
-.cpp.obj:
-!if $d(FORCE_CPP32)
-	cpp32 @$(BORRSP) $(PREPROCFLAGS) $<
-!else
-	$(CC) @$(BORRSP) /c { $< }
-!endif
-
-!ifndef NO_PCH
-PCH_TARGETS=$(PCH_FILE) $(D)\$(PCH_CPP).obj
-!endif
-
-#############################################################################
-# Goals to build
-
-GOALS=log.mode create.dir create.rsp
-!ifndef NO_PCH
-GOALS=$(GOALS) $(PCH_TARGETS)
-!endif
-GOALS=$(GOALS) $(LIBDIR)\$(GOAL).lib
-
-goal: $(GOALS)
-
-log.mode:
-  @-echo BORLAND.MAK: 
-  @-echo              GOAL=$(GOAL), DLL=$(DLL),  DEBUG=$(DEBUG), 
-  @-echo              DBGINFO=$(DBGINFO), RCDEFINES=$(RCDEFINES), 
-  @-echo              CL_OPT=$(CL_OPT), DEFS=$(DEFS),
-  @-echo              CPPFLAGS=$(CPPFLAGS)	 
-  @-echo              D=$(D)
-  @-echo              STATICLINK_OBJS=$(STATICLINK_OBJS)
-
-create.rsp:
-!ifndef NO_PCH
-!if "$(NO_CLEAN_PCH)" == "0"
-    @-if exist $(PCH_FILE) echo Erasing PCH file: $(PCH_FILE) for a fresh build
-    @-if exist $(PCH_FILE) erase $(PCH_FILE) > nul 
-!endif
-!endif
-    @-if exist $(BORRSP) erase $(BORRSP) > nul
-    copy &&|
-$(CPPFLAGS) -I$(BCINCL);$(MFCINCL)
-| $(BORRSP)
-
-create.dir:
-	@-if not exist $(D) mkdir $(D)
-	@-if not exist $(LIBDIR) mkdir $(LIBDIR)
-
-clean:
-	@-if exist *.map erase *.map
-	@-if exist *.dll erase *.dll
-	@-if exist *.cfg erase *.cfg
-	@-if exist *.rsp erase *.rsp
-	@-if exist *.tds erase *.tds
-!if $d(INTEGRATION_BUILD)
-	@-if exist $(PLATFORM)\*.def erase $(PLATFORM)\*.def
-!endif
-	@-if exist $$DLLD.W  rmdir $$DLLD.W /s
-	@-if exist $$DLL.W rmdir $$DLL.W /s
-	@-if exist $$NW rmdir $$NW /s
-	@-if exist $$NWD rmdir $$NWD /s
-
-
-#############################################################################
-# Precompiled header file
-
-!ifndef NO_PCH
-
-!if "$(DEBUG)" == "1"
-HDRS =$(MFCINCL)\*.h
-!else
-HDRS =$(MFCINCL)\*.h $(MFCINCL)\*.inl
-!endif
-
-!if "$(DLL)" != "2"
-$(PCH_TARGETS): $(PCH_CPP).cpp
-	$(CC) @&&!
-$(CPPFLAGS) -I$(BCINCL);$(MFCINCL) /c $(PCH_CPP).cpp
-!
-
-!endif # DLL != 2
-!endif # NO_PCH
-
-
-#############################################################################
-# Build the library from the up-to-date objs
-
-!if "$(DLL)" != "2"
-# Build final library
-$(LIBDIR)\$(GOAL).lib: $(OBJS)
-	@-if exist $@ erase $@
-	@$(LIB32) $@ /P2048 @&&!
-+-$(**: = &^
-+-)
-!
-
-!endif #DLL!=2
-
-#############################################################################

+ 0 - 0
licence.txt → license.txt


+ 8 - 3
readme.txt

@@ -2,12 +2,17 @@ This is the README file for source code package of WinSCP.
 
 To build WinSCP you need:
 - Embarcadero C++ Builder XE2 Professional.
-- Copy MFC source code from Borland C++ Builder 6 Professional and
-  build its Unicode version (see readme_mfc.txt).
+  http://www.embarcadero.com/products/cbuilder
+- Microsoft .NET Framework 3.5 (for MSBuild)
+  http://www.microsoft.com/netframework
 - nasm from http://www.nasm.us/
+- Build MFC (see readme_mfc.txt).
 - To build 64-bit version of drag&drop shell extension, you need
   Windows Platform SDK:
   http://msdn.microsoft.com/en-us/windows/bb980924
+- To build WinSCP .NET assembly, you need Microsoft Visual Studio 2012
+  http://www.microsoft.com/visualstudio
+  and Microsoft .NET Framework 4.0
 
 To build WinSCP from source by yourself, modify and use 'build.bat' in root
 folder of source code package.
@@ -32,4 +37,4 @@ Directory structure:
 
 WinSCP homepage is http://winscp.net/
 
-See the file 'licence.txt' for the licence conditions.
+See the file 'license.txt' for the license conditions.

+ 2 - 2
readme_mfc.txt

@@ -1,9 +1,9 @@
 The following is a copy of post at
 https://forums.embarcadero.com/message.jspa?messageID=175480#175480
 
-1) copy $(BCB6)\source\mfc to $(BDS)\source\mfc
+1) copy libs\mfc\source to $(BDS)\source\mfc
 
-2) copy $(BCB6)\include\mfc to $(BDS)\include\mfc
+2) copy libs\mfc\include to $(BDS)\include\mfc
 
 3) make following changes to files in $(BDS)\source\mfc
 

+ 2 - 2
source/Console.cbproj

@@ -41,10 +41,10 @@
 			<PackageImports>rtl.bpi;$(PackageImports)</PackageImports>
 			<ProjectType>CppConsoleApplication</ProjectType>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.0.1.0;InternalName=console;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.2.3.0;ReleaseType=beta;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.0.2.0;InternalName=console;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.2.4.0;ReleaseType=beta;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>4</VerInfo_MajorVer>
-			<VerInfo_Release>1</VerInfo_Release>
+			<VerInfo_Release>2</VerInfo_Release>
 		</PropertyGroup>
 		<PropertyGroup Condition="'$(Cfg_1)'!=''">
 			<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+ 1 - 1
source/DragExt.cbproj

@@ -42,7 +42,7 @@
 			<ProjectType>CppDynamicLibrary</ProjectType>
 			<VerInfo_DLL>true</VerInfo_DLL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.2.3.0;ReleaseType=beta;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.2.4.0;ReleaseType=beta;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
 			<VerInfo_Release>1</VerInfo_Release>

+ 2 - 2
source/DragExt64.rc

@@ -1,6 +1,6 @@
 1 VERSIONINFO
 FILEVERSION 1,2,1,0
-PRODUCTVERSION 5,2,3,0
+PRODUCTVERSION 5,2,4,0
 FILEOS 0x4
 FILETYPE 0x2
 {
@@ -16,7 +16,7 @@ FILETYPE 0x2
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "dragext64.dll\0"
             VALUE "ProductName", "WinSCP\0"
-            VALUE "ProductVersion", "5.2.3.0\0"
+            VALUE "ProductVersion", "5.2.4.0\0"
             VALUE "ReleaseType", "beta\0"
             VALUE "WWW", "http://winscp.net/\0"
         }

+ 5 - 5
source/WinSCP.cbproj

@@ -31,7 +31,7 @@
 		</PropertyGroup>
 		<PropertyGroup Condition="'$(Base)'!=''">
 			<_TCHARMapping>wchar_t</_TCHARMapping>
-			<AllPackageLibs>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;Moje.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib</AllPackageLibs>
+			<AllPackageLibs>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;Moje.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib</AllPackageLibs>
 			<BCC_AllWarnings>true</BCC_AllWarnings>
 			<BCC_ExtendedErrorInfo>true</BCC_ExtendedErrorInfo>
 			<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
@@ -44,18 +44,18 @@
 			<ILINK_GenerateDRC>true</ILINK_GenerateDRC>
 			<ILINK_LibraryPath>windows\;forms\;packages\filemng;packages\tbx;packages\png;..\libs\lib;$(LIB_PATH);$(ILINK_LibraryPath)</ILINK_LibraryPath>
 			<IncludePath>console;windows\;forms\;core;resource;components;dragext;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;packages\png;$(BDS)\include\mfc;$(BDS)\include\windows;$(BDS)\include\windows\vcl;$(BDS)\include\dinkumware;$(IncludePath)</IncludePath>
-			<LinkPackageStatics>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;Moje.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib</LinkPackageStatics>
-			<Manifest_File>None</Manifest_File>
+			<LinkPackageStatics>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;Moje.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib</LinkPackageStatics>
+			<Manifest_File>windows\WinSCP.exe.manifest</Manifest_File>
 			<Multithreaded>true</Multithreaded>
 			<OutputExt>exe</OutputExt>
 			<ProjectType>CppVCLApplication</ProjectType>
 			<UsingDelphiRTL>true</UsingDelphiRTL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.2.3.0;InternalName=winscp;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.2.3.0;ReleaseType=beta;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.2.4.0;InternalName=winscp;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.2.4.0;ReleaseType=beta;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>5</VerInfo_MajorVer>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
-			<VerInfo_Release>3</VerInfo_Release>
+			<VerInfo_Release>4</VerInfo_Release>
 		</PropertyGroup>
 		<PropertyGroup Condition="'$(Cfg_1)'!=''">
 			<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+ 3 - 0
source/WinSCP.cpp

@@ -28,6 +28,9 @@ WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
     CoreInitialize();
     InitializeWinHelp();
     InitializeSystemSettings();
+    // now everything is setup and mainly the configured locale is already loaded,
+    // detect scaling type and possibly forbid further runtime changes to locale
+    GUIConfiguration->DetectScalingType();
 
     try
     {

+ 26 - 1
source/components/ThemePageControl.cpp

@@ -65,6 +65,30 @@ __fastcall TThemePageControl::TThemePageControl(TComponent * Owner) :
   FOldTabIndex = -1;
 }
 //----------------------------------------------------------------------------------------------------------
+int __fastcall TThemePageControl::GetTabsHeight()
+{
+  // Calculated height includes tab/contents separator line on Windows 7/8,
+  // but not on Windows XP
+
+  TRect Rect = GetClientRect();
+  ::SendMessage(Handle, TCM_ADJUSTRECT, FALSE, (LPARAM)&Rect);
+  int Result = Rect.Top - 1;
+
+  // two different ways to calculate the same, not sure which one is more reliable,
+  // so we want to know in case they differ
+  if (ALWAYS_TRUE(PageCount >= 0))
+  {
+    TRect Rect = TabRect(0);
+    int Result2 = Rect.Bottom + 1;
+    if (ALWAYS_FALSE(Result != Result2))
+    {
+      Result = Result2;
+    }
+  }
+
+  return Result;
+}
+//----------------------------------------------------------------------------------------------------------
 void __fastcall TThemePageControl::PaintWindow(HDC DC)
 {
   // Themes not enabled, give up
@@ -198,8 +222,9 @@ void __fastcall TThemePageControl::DrawTabItem(HDC DC, int Item, TRect Rect, boo
     {
       Left = (Rect.Right - Images->Width - Rect.Left) / 2;
     }
+    int Y = ((Rect.Top + Rect.Bottom - Images->Height) / 2) - 1 + (Selected ? 0 : -2);
     ImageList_Draw((HIMAGELIST)Images->Handle, Pages[Item]->ImageIndex, DC,
-      Left, Rect.Top - 1 + (Selected ? 0 : -2), ILD_TRANSPARENT);
+      Left, Y, ILD_TRANSPARENT);
     Rect.Left += Images->Width + 3;
   }
   else

+ 2 - 0
source/components/ThemePageControl.h

@@ -23,6 +23,8 @@ friend class TThemeTabSheet;
 public:
   __fastcall TThemePageControl(TComponent * Owner);
 
+  int __fastcall GetTabsHeight();
+
 protected:
   virtual void __fastcall PaintWindow(HDC DC);
   DYNAMIC bool __fastcall CanChange();

+ 18 - 31
source/console/Main.cpp

@@ -100,37 +100,21 @@ void InitializeConsole(wchar_t* InstanceName, HANDLE& RequestEvent, HANDLE& Resp
     throw runtime_error("Cannot create mapping object.");
   }
 
-  typedef HANDLE WINAPI (*TCreateJobObject)(LPSECURITY_ATTRIBUTES JobAttributes, LPCTSTR Name);
-  typedef HANDLE WINAPI (*TSetInformationJobObject)(HANDLE Job, JOBOBJECTINFOCLASS JobObjectInformationClass,
-    LPVOID JobObjectInformation, DWORD JobObjectInformationLength);
-
-  HANDLE Kernel32 = GetModuleHandle(L"kernel32");
-  TCreateJobObject CreateJobObject =
-    (TCreateJobObject)GetProcAddress(Kernel32, "CreateJobObjectW");
-  TSetInformationJobObject SetInformationJobObject =
-    (TSetInformationJobObject)GetProcAddress(Kernel32, "SetInformationJobObject");
-  if ((CreateJobObject != NULL) && (SetInformationJobObject != NULL))
+  swprintf(Name, L"%s%s", CONSOLE_JOB, InstanceName);
+  Job = CreateJobObject(NULL, Name);
+  if (Job == NULL)
   {
-    swprintf(Name, L"%s%s", CONSOLE_JOB, InstanceName);
-    Job = CreateJobObject(NULL, Name);
-    if (Job == NULL)
-    {
-      throw runtime_error("Cannot create job object.");
-    }
-
-    JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInformation;
-    memset(&ExtendedLimitInformation, 0, sizeof(ExtendedLimitInformation));
-    ExtendedLimitInformation.BasicLimitInformation.LimitFlags =
-      JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
-    if (SetInformationJobObject(Job, JobObjectExtendedLimitInformation,
-          &ExtendedLimitInformation, sizeof(ExtendedLimitInformation)) == 0)
-    {
-      CloseHandle(Job);
-      Job = NULL;
-    }
+    throw runtime_error("Cannot create job object.");
   }
-  else
+
+  JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInformation;
+  memset(&ExtendedLimitInformation, 0, sizeof(ExtendedLimitInformation));
+  ExtendedLimitInformation.BasicLimitInformation.LimitFlags =
+    JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+  if (SetInformationJobObject(Job, JobObjectExtendedLimitInformation,
+        &ExtendedLimitInformation, sizeof(ExtendedLimitInformation)) == 0)
   {
+    CloseHandle(Job);
     Job = NULL;
   }
 
@@ -376,7 +360,10 @@ void FinalizeConsole(const wchar_t* /*InstanceName*/, HANDLE RequestEvent,
   CloseHandle(ResponseEvent);
   CloseHandle(CancelEvent);
   CloseHandle(FileMapping);
-  CloseHandle(Job);
+  if (Job != NULL)
+  {
+    CloseHandle(Job);
+  }
 }
 //---------------------------------------------------------------------------
 static wchar_t LastFromBeginning[sizeof(TConsoleCommStruct::TPrintEvent)] = L""; //???
@@ -776,8 +763,8 @@ int wmain(int /*argc*/, wchar_t* /*argv*/[])
 
 
     bool SupportsUtf8ConsoleOutput =
-      (VersionInfo.dwMajorVersion == 6) &&
-      (VersionInfo.dwMinorVersion == 1);
+      ((VersionInfo.dwMajorVersion == 6) && (VersionInfo.dwMinorVersion >= 1)) ||
+      (VersionInfo.dwMajorVersion > 6);
 
     if ((InputType == FILE_TYPE_DISK) || (InputType == FILE_TYPE_PIPE) ||
         SupportsUtf8ConsoleOutput)

+ 40 - 12
source/core/Common.cpp

@@ -1488,6 +1488,14 @@ bool __fastcall RecursiveDeleteFile(const UnicodeString FileName, bool ToRecycle
   return Result;
 }
 //---------------------------------------------------------------------------
+void __fastcall DeleteFileChecked(const UnicodeString & FileName)
+{
+  if (!DeleteFile(FileName))
+  {
+    throw EOSExtException(FMTLOAD(DELETE_LOCAL_FILE_ERROR, (FileName)));
+  }
+}
+//---------------------------------------------------------------------------
 unsigned int __fastcall CancelAnswer(unsigned int Answers)
 {
   unsigned int Result;
@@ -1775,26 +1783,27 @@ void __fastcall AddToList(UnicodeString & List, const UnicodeString & Value, con
   }
 }
 //---------------------------------------------------------------------------
+bool __fastcall IsWinXPOrOlder()
+{
+  // Win XP is 5.1
+  // Vista is 6.0
+  // There also 5.2, what is Windows 2003 or Windows XP 64bit
+  // (we consider it WinXP for now)
+  return !CheckWin32Version(6, 0);
+}
+//---------------------------------------------------------------------------
 bool __fastcall IsWin7()
 {
   return CheckWin32Version(6, 1);
 }
 //---------------------------------------------------------------------------
+// Duplicated in PasTools.pas
 bool __fastcall IsExactly2008R2()
 {
-  HINSTANCE Kernel32 = GetModuleHandle(kernel32);
-  typedef BOOL WINAPI (* TGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
-  TGetProductInfo GetProductInfo =
-      (TGetProductInfo)GetProcAddress(Kernel32, "GetProductInfo");
-  bool Result;
-  if (GetProductInfo == NULL)
+  bool Result = (Win32MajorVersion == 6) && (Win32MinorVersion == 1);
+  DWORD Type;
+  if (Result && GetWindowsProductType(Type))
   {
-    Result = false;
-  }
-  else
-  {
-    DWORD Type;
-    GetProductInfo(Win32MajorVersion, Win32MinorVersion, 0, 0, &Type);
     switch (Type)
     {
       case 0x0008 /*PRODUCT_DATACENTER_SERVER*/:
@@ -1853,6 +1862,25 @@ UnicodeString __fastcall DefaultEncodingName()
   return ADefaultEncodingName;
 }
 //---------------------------------------------------------------------------
+bool _fastcall GetWindowsProductType(DWORD & Type)
+{
+  bool Result;
+  HINSTANCE Kernel32 = GetModuleHandle(kernel32);
+  typedef BOOL WINAPI (* TGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
+  TGetProductInfo GetProductInfo =
+      (TGetProductInfo)GetProcAddress(Kernel32, "GetProductInfo");
+  if (GetProductInfo == NULL)
+  {
+    Result = false;
+  }
+  else
+  {
+    GetProductInfo(Win32MajorVersion, Win32MinorVersion, 0, 0, &Type);
+    Result = true;
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 UnicodeString __fastcall WindowsProductName()
 {
   UnicodeString Result;

+ 11 - 11
source/core/Common.h

@@ -3,7 +3,7 @@
 #define CommonH
 //---------------------------------------------------------------------------
 #define EXCEPTION throw ExtException(NULL, L"")
-#define THROWOSIFFALSE(C) if (!(C)) RaiseLastOSError();
+#define THROWOSIFFALSE(C) { if (!(C)) RaiseLastOSError(); }
 #define SAFE_DESTROY_EX(CLASS, OBJ) { CLASS * PObj = OBJ; OBJ = NULL; delete PObj; }
 #define SAFE_DESTROY(OBJ) SAFE_DESTROY_EX(TObject, OBJ)
 #define ASCOPY(dest, source) \
@@ -78,6 +78,7 @@ UnicodeString __fastcall DecodeUrlChars(UnicodeString S);
 UnicodeString __fastcall EncodeUrlChars(UnicodeString S, UnicodeString Ignore = L"");
 UnicodeString __fastcall EncodeUrlString(UnicodeString S);
 bool __fastcall RecursiveDeleteFile(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);
 unsigned int __fastcall ContinueAnswer(unsigned int Answers);
@@ -87,6 +88,7 @@ UnicodeString __fastcall EscapeHotkey(const UnicodeString & Caption);
 bool __fastcall CutToken(UnicodeString & Str, UnicodeString & Token,
   UnicodeString * RawToken = NULL);
 void __fastcall AddToList(UnicodeString & List, const UnicodeString & Value, const UnicodeString & Delimiter);
+bool __fastcall IsWinXPOrOlder();
 bool __fastcall IsWin7();
 bool __fastcall IsExactly2008R2();
 TLibModule * __fastcall FindModule(void * Instance);
@@ -95,6 +97,7 @@ bool __fastcall TryRelativeStrToDateTime(UnicodeString S, TDateTime & DateTime);
 LCID __fastcall GetDefaultLCID();
 UnicodeString __fastcall DefaultEncodingName();
 UnicodeString __fastcall WindowsProductName();
+bool _fastcall GetWindowsProductType(DWORD & Type);
 bool __fastcall IsDirectoryWriteable(const UnicodeString & Path);
 UnicodeString __fastcall FormatNumber(__int64 Size);
 UnicodeString __fastcall FormatSize(__int64 Size);
@@ -195,6 +198,12 @@ public:
   {
   }
 
+  __fastcall TValueRestorer(T & Target) :
+    FTarget(Target),
+    FValue(Target)
+  {
+  }
+
   __fastcall ~TValueRestorer()
   {
     FTarget = FValue;
@@ -205,20 +214,11 @@ protected:
   T FValue;
 };
 //---------------------------------------------------------------------------
-class TBoolRestorer : TValueRestorer<bool>
-{
-public:
-  __fastcall TBoolRestorer(bool & Target) :
-    TValueRestorer<bool>(Target, !Target)
-  {
-  }
-};
-//---------------------------------------------------------------------------
 class TAutoNestingCounter : TValueRestorer<int>
 {
 public:
   __fastcall TAutoNestingCounter(int & Target) :
-    TValueRestorer<int>(Target, Target)
+    TValueRestorer<int>(Target)
   {
     assert(Target >= 0);
     ++Target;

+ 57 - 33
source/core/Configuration.cpp

@@ -184,6 +184,12 @@ void __fastcall TConfiguration::Save()
   DoSave(false, false);
 }
 //---------------------------------------------------------------------------
+void __fastcall TConfiguration::SaveExplicit()
+{
+  // only modified, explicit
+  DoSave(false, true);
+}
+//---------------------------------------------------------------------------
 void __fastcall TConfiguration::DoSave(bool All, bool Explicit)
 {
   if (FDontSave) return;
@@ -554,7 +560,7 @@ void __fastcall TConfiguration::CleanupConfiguration()
   }
   catch (Exception &E)
   {
-    throw ExtException(&E, CLEANUP_CONFIG_ERROR);
+    throw ExtException(&E, LoadStr(CLEANUP_CONFIG_ERROR));
   }
 }
 //---------------------------------------------------------------------------
@@ -579,7 +585,7 @@ void __fastcall TConfiguration::CleanupHostKeys()
   }
   catch (Exception &E)
   {
-    throw ExtException(&E, CLEANUP_HOSTKEYS_ERROR);
+    throw ExtException(&E, LoadStr(CLEANUP_HOSTKEYS_ERROR));
   }
 }
 //---------------------------------------------------------------------------
@@ -590,15 +596,12 @@ void __fastcall TConfiguration::CleanupRandomSeedFile()
     DontSaveRandomSeed();
     if (FileExists(RandomSeedFileName))
     {
-      if (!DeleteFile(RandomSeedFileName))
-      {
-        RaiseLastOSError();
-      }
+      DeleteFileChecked(RandomSeedFileName);
     }
   }
   catch (Exception &E)
   {
-    throw ExtException(&E, CLEANUP_SEEDFILE_ERROR);
+    throw ExtException(&E, LoadStr(CLEANUP_SEEDFILE_ERROR));
   }
 }
 //---------------------------------------------------------------------------
@@ -608,10 +611,7 @@ void __fastcall TConfiguration::CleanupIniFile()
   {
     if (FileExists(IniFileStorageNameForReading))
     {
-      if (!DeleteFile(IniFileStorageNameForReading))
-      {
-        RaiseLastOSError();
-      }
+      DeleteFileChecked(IniFileStorageNameForReading);
     }
     if (Storage == stIniFile)
     {
@@ -620,7 +620,7 @@ void __fastcall TConfiguration::CleanupIniFile()
   }
   catch (Exception &E)
   {
-    throw ExtException(&E, CLEANUP_INIFILE_ERROR);
+    throw ExtException(&E, LoadStr(CLEANUP_INIFILE_ERROR));
   }
 }
 //---------------------------------------------------------------------------
@@ -660,9 +660,18 @@ UnicodeString __fastcall TConfiguration::GetOSVersionStr()
   OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
   if (GetVersionEx(&OSVersionInfo) != 0)
   {
-    Result = FORMAT(L"%d.%d.%d %s", (int(OSVersionInfo.dwMajorVersion),
-      int(OSVersionInfo.dwMinorVersion), int(OSVersionInfo.dwBuildNumber),
-      OSVersionInfo.szCSDVersion)).Trim();
+    Result = FORMAT(L"%d.%d.%d", (int(OSVersionInfo.dwMajorVersion),
+      int(OSVersionInfo.dwMinorVersion), int(OSVersionInfo.dwBuildNumber)));
+    UnicodeString CSDVersion = OSVersionInfo.szCSDVersion;
+    if (!CSDVersion.IsEmpty())
+    {
+      Result += L" " + CSDVersion;
+    }
+    UnicodeString ProductName = WindowsProductName();
+    if (!ProductName.IsEmpty())
+    {
+      Result += L" - " + ProductName;
+    }
   }
   return Result;
 }
@@ -958,32 +967,47 @@ void __fastcall TConfiguration::SetStorage(TStorage value)
 {
   if (FStorage != value)
   {
-    THierarchicalStorage * SourceStorage = NULL;
-    THierarchicalStorage * TargetStorage = NULL;
-
+    TStorage StorageBak = FStorage;
     try
     {
-      SourceStorage = CreateScpStorage(false);
-      SourceStorage->AccessMode = smRead;
+      THierarchicalStorage * SourceStorage = NULL;
+      THierarchicalStorage * TargetStorage = NULL;
 
-      FStorage = value;
+      try
+      {
+        SourceStorage = CreateScpStorage(false);
+        SourceStorage->AccessMode = smRead;
 
-      TargetStorage = CreateScpStorage(false);
-      TargetStorage->AccessMode = smReadWrite;
-      TargetStorage->Explicit = true;
+        FStorage = value;
 
-      // copy before save as it removes the ini file,
-      // when switching from ini to registry
-      CopyData(SourceStorage, TargetStorage);
+        TargetStorage = CreateScpStorage(false);
+        TargetStorage->AccessMode = smReadWrite;
+        TargetStorage->Explicit = true;
+
+        // copy before save as it removes the ini file,
+        // when switching from ini to registry
+        CopyData(SourceStorage, TargetStorage);
+      }
+      __finally
+      {
+        delete SourceStorage;
+        delete TargetStorage;
+      }
+
+      // save all and explicit,
+      // this also removes an INI file, when switching to registry storage
+      DoSave(true, true);
     }
-    __finally
+    catch (...)
     {
-      delete SourceStorage;
-      delete TargetStorage;
+      // If this fails, do not pretend that storage was switched.
+      // For instance:
+      // - When writting to an IFI file fails (unlikely, as we fallsback to user profile)
+      // - When removing INI file fails, when switching to registry
+      //   (possible, when the INI file is in Program files folder)
+      FStorage = StorageBak;
+      throw;
     }
-
-    // save all and explicit
-    DoSave(true, true);
   }
 }
 //---------------------------------------------------------------------------

+ 3 - 2
source/core/Configuration.h

@@ -160,8 +160,9 @@ public:
   __fastcall TConfiguration();
   virtual __fastcall ~TConfiguration();
   virtual void __fastcall Default();
-  virtual void __fastcall Load();
-  virtual void __fastcall Save();
+  void __fastcall Load();
+  void __fastcall Save();
+  void __fastcall SaveExplicit();
   void __fastcall SetNulStorage();
   void __fastcall SetDefaultStorage();
   void __fastcall Export(const UnicodeString & FileName);

+ 25 - 9
source/core/FtpFileSystem.cpp

@@ -229,6 +229,7 @@ __fastcall TFTPFileSystem::TFTPFileSystem(TTerminal * ATerminal):
   FCommandReply(0),
   FLastCommand(CMD_UNKNOWN),
   FLastResponse(new TStringList()),
+  FLastErrorResponse(new TStringList()),
   FLastError(new TStringList()),
   FFeatures(new TStringList()),
   FFileList(NULL),
@@ -276,6 +277,8 @@ __fastcall TFTPFileSystem::~TFTPFileSystem()
 
   delete FLastResponse;
   FLastResponse = NULL;
+  delete FLastErrorResponse;
+  FLastErrorResponse = NULL;
   delete FLastError;
   FLastError = NULL;
   delete FFeatures;
@@ -450,8 +453,8 @@ void __fastcall TFTPFileSystem::Open()
     }
 
     FPasswordFailed = false;
+    TValueRestorer<bool> OpeningRestorer(FOpening);
     FOpening = true;
-    TBoolRestorer OpeningRestorer(FOpening);
 
     FActive = FFileZillaIntf->Connect(
       HostName.c_str(), Data->PortNumber, UserName.c_str(),
@@ -1132,10 +1135,7 @@ void __fastcall TFTPFileSystem::Sink(const UnicodeString FileName,
       );
 
       FILE_OPERATION_LOOP (FMTLOAD(CREATE_DIR_ERROR, (DestFullName)),
-        if (!ForceDirectories(DestFullName))
-        {
-          RaiseLastOSError();
-        }
+        THROWOSIFFALSE(ForceDirectories(DestFullName));
       );
 
       TSinkFileParams SinkFileParams;
@@ -2499,6 +2499,8 @@ void __fastcall TFTPFileSystem::ResetReply()
   FLastCodeClass = 0;
   assert(FLastResponse != NULL);
   FLastResponse->Clear();
+  assert(FLastErrorResponse != NULL);
+  FLastErrorResponse->Clear();
   assert(FLastError != NULL);
   FLastError->Clear();
 }
@@ -2621,9 +2623,10 @@ void __fastcall TFTPFileSystem::GotReply(unsigned int Reply, unsigned int Flags,
         // associated with session closure is not reused
         FLastError->Clear();
 
-        MoreMessages->AddStrings(FLastResponse);
+        MoreMessages->AddStrings(FLastErrorResponse);
         // see comment for FLastError
         FLastResponse->Clear();
+        FLastErrorResponse->Clear();
 
         if (MoreMessages->Count == 0)
         {
@@ -2673,6 +2676,9 @@ void __fastcall TFTPFileSystem::GotReply(unsigned int Reply, unsigned int Flags,
     {
       *Response = FLastResponse;
       FLastResponse = new TStringList();
+      // just to be consistent
+      delete FLastErrorResponse;
+      FLastErrorResponse = new TStringList();
     }
   }
   __finally
@@ -2687,6 +2693,15 @@ void __fastcall TFTPFileSystem::SetLastCode(int Code)
   FLastCodeClass = (Code / 100);
 }
 //---------------------------------------------------------------------------
+void __fastcall TFTPFileSystem::StoreLastResponse(const UnicodeString & Text)
+{
+  FLastResponse->Add(Text);
+  if (FLastCodeClass >= 4)
+  {
+    FLastErrorResponse->Add(Text);
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
 {
   int Code;
@@ -2724,11 +2739,12 @@ void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
   {
     FMultineResponse = (Response.Length() >= 4) && (Response[4] == L'-');
     FLastResponse->Clear();
+    FLastErrorResponse->Clear();
+    SetLastCode(Code);
     if (Response.Length() >= 5)
     {
-      FLastResponse->Add(Response.SubString(5, Response.Length() - 4));
+      StoreLastResponse(Response.SubString(5, Response.Length() - 4));
     }
-    SetLastCode(Code);
   }
   else
   {
@@ -2751,7 +2767,7 @@ void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
     // Intermediate empty lines are being added
     if (FMultineResponse || (Response.Length() >= Start))
     {
-      FLastResponse->Add(Response.SubString(Start, Response.Length() - Start + 1));
+      StoreLastResponse(Response.SubString(Start, Response.Length() - Start + 1));
     }
   }
 

+ 2 - 0
source/core/FtpFileSystem.h

@@ -180,6 +180,7 @@ protected:
   void __fastcall RemoteFileTimeToDateTimeAndPrecision(const TRemoteFileTime & Source,
     TDateTime & DateTime, TModificationFmt & ModificationFmt);
   void __fastcall SetLastCode(int Code);
+  void __fastcall StoreLastResponse(const UnicodeString & Text);
 
   static bool __fastcall Unquote(UnicodeString & Str);
   static UnicodeString __fastcall ExtractStatusMessage(UnicodeString Status);
@@ -212,6 +213,7 @@ private:
   UnicodeString FTimeoutStatus;
   UnicodeString FDisconnectStatus;
   TStrings * FLastResponse;
+  TStrings * FLastErrorResponse;
   TStrings * FLastError;
   UnicodeString FSystem;
   TStrings * FFeatures;

+ 1 - 8
source/core/HierarchicalStorage.cpp

@@ -989,14 +989,7 @@ void __fastcall TIniFileStorage::Flush()
           // "access denied" errors upon implicit saves to existing file are ignored
           if (Explicit || !Exists || (GetLastError() != ERROR_ACCESS_DENIED))
           {
-            try
-            {
-              RaiseLastOSError();
-            }
-            catch(Exception & E)
-            {
-              throw ExtException(&E, FMTLOAD(CREATE_FILE_ERROR, (Storage)));
-            }
+            throw EOSExtException(FMTLOAD((Exists ? WRITE_ERROR : CREATE_FILE_ERROR), (Storage)));
           }
         }
         else

+ 7 - 15
source/core/Queue.cpp

@@ -599,9 +599,13 @@ void __fastcall TTerminalQueue::DeleteItem(TQueueItem * Item, bool CanKeep)
         delete Item;
       }
 
-      Empty =
-        EmptyButMonitoredItems(FDoneItems) &&
-        EmptyButMonitoredItems(FItems);
+      Empty = true;
+      Index = 0;
+      while (Empty && (Index < FItems->Count))
+      {
+        Empty = (GetItem(FItems, Index)->CompleteEvent != INVALID_HANDLE_VALUE);
+        Index++;
+      }
     }
 
     DoListUpdate();
@@ -614,18 +618,6 @@ void __fastcall TTerminalQueue::DeleteItem(TQueueItem * Item, bool CanKeep)
   }
 }
 //---------------------------------------------------------------------------
-bool __fastcall TTerminalQueue::EmptyButMonitoredItems(TList * List)
-{
-  bool Empty = true;
-  int Index = 0;
-  while (Empty && (Index < List->Count))
-  {
-    Empty = (GetItem(List, Index)->CompleteEvent != INVALID_HANDLE_VALUE);
-    Index++;
-  }
-  return !Empty;
-}
-//---------------------------------------------------------------------------
 TQueueItem * __fastcall TTerminalQueue::GetItem(TList * List, int Index)
 {
   return reinterpret_cast<TQueueItem*>(List->Items[Index]);

+ 0 - 1
source/core/Queue.h

@@ -119,7 +119,6 @@ protected:
   inline static TQueueItem * __fastcall GetItem(TList * List, int Index);
   inline TQueueItem * __fastcall GetItem(int Index);
   void __fastcall FreeItemsList(TList * List);
-  static bool __fastcall EmptyButMonitoredItems(TList * List);
   void __fastcall UpdateStatusForList(
     TTerminalQueueStatus * Status, TList * List, TTerminalQueueStatus * Current);
   bool __fastcall ItemGetData(TQueueItem * Item, TQueueItemProxy * Proxy);

+ 1 - 1
source/core/ScpFileSystem.cpp

@@ -2323,7 +2323,7 @@ void __fastcall TSCPFileSystem::SCPSink(const UnicodeString TargetDir,
           if (!FileData.Exists)
           {
             FILE_OPERATION_LOOP (FMTLOAD(CREATE_DIR_ERROR, (DestFileName)),
-              if (!ForceDirectories(DestFileName)) RaiseLastOSError();
+              THROWOSIFFALSE(ForceDirectories(DestFileName));
             );
             /* SCP: can we set the timestamp for directories ? */
           }

+ 1 - 1
source/core/SessionData.cpp

@@ -2744,7 +2744,7 @@ void __fastcall TStoredSessionList::Cleanup()
   }
   catch (Exception &E)
   {
-    throw ExtException(&E, CLEANUP_SESSIONS_ERROR);
+    throw ExtException(&E, LoadStr(CLEANUP_SESSIONS_ERROR));
   }
 }
 //---------------------------------------------------------------------------

+ 3 - 7
source/core/SessionInfo.cpp

@@ -797,7 +797,7 @@ void __fastcall TSessionLog::OpenLogFile()
     FConfiguration->LogFileName = UnicodeString();
     try
     {
-      throw ExtException(&E, LOG_GEN_ERROR);
+      throw ExtException(&E, LoadStr(LOG_GEN_ERROR));
     }
     catch (Exception & E)
     {
@@ -908,13 +908,9 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
         delete Storage;
       }
 
-      typedef BOOL WINAPI (* TGetUserNameEx)(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize);
-      HINSTANCE Secur32 = LoadLibrary(L"secur32.dll");
-      TGetUserNameEx GetUserNameEx =
-        (Secur32 != NULL) ? (TGetUserNameEx)GetProcAddress(Secur32, "GetUserNameExW") : NULL;
       wchar_t UserName[UNLEN + 1];
       unsigned long UserNameSize = LENOF(UserName);
-      if ((GetUserNameEx == NULL) || !GetUserNameEx(NameSamCompatible, UserName, &UserNameSize))
+      if (ALWAYS_FALSE(!GetUserNameEx(NameSamCompatible, UserName, &UserNameSize)))
       {
         wcscpy(UserName, L"<Failed to retrieve username>");
       }
@@ -1161,7 +1157,7 @@ void __fastcall TActionLog::Add(const UnicodeString & Line)
       FConfiguration->LogActions = false;
       try
       {
-        throw ExtException(&E, LOG_GEN_ERROR);
+        throw ExtException(&E, LoadStr(LOG_GEN_ERROR));
       }
       catch (Exception &E)
       {

+ 4 - 6
source/core/SftpFileSystem.cpp

@@ -3186,6 +3186,7 @@ void __fastcall TSFTPFileSystem::ReadSymlink(TRemoteFile * SymlinkFile,
     FTerminal->FatalError(NULL, LoadStr(SFTP_NON_ONE_FXP_NAME_PACKET));
   }
   SymlinkFile->LinkTo = ReadLinkPacket.GetPathString(FUtfStrings);
+  FTerminal->LogEvent(FORMAT(L"Link resolved to \"%s\".", (SymlinkFile->LinkTo)));
 
   ReceiveResponse(&AttrsPacket, &AttrsPacket, SSH_FXP_ATTRS);
   // SymlinkFile->FileName was used instead SymlinkFile->LinkTo before, why?
@@ -4903,7 +4904,7 @@ void __fastcall TSFTPFileSystem::SFTPSink(const UnicodeString FileName,
       );
 
       FILE_OPERATION_LOOP (FMTLOAD(CREATE_DIR_ERROR, (DestFullName)),
-        if (!ForceDirectories(DestFullName)) RaiseLastOSError();
+        THROWOSIFFALSE(ForceDirectories(DestFullName));
       );
 
       TSinkFileParams SinkFileParams;
@@ -5310,12 +5311,9 @@ void __fastcall TSFTPFileSystem::SFTPSink(const UnicodeString FileName,
 
           if (FileExists(DestFullName))
           {
-            THROWOSIFFALSE(Sysutils::DeleteFile(DestFullName));
-          }
-          if (!Sysutils::RenameFile(DestPartialFullName, DestFullName))
-          {
-            RaiseLastOSError();
+            DeleteFileChecked(DestFullName);
           }
+          THROWOSIFFALSE(Sysutils::RenameFile(DestPartialFullName, DestFullName));
         );
       }
 

+ 4 - 2
source/core/Terminal.cpp

@@ -3751,6 +3751,8 @@ bool __fastcall TTerminal::DoCreateLocalFile(const UnicodeString FileName,
     Done = (*AHandle != INVALID_HANDLE_VALUE);
     if (!Done)
     {
+      // save the error, otherwise it gets overwritten by call to FileExists
+      int LastError = GetLastError();
       int FileAttr;
       if (::FileExists(FileName) &&
         (((FileAttr = FileGetAttr(FileName)) & (faReadOnly | faHidden)) != 0))
@@ -3804,7 +3806,7 @@ bool __fastcall TTerminal::DoCreateLocalFile(const UnicodeString FileName,
       }
       else
       {
-        RaiseLastOSError();
+        RaiseLastOSError(LastError);
       }
     }
   }
@@ -3870,7 +3872,7 @@ void __fastcall TTerminal::OpenLocalFile(const UnicodeString FileName,
         FILETIME CTime;
         // Get last file access and modification time
         FILE_OPERATION_LOOP (FMTLOAD(CANT_GET_ATTRS, (FileName)),
-          if (!GetFileTime(Handle, &CTime, &ATime, &MTime)) RaiseLastOSError();
+          THROWOSIFFALSE(GetFileTime(Handle, &CTime, &ATime, &MTime));
         );
         if (ACTime)
         {

+ 1 - 1
source/core/WebDAVFileSystem.cpp

@@ -13304,7 +13304,7 @@ void __fastcall TWebDAVFileSystem::Sink(const UnicodeString FileName,
         );
 
         FILE_OPERATION_LOOP (FMTLOAD(CREATE_DIR_ERROR, (DestFullName.c_str())),
-          if (!ForceDirectories(DestFullName)) { RaiseLastOSError(); }
+          THROWOSIFFALSE(ForceDirectories(DestFullName));
         );
 
         TSinkFileParams SinkFileParams;

+ 17 - 8
source/filezilla/AsyncProxySocketLayer.cpp

@@ -168,6 +168,7 @@ void CAsyncProxySocketLayer::SetProxy(int nProxyType)
 
 void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort)
 {
+	USES_CONVERSION;
 	//Validate the parameters
 	ASSERT(nProxyType==PROXYTYPE_SOCKS4  ||
 		   nProxyType==PROXYTYPE_SOCKS4A ||
@@ -193,6 +194,7 @@ void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, i
 
 void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, const char * pProxyUser, const char * pProxyPass)
 {
+	USES_CONVERSION;
 	//Validate the parameters
 	ASSERT(nProxyType==PROXYTYPE_SOCKS5 || nProxyType==PROXYTYPE_HTTP11);
 	ASSERT(!m_nProxyOpID);
@@ -236,7 +238,8 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 		TriggerEvent(FD_READ, nErrorCode, TRUE);
 	}
 	if (!m_nProxyOpState) //We should not receive a response yet!
-	{ //Ignore it
+	{ 
+		//Ignore it
 		return;
 	}
 	if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
@@ -292,7 +295,8 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 					int port;
 					memcpy(&ip,&m_pRecvBuffer[4],4);
 					if (!ip)
-					{ //No IP return, use the IP of the proxy server
+					{ 
+						//No IP return, use the IP of the proxy server
 						SOCKADDR SockAddr;
 						memset(&SockAddr,0,sizeof(SockAddr));
 						int SockAddrLen=sizeof(SockAddr);
@@ -386,7 +390,6 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 			m_nRecvBufferPos+=numread;
 			if (m_nRecvBufferPos==2)
 			{
-
 				if (m_pRecvBuffer[0]!=5)
 				{
 					DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
@@ -399,9 +402,11 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 					return;
 				}
 				if (m_pRecvBuffer[1])
-				{ //Auth needed
+				{ 
+					//Auth needed
 					if (m_pRecvBuffer[1]!=2)
-					{ //Unknown auth type
+					{ 
+						//Unknown auth type
 						DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
 						if (m_nProxyOpID==PROXYOP_CONNECT)
 							TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
@@ -500,7 +505,8 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 			return;
 		}
 		else if (m_nProxyOpState==2)
-		{//Response to the auth request
+		{
+			//Response to the auth request
 			if (!m_pRecvBuffer)
 				m_pRecvBuffer=new char[2];
 			int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
@@ -576,7 +582,8 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 			}
 		}
 		else if (m_nProxyOpState==3)
-		{//Response to the connection request
+		{
+			//Response to the connection request
 			if (!m_pRecvBuffer)
 			{
 				m_pRecvBuffer=new char[10];
@@ -612,7 +619,8 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 					return;
 				}
 				if (m_nRecvBufferLen==5)
-				{ //Check which kind of address the response contains
+				{ 
+					//Check which kind of address the response contains
 					if (m_pRecvBuffer[3]==1)
 						m_nRecvBufferLen=10;
 					else
@@ -1038,6 +1046,7 @@ void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
 			}
 			delete [] pHost;
 
+			USES_CONVERSION;
 			int numsent=SendNext(str, strlen(str) );
 			int nErrorCode=WSAGetLastError();
 			if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)

+ 11 - 67
source/filezilla/AsyncSocketEx.cpp

@@ -116,9 +116,6 @@ protected:
 
 CCriticalSectionWrapper CAsyncSocketEx::m_sGlobalCriticalSection;
 CAsyncSocketEx::t_AsyncSocketExThreadDataList *CAsyncSocketEx::m_spAsyncSocketExThreadDataList = 0;
-HMODULE CAsyncSocketEx::m_hDll = 0;
-t_getaddrinfo CAsyncSocketEx::p_getaddrinfo = 0;
-t_freeaddrinfo CAsyncSocketEx::p_freeaddrinfo = 0;
 
 
 #ifndef _AFX
@@ -491,7 +488,9 @@ public:
 						pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
 					}
 					else
+					{
 						pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
+					}
 				}
 			}
 #endif //NOLAYERS
@@ -523,7 +522,9 @@ public:
 			
 			//Dispatch to layer
 			if (pMsg->pLayer)
+			{
 				pMsg->pLayer->CallEvent(nEvent, nErrorCode);
+			}
 			else
 			{
 				//Dispatch to CAsyncSocketEx instance
@@ -925,30 +926,6 @@ BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
 	
 	if ((m_SocketData.nFamily == AF_INET6 || m_SocketData.nFamily == AF_INET) && lpszAscii)
 	{
-		if (!p_getaddrinfo)
-		{
-			if (m_SocketData.nFamily != AF_INET)
-			{
-				WSASetLastError(WSAEPROTONOSUPPORT);
-				return FALSE;
-			}
-			else
-			{
-				unsigned long ip = inet_addr(lpszAscii);
-				if (!ip)
-				{
-					WSASetLastError(WSAEINVAL);
-					return FALSE;
-				}
-
-				SOCKADDR_IN sockAddr;
-				memset(&sockAddr, 0, sizeof(sockAddr));
-				sockAddr.sin_family = m_SocketData.nFamily;
-				sockAddr.sin_addr.s_addr = ip;
-				sockAddr.sin_port = htons((u_short)nSocketPort);
-				return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
-			}
-		}
 		addrinfo hints, *res0, *res;
 		int error;
 		char port[10];
@@ -958,7 +935,7 @@ BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
 		hints.ai_family = m_SocketData.nFamily;
 		hints.ai_socktype = SOCK_STREAM;
 		_snprintf(port, 9, "%lu", nSocketPort);
-		error = p_getaddrinfo(lpszAscii, port, &hints, &res0);
+		error = getaddrinfo(lpszAscii, port, &hints, &res0);
 		if (error)
 			return FALSE;
 
@@ -971,7 +948,7 @@ BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
 			else
 				continue ;
 
-			p_freeaddrinfo(res0);
+			freeaddrinfo(res0);
 
 			return ret ;
 	}
@@ -1049,7 +1026,7 @@ void CAsyncSocketEx::Close()
 	}
 	if (m_SocketData.addrInfo)
 	{
-		p_freeaddrinfo(m_SocketData.addrInfo);
+		freeaddrinfo(m_SocketData.addrInfo);
 		m_SocketData.addrInfo = 0;
 		m_SocketData.nextAddr = 0;
 	}
@@ -1118,21 +1095,6 @@ BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
 		m_pLocalAsyncSocketExThreadData->nThreadId=id;
 		m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
 		m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
-
-		m_hDll = LoadLibrary(_T("WS2_32.dll"));
-		if (m_hDll)
-		{
-			p_getaddrinfo = (t_getaddrinfo)GetProcAddress(m_hDll, "getaddrinfo");
-			p_freeaddrinfo = (t_freeaddrinfo)GetProcAddress(m_hDll, "freeaddrinfo");
-
-			if (!p_getaddrinfo || !p_freeaddrinfo)
-			{
-				p_getaddrinfo = 0;
-				p_freeaddrinfo = 0;
-				FreeLibrary(m_hDll);
-				m_hDll = 0;
-			}
-		}
 	}
 	m_sGlobalCriticalSection.Unlock();
 	return TRUE;
@@ -1184,18 +1146,6 @@ void CAsyncSocketEx::FreeAsyncSocketExInstance()
 				else
 					m_spAsyncSocketExThreadDataList=pList->pNext;
 				delete pList;
-
-				// Last thread closed, free dll
-				if (!m_spAsyncSocketExThreadDataList)
-				{
-					if (m_hDll)
-					{
-						p_getaddrinfo = 0;
-						p_freeaddrinfo = 0;
-						FreeLibrary(m_hDll);
-						m_hDll = 0;
-					}
-				}
 				break;
 			}
 
@@ -1281,19 +1231,13 @@ BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
 	}
 	else
 	{
-		if (!p_getaddrinfo)
-		{
-			WSASetLastError(WSAEPROTONOSUPPORT);
-			return FALSE;
-		}
-
 		USES_CONVERSION;
 
 		ASSERT( lpszHostAddress != NULL );
 
 		if (m_SocketData.addrInfo)
 		{
-			p_freeaddrinfo(m_SocketData.addrInfo);
+			freeaddrinfo(m_SocketData.addrInfo);
 			m_SocketData.addrInfo = 0;
 			m_SocketData.nextAddr = 0;
 		}
@@ -1307,7 +1251,7 @@ BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
 		hints.ai_family = m_SocketData.nFamily;
 		hints.ai_socktype = SOCK_STREAM;
 		_snprintf(port, 9, "%lu", nHostPort);
-		error = p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
+		error = getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
 		if (error)
 			return FALSE;
 
@@ -1388,7 +1332,7 @@ BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
 
 		if (!m_SocketData.nextAddr)
 		{
-			p_freeaddrinfo(m_SocketData.addrInfo);
+			freeaddrinfo(m_SocketData.addrInfo);
 			m_SocketData.nextAddr = 0;
 			m_SocketData.addrInfo = 0;
 		}
@@ -1892,7 +1836,7 @@ bool CAsyncSocketEx::TryNextProtocol()
 
 	if (!m_SocketData.nextAddr)
 	{
-		p_freeaddrinfo(m_SocketData.addrInfo);
+		freeaddrinfo(m_SocketData.addrInfo);
 		m_SocketData.nextAddr = 0;
 		m_SocketData.addrInfo = 0;
 	}

+ 0 - 6
source/filezilla/AsyncSocketEx.h

@@ -317,12 +317,6 @@ protected:
 	UINT m_nSocketPort;
 	LPTSTR m_lpszSocketAddress;
 
-	// imported IPv6 functions
-	static HMODULE m_hDll;
-
-	static t_getaddrinfo p_getaddrinfo;
-	static t_freeaddrinfo p_freeaddrinfo;
-
 	friend CAsyncSocketExHelperWindow;
 
 #ifndef NOLAYERS

+ 27 - 12
source/filezilla/AsyncSocketExLayer.cpp

@@ -123,31 +123,45 @@ CAsyncSocketExLayer *CAsyncSocketExLayer::AddLayer(CAsyncSocketExLayer *pLayer,
 
 int CAsyncSocketExLayer::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
 {
-	return ReceiveNext(lpBuf, nBufLen, nFlags);
+	int Result = ReceiveNext(lpBuf, nBufLen, nFlags);
+	return Result;
 }
 
 int CAsyncSocketExLayer::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
 {
-	return SendNext(lpBuf, nBufLen, nFlags);
+	int Result = SendNext(lpBuf, nBufLen, nFlags);
+	return Result;
 }
 
 
 void CAsyncSocketExLayer::OnReceive(int nErrorCode)
 {
 	if (m_pPrevLayer)
+	{
 		m_pPrevLayer->OnReceive(nErrorCode);
+	}	
 	else
+	{
 		if (m_pOwnerSocket->m_lEvent&FD_READ)
+		{
 			m_pOwnerSocket->OnReceive(nErrorCode);
+		}
+	}
 }
 
 void CAsyncSocketExLayer::OnSend(int nErrorCode)
 {
 	if (m_pPrevLayer)
+	{
 		m_pPrevLayer->OnSend(nErrorCode);
+	}
 	else
+	{
 		if (m_pOwnerSocket->m_lEvent&FD_WRITE)
+		{
 			m_pOwnerSocket->OnSend(nErrorCode);
+		}
+	}
 }
 
 void CAsyncSocketExLayer::OnConnect(int nErrorCode)
@@ -229,7 +243,7 @@ void CAsyncSocketExLayer::Close()
 void CAsyncSocketExLayer::CloseNext()
 {
 	if (m_addrInfo)
-		m_pOwnerSocket->p_freeaddrinfo(m_addrInfo);
+		freeaddrinfo(m_addrInfo);
 	m_nextAddr = 0;
 	m_addrInfo = 0;
 
@@ -274,7 +288,9 @@ int CAsyncSocketExLayer::SendNext(const void *lpBuf, int nBufLen, int nFlags /*=
 		return send(m_pOwnerSocket->GetSocketHandle(), (LPSTR)lpBuf, nBufLen, nFlags);
 	}
 	else
+	{
 		return m_pNextLayer->Send(lpBuf, nBufLen, nFlags);
+	}
 }
 
 int CAsyncSocketExLayer::ReceiveNext(void *lpBuf, int nBufLen, int nFlags /*=0*/)
@@ -301,7 +317,9 @@ int CAsyncSocketExLayer::ReceiveNext(void *lpBuf, int nBufLen, int nFlags /*=0*/
 		return recv(m_pOwnerSocket->GetSocketHandle(), (LPSTR)lpBuf, nBufLen, nFlags);
 	}
 	else
+	{
 		return m_pNextLayer->Receive(lpBuf, nBufLen, nFlags);
+	}
 }
 
 BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
@@ -343,11 +361,6 @@ BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
 	}
 	else if (m_nFamily == AF_INET6 || m_nFamily == AF_UNSPEC)
 	{
-		if (!m_pOwnerSocket->p_getaddrinfo)
-		{
-			WSASetLastError(WSAEPROTONOSUPPORT);
-			return FALSE;
-		}
 		USES_CONVERSION;
 
 		ASSERT(lpszHostAddress != NULL);
@@ -357,7 +370,7 @@ BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
 		int error;
 		char port[10];
 
-		m_pOwnerSocket->p_freeaddrinfo(m_addrInfo);
+		freeaddrinfo(m_addrInfo);
 		m_nextAddr = 0;
 		m_addrInfo = 0;
 
@@ -366,7 +379,7 @@ BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
 		hints.ai_socktype = SOCK_STREAM;
 		hints.ai_flags = 0;
 		_snprintf(port, 9, "%lu", nHostPort);
-		error = m_pOwnerSocket->p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &res0);
+		error = getaddrinfo(T2CA(lpszHostAddress), port, &hints, &res0);
 		if (error)
 			return FALSE;
 
@@ -443,7 +456,7 @@ BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
 			m_nextAddr = res1;
 		}
 		else
-			m_pOwnerSocket->p_freeaddrinfo(res0);
+			freeaddrinfo(res0);
 
 		if (INVALID_SOCKET == m_pOwnerSocket->GetSocketHandle())
 			res = FALSE ;
@@ -657,7 +670,9 @@ void CAsyncSocketExLayer::SetLayerState(int nLayerState)
 void CAsyncSocketExLayer::CallEvent(int nEvent, int nErrorCode)
 {
 	if (m_nCriticalError)
+	{
 		return;
+	}
 	m_nCriticalError = nErrorCode;
 	switch (nEvent)
 	{
@@ -995,7 +1010,7 @@ bool CAsyncSocketExLayer::TryNextProtocol()
 
 	if (!m_nextAddr)
 	{
-		m_pOwnerSocket->p_freeaddrinfo(m_addrInfo);
+		freeaddrinfo(m_addrInfo);
 		m_nextAddr = 0;
 		m_addrInfo = 0;
 	}

+ 82 - 81
source/filezilla/AsyncSslSocketLayer.cpp

@@ -512,7 +512,9 @@ void CAsyncSslSocketLayer::OnReceive(int nErrorCode)
 			return;
 		}
 		if (m_nNetworkError)
+		{
 			return;
+		}
 
 		char buffer[16384];
 
@@ -622,7 +624,9 @@ void CAsyncSslSocketLayer::OnSend(int nErrorCode)
 	if (m_bUseSSL)
 	{
 		if (m_nNetworkError)
+		{
 			return;
+		}
 
 		m_mayTriggerWrite = false;
 
@@ -1580,11 +1584,79 @@ void CAsyncSslSocketLayer::UnloadSSL()
 	m_sCriticalSection.Unlock();
 }
 
-BOOL CAsyncSslSocketLayer::GetPeerCertificateData(t_SslCertData &SslCertData)
+bool AsnTimeToValidTime(ASN1_TIME * AsnTime, t_SslCertData::t_validTime & ValidTime)
+{
+	int i = AsnTime->length;
+	const char * v = (const char *)AsnTime->data;
+
+	if (i < 10)
+	{
+		return FALSE;
+	}
+
+	for (int i2 = 0; i2 < 10; i2++)
+	{
+		if ((v[i2] > '9') || (v[i2] < '0'))
+		{
+			return FALSE;
+		}
+	}
+
+	if (AsnTime->type == V_ASN1_UTCTIME)
+	{
+		ValidTime.y= (v[0]-'0')*10+(v[1]-'0');
+		if (ValidTime.y < 50) ValidTime.y+=100;
+		ValidTime.y += 1900;
+		v += 2;
+		i -= 2;
+	}
+	else if (AsnTime->type == V_ASN1_GENERALIZEDTIME)
+	{
+		if (i < 12)
+		{
+			return FALSE;
+		}
+		ValidTime.y = (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
+		v += 4;
+		i -= 4;
+	}
+	else
+	{
+		return FALSE;
+	}
+
+	ValidTime.M = (v[0]-'0')*10+(v[1]-'0');
+	if ((ValidTime.M > 12) || (ValidTime.M < 1))
+	{
+		return FALSE;
+	}
+
+	ValidTime.d = (v[2]-'0')*10+(v[3]-'0');
+	ValidTime.h = (v[4]-'0')*10+(v[5]-'0');
+	ValidTime.m =  (v[6]-'0')*10+(v[7]-'0');
+
+	if ((i >= 10) &&
+			(v[8] >= '0') && (v[8] <= '9') &&
+			(v[9] >= '0') && (v[9] <= '9'))
+	{
+		ValidTime.s = (v[8]-'0')*10+(v[9]-'0');
+	}
+	else
+	{
+		ValidTime.s = 0;
+	}
+
+	return TRUE;
+}
+
+BOOL CAsyncSslSocketLayer::GetPeerCertificateData(t_SslCertData &SslCertData, LPCTSTR & Error)
 {
 	X509 *pX509=pSSL_get_peer_certificate(m_ssl);
 	if (!pX509)
+	{
+		Error = _T("Cannot get certificate");
 		return FALSE;
+	}
 
 	//Reset the contents of SslCertData
 	memset(&SslCertData, 0, sizeof(t_SslCertData));
@@ -1809,110 +1881,37 @@ BOOL CAsyncSslSocketLayer::GetPeerCertificateData(t_SslCertData &SslCertData)
 
 	//Set date fields
 
-	static const char *mon[12]=
-    {
-    "Jan","Feb","Mar","Apr","May","Jun",
-    "Jul","Aug","Sep","Oct","Nov","Dec"
-    };
-
 	//Valid from
-	ASN1_UTCTIME *pTime=X509_get_notBefore(pX509);
+	ASN1_TIME *pTime=X509_get_notBefore(pX509);
 	if (!pTime)
 	{
 		pX509_free(pX509);
+		Error = _T("Cannot get start time");
 		return FALSE;
 	}
 
-	char *v;
-	int gmt = 0;
-	int i;
-	int y=0, M=0, d=0, h=0, m=0, s=0;
-
-	i = pTime->length;
-	v = (char *)pTime->data;
-
-	if (i < 10)
+	if (!AsnTimeToValidTime(pTime, SslCertData.validFrom))
 	{
 		pX509_free(pX509);
+		Error = _T("Invalid start time");
 		return FALSE;
 	}
-	if (v[i-1] == 'Z') gmt=1;
-	for (i=0; i<10; i++)
-		if ((v[i] > '9') || (v[i] < '0'))
-		{
-			pX509_free(pX509);
-			return FALSE;
-		}
-	y= (v[0]-'0')*10+(v[1]-'0');
-	if (y < 50) y+=100;
-	M= (v[2]-'0')*10+(v[3]-'0');
-	if ((M > 12) || (M < 1))
-	{
-		pX509_free(pX509);
-		return FALSE;
-	}
-	d= (v[4]-'0')*10+(v[5]-'0');
-	h= (v[6]-'0')*10+(v[7]-'0');
-	m=  (v[8]-'0')*10+(v[9]-'0');
-	if (	(v[10] >= '0') && (v[10] <= '9') &&
-		(v[11] >= '0') && (v[11] <= '9'))
-		s=  (v[10]-'0')*10+(v[11]-'0');
-
-	SslCertData.validFrom.y = y+1900;
-	SslCertData.validFrom.M = M;
-	SslCertData.validFrom.d = d;
-	SslCertData.validFrom.h = h;
-	SslCertData.validFrom.m = m;
-	SslCertData.validFrom.s = s;
 
 	//Valid until
 	pTime = X509_get_notAfter(pX509);
 	if (!pTime)
 	{
 		pX509_free(pX509);
+		Error = _T("Cannot get end time");
 		return FALSE;
 	}
 
-	gmt = 0;
-	i;
-	y=0,M=0,d=0,h=0,m=0,s=0;
-
-	i=pTime->length;
-	v=(char *)pTime->data;
-
-	if (i < 10)
+	if (!AsnTimeToValidTime(pTime, SslCertData.validUntil))
 	{
 		pX509_free(pX509);
+		Error = _T("Invalid end time");
 		return FALSE;
 	}
-	if (v[i-1] == 'Z') gmt=1;
-	for (i=0; i<10; i++)
-		if ((v[i] > '9') || (v[i] < '0'))
-		{
-			pX509_free(pX509);
-			return FALSE;
-		}
-	y= (v[0]-'0')*10+(v[1]-'0');
-	if (y < 50) y+=100;
-	M= (v[2]-'0')*10+(v[3]-'0');
-	if ((M > 12) || (M < 1))
-	{
-		pX509_free(pX509);
-		return FALSE;
-	}
-	d= (v[4]-'0')*10+(v[5]-'0');
-	h= (v[6]-'0')*10+(v[7]-'0');
-	m=  (v[8]-'0')*10+(v[9]-'0');
-	if (	(v[10] >= '0') && (v[10] <= '9') &&
-		(v[11] >= '0') && (v[11] <= '9'))
-		s=  (v[10]-'0')*10+(v[11]-'0');
-
-	SslCertData.validUntil.y = y+1900;
-	SslCertData.validUntil.M = M;
-	SslCertData.validUntil.d = d;
-	SslCertData.validUntil.h = h;
-	SslCertData.validUntil.m = m;
-	SslCertData.validUntil.s = s;
 
 	unsigned int length = 20;
 	pX509_digest(pX509, pEVP_sha1(), SslCertData.hash, &length);
@@ -2385,7 +2384,9 @@ void CAsyncSslSocketLayer::TriggerEvents()
 	if (m_onCloseCalled && m_bSslEstablished)
 	{
 		if (pBIO_ctrl_pending(m_sslbio) <= 0)
+		{
 			TriggerEvent(FD_CLOSE, 0, TRUE);
+		}
 	}
 }
 

+ 2 - 2
source/filezilla/AsyncSslSocketLayer.h

@@ -143,7 +143,7 @@ public:
 	virtual ~CAsyncSslSocketLayer();
 
 	void SetNotifyReply(int nID, int nCode, int result);
-	BOOL GetPeerCertificateData(t_SslCertData &SslCertData);
+	BOOL GetPeerCertificateData(t_SslCertData &SslCertData, LPCTSTR & Error);
 	std::string GetTlsVersionStr();
 	std::string GetCipherName();
 
@@ -201,7 +201,7 @@ private:
 	static int m_nSslRefCount;
 	BOOL m_bSslInitialized;
 	int m_nShutDown;
-	BOOL m_nNetworkError;
+	int m_nNetworkError;
 	int m_nSslAsyncNotifyId;
 	BOOL m_bBlocking;
 	BOOL m_bSslEstablished;

+ 17 - 10
source/filezilla/FtpControlSocket.cpp

@@ -1352,7 +1352,7 @@ BOOL CFtpControlSocket::Send(CString str)
 		}
 		if (res != sendLen)
 		{
-			if (res == -2)
+			if (res < 0)
 				res = 0;
 			if (!m_sendBuffer)
 			{
@@ -1389,7 +1389,7 @@ BOOL CFtpControlSocket::Send(CString str)
 		}
 		if (res != sendLen)
 		{
-			if (res == -2)
+			if (res < 0)
 				res = 0;
 			if (!m_sendBuffer)
 			{
@@ -2306,10 +2306,10 @@ void CFtpControlSocket::List(BOOL bFinish, int nError /*=FALSE*/, CServerPath pa
 						memset(&hints, 0, sizeof(addrinfo));
 						hints.ai_family = AF_INET6;
 						hints.ai_socktype = SOCK_STREAM;
-						if (!p_getaddrinfo(T2CA(host), "1024", &hints, &res))
+						if (!getaddrinfo(T2CA(host), "1024", &hints, &res))
 						{
 							host = Inet6AddrToString(((SOCKADDR_IN6 *)res->ai_addr)->sin6_addr);
-							p_freeaddrinfo(res);
+							freeaddrinfo(res);
 						}
 						else
 							host = _T("");
@@ -3967,11 +3967,14 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 						}
 					}
 					if (!nReplyError)
+					{
 						m_pTransferSocket->SetActive();
+					}
 				}
 				else if (pData->bPasv)
+				{
 					m_pTransferSocket->SetActive();
-
+				}
 			}
 			break;
 		case FILETRANSFER_WAITFINISH:
@@ -4202,10 +4205,10 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 						memset(&hints, 0, sizeof(addrinfo));
 						hints.ai_family = AF_INET6;
 						hints.ai_socktype = SOCK_STREAM;
-						if (!p_getaddrinfo(T2CA(host), "1024", &hints, &res))
+						if (!getaddrinfo(T2CA(host), "1024", &hints, &res))
 						{
 							host = Inet6AddrToString(((SOCKADDR_IN6 *)res->ai_addr)->sin6_addr);
-							p_freeaddrinfo(res);
+							freeaddrinfo(res);
 						}
 						else
 							host = _T("");
@@ -4442,10 +4445,10 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 						memset(&hints, 0, sizeof(addrinfo));
 						hints.ai_family = AF_INET6;
 						hints.ai_socktype = SOCK_STREAM;
-						if (!p_getaddrinfo(T2CA(host), "1024", &hints, &res))
+						if (!getaddrinfo(T2CA(host), "1024", &hints, &res))
 						{
 							host = Inet6AddrToString(((SOCKADDR_IN6 *)res->ai_addr)->sin6_addr);
-							p_freeaddrinfo(res);
+							freeaddrinfo(res);
 						}
 						else
 							host = _T("");
@@ -5972,7 +5975,8 @@ int CFtpControlSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
 					break;
 				case SSL_VERIFY_CERT:
 					t_SslCertData *pData = new t_SslCertData;
-					if (m_pSslLayer->GetPeerCertificateData(*pData))
+					LPTSTR CertError = NULL;
+					if (m_pSslLayer->GetPeerCertificateData(*pData, CertError))
 					{
 						CVerifyCertRequestData *pRequestData = new CVerifyCertRequestData;
 						pRequestData->nRequestID=m_pOwner->GetNextAsyncRequestID();
@@ -5996,6 +6000,9 @@ int CFtpControlSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
 					{
 						delete pData;
 						delete [] iter->str;
+						CString str;
+						str.Format(TLS_CERT_DECODE_ERROR, CertError);
+						ShowStatus(str, FZ_LOG_ERROR);
 						ResetOperation(FZ_REPLY_ERROR);
 						continue;
 					}

+ 2 - 2
source/filezilla/FtpListResult.cpp

@@ -667,7 +667,7 @@ void CFtpListResult::SendToMessageLog(HWND hWnd, UINT nMsg)
 		t_ffam_statusmessage *pStatus = new t_ffam_statusmessage;
 		pStatus->post = TRUE;
 		pStatus->status = _T("<Empty directory listing>");
-		pStatus->type = 5;
+		pStatus->type = FZ_LOG_INFO;
 		PostMessage(hWnd, nMsg, FZ_MSG_MAKEMSG(FZ_MSG_STATUS, 0), (LPARAM)pStatus);
 	}
 	while (line)
@@ -679,7 +679,7 @@ void CFtpListResult::SendToMessageLog(HWND hWnd, UINT nMsg)
 		t_ffam_statusmessage *pStatus = new t_ffam_statusmessage;
 		pStatus->post = TRUE;
 		pStatus->status = status;
-		pStatus->type = 5;
+		pStatus->type = FZ_LOG_INFO;
 		if (!PostMessage(hWnd, nMsg, FZ_MSG_MAKEMSG(FZ_MSG_STATUS, 0), (LPARAM)pStatus))
 			delete pStatus;
 

+ 2 - 0
source/filezilla/MainThread.cpp

@@ -543,7 +543,9 @@ DWORD CMainThread::Run()
 	{
 		TranslateMessage(&msg);
 		if (!msg.hwnd)
+		{
 			OnThreadMessage(msg.message, msg.wParam, msg.lParam);
+		}
 		DispatchMessage(&msg);
 	}
 	DWORD res = ExitInstance();

+ 89 - 200
source/filezilla/TransferSocket.cpp

@@ -183,13 +183,7 @@ void CTransferSocket::OnReceive(int nErrorCode)
 				else if (res != Z_OK && res != Z_BUF_ERROR)
 				{
 					delete [] out;
-					Close();
-					if (!m_bSentClose)
-					{
-						m_nMode |= CSMODE_TRANSFERERROR;
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
+					CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 					return;
 				}
 				else
@@ -229,12 +223,7 @@ void CTransferSocket::OnReceive(int nErrorCode)
 			delete [] buffer;
 		if (!numread)
 		{
-			Close();
-			if (!m_bSentClose)
-			{
-				m_bSentClose = TRUE;
-				m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-			}
+			CloseAndEnsureSendClose(0);
 		}
 		if (numread == SOCKET_ERROR)
 		{
@@ -253,13 +242,8 @@ void CTransferSocket::OnReceive(int nErrorCode)
 #endif
 			else if (nError != WSAEWOULDBLOCK)
 			{
-				Close();
-				if (!m_bSentClose)
-				{
-					m_nMode |= CSMODE_TRANSFERERROR;
-					m_bSentClose = TRUE;
-					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-				}
+				LogError(nError);
+				CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 			}
 		}
 	}
@@ -295,12 +279,7 @@ void CTransferSocket::OnReceive(int nErrorCode)
 
 		if (!numread)
 		{
-			Close();
-			if (!m_bSentClose)
-			{
-				m_bSentClose = TRUE;
-				m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-			}
+			CloseAndEnsureSendClose(0);
 			return;
 		}
 		
@@ -321,13 +300,8 @@ void CTransferSocket::OnReceive(int nErrorCode)
 #endif
 			else if (nError != WSAEWOULDBLOCK)
 			{
-				Close();
-				if (!m_bSentClose)
-				{
-					m_nMode |= CSMODE_TRANSFERERROR;
-					m_bSentClose = TRUE;
-					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-				}
+				LogError(nError);
+				CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 			}
 
 			UpdateStatusBar(false);
@@ -365,13 +339,8 @@ void CTransferSocket::OnReceive(int nErrorCode)
 				}
 				else if (res != Z_OK && res != Z_BUF_ERROR)
 				{
-					Close();
-					if (!m_bSentClose)
-					{
-						m_nMode |= CSMODE_TRANSFERERROR;
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
+					m_pOwner->ShowStatus(L"Compression error", FZ_LOG_ERROR);
+					CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 					return;
 				}
 			}
@@ -388,13 +357,7 @@ void CTransferSocket::OnReceive(int nErrorCode)
 			if (e->GetErrorMessage(msg, BUFSIZE))
 				m_pOwner->ShowStatus(msg, FZ_LOG_ERROR);
 			delete [] msg;
-			Close();
-			if (!m_bSentClose)
-			{
-				m_nMode |= CSMODE_TRANSFERERROR;
-				m_bSentClose = TRUE;
-				m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-			}
+			CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 			return;
 		}
 		END_CATCH;
@@ -451,13 +414,7 @@ void CTransferSocket::OnAccept(int nErrorCode)
 
 			if (res)
 			{
-				Close();
-				if (!m_bSentClose)
-				{
-					m_nMode |= CSMODE_TRANSFERERROR;
-					m_bSentClose = TRUE;
-					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-				}
+				CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 				return;
 			}
 		}
@@ -488,13 +445,7 @@ void CTransferSocket::OnConnect(int nErrorCode)
 		str.Replace( _T("\n"), _T("\0") );
 		str.Replace( _T("\r"), _T("\0") );
 		m_pOwner->ShowStatus(str, FZ_LOG_ERROR);
-		Close();
-		if (!m_bSentClose)
-		{
-			m_nMode|=CSMODE_TRANSFERERROR;
-			m_bSentClose=TRUE;
-			m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-		}	
+		CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 	}
 	else
 	{
@@ -537,13 +488,7 @@ void CTransferSocket::OnConnect(int nErrorCode)
 					
 			if (res)
 			{
-				Close();
-				if (!m_bSentClose)
-				{
-					m_nMode |= CSMODE_TRANSFERERROR;
-					m_bSentClose = TRUE;
-					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-				}
+				CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 				return;
 			}
 		}
@@ -570,12 +515,7 @@ void CTransferSocket::OnClose(int nErrorCode)
 	}
 
 	OnReceive(0);
-	Close();
-	if (!m_bSentClose)
-	{
-		m_bSentClose=TRUE;
-		m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-	}
+	CloseAndEnsureSendClose(0);
 }
 
 int CTransferSocket::CheckForTimeout(int delay)
@@ -591,13 +531,7 @@ int CTransferSocket::CheckForTimeout(int delay)
 	if (span.GetTotalSeconds()>=delay)
 	{
 		m_pOwner->ShowStatus(IDS_ERRORMSG_TIMEOUT, FZ_LOG_ERROR);
-		Close();
-		if (!m_bSentClose)
-		{
-			m_nMode |= CSMODE_TRANSFERTIMEOUT;
-			m_bSentClose = TRUE;
-			VERIFY(m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode));
-		}
+		CloseAndEnsureSendClose(CSMODE_TRANSFERTIMEOUT);
 		return 2;
 	}
 	return 1;
@@ -704,14 +638,8 @@ void CTransferSocket::OnSend(int nErrorCode)
 				res = deflate(&m_zlibStream, m_pFile ? 0 : Z_FINISH);
 				if (res != Z_OK && (!m_pFile && res != Z_STREAM_END))
 				{
-					m_pOwner->ShowStatus("ZLib error", FZ_LOG_ERROR);
-					Close();
-					if (!m_bSentClose)
-					{
-						m_nMode |= CSMODE_TRANSFERERROR;
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
+					m_pOwner->ShowStatus("Decompression error", FZ_LOG_ERROR);
+					CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 					return;
 				}
 			}
@@ -754,16 +682,7 @@ void CTransferSocket::OnSend(int nErrorCode)
 #endif
 				else if (nError != WSAEWOULDBLOCK)
 				{
-					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-					{
-						Close();
-						if (!m_bSentClose)
-						{
-							m_nMode |= CSMODE_TRANSFERERROR;
-							m_bSentClose = TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
-					}
+					CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
 				}
 				UpdateStatusBar(false);
 				return;
@@ -781,15 +700,7 @@ void CTransferSocket::OnSend(int nErrorCode)
 			if (!m_zlibStream.avail_in && !m_pFile && m_zlibStream.avail_out &&
 				m_zlibStream.avail_out + m_bufferpos == BUFSIZE && res == Z_STREAM_END)
 			{
-				if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-				{
-					Close();
-					if (!m_bSentClose)
-					{
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
-				}
+				CloseOnShutDownOrError(0);
 				return;
 			}
 
@@ -836,15 +747,7 @@ void CTransferSocket::OnSend(int nErrorCode)
 			}
 			else if (!numread && !m_bufferpos)
 			{
-				if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-				{
-					Close();
-					if (!m_bSentClose)
-					{
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
-				}
+				CloseOnShutDownOrError(0);
 				return;
 			}
 		}
@@ -857,15 +760,7 @@ void CTransferSocket::OnSend(int nErrorCode)
 
 		if (numread+m_bufferpos <= 0)
 		{
-			if (ShutDown() || GetLastError()!=WSAEWOULDBLOCK)
-			{
-				Close();
-				if (!m_bSentClose)
-				{
-					m_bSentClose=TRUE;
-					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-				}
-			}
+			CloseOnShutDownOrError(0);
 			return;
 		}
 			
@@ -903,16 +798,7 @@ void CTransferSocket::OnSend(int nErrorCode)
 #endif
 				else
 				{
-					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-					{
-						Close();
-						if (!m_bSentClose)
-						{
-							m_nMode |= CSMODE_TRANSFERERROR;
-							m_bSentClose = TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
-					}
+					CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
 				}
 				UpdateStatusBar(false);
 				return;
@@ -924,29 +810,12 @@ void CTransferSocket::OnSend(int nErrorCode)
 				if (pos < 0 || (numsent + pos) > BUFSIZE)
 				{
 					LogMessage(__FILE__, __LINE__, this, FZ_LOG_WARNING, _T("Index out of range"));
-					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-					{
-						Close();
-						if (!m_bSentClose)
-						{
-							m_nMode |= CSMODE_TRANSFERERROR;
-							m_bSentClose = TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
-					}
+					CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
 					return;
 				}
 				else if (!pos && numread < (currentBufferSize-m_bufferpos) && m_bufferpos != currentBufferSize)
 				{
-					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-					{
-						Close();
-						if (!m_bSentClose)
-						{
-							m_bSentClose = TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
-					}
+					CloseOnShutDownOrError(0);
 					return;
 				}
 				else if (!pos)
@@ -983,15 +852,7 @@ void CTransferSocket::OnSend(int nErrorCode)
 				}
 				else if (!numread && !m_bufferpos)
 				{
-					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-					{
-						Close();
-						if (!m_bSentClose)
-						{
-							m_bSentClose = TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
-					}
+					CloseOnShutDownOrError(0);
 					return;
 				}
 			}
@@ -1271,12 +1132,7 @@ int CTransferSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
 					switch(iter->nParam2)
 					{
 					case SSL_INFO_SHUTDOWNCOMPLETE:
-						Close();
-						if (!m_bSentClose)
-						{
-							m_bSentClose=TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
+						CloseAndEnsureSendClose(0);
 						break;
 					case SSL_INFO_ESTABLISHED:
 						m_pOwner->ShowStatus(IDS_STATUSMSG_SSLESTABLISHEDTRANSFER, FZ_LOG_STATUS);
@@ -1299,26 +1155,19 @@ int CTransferSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
 						m_pOwner->ShowStatus(IDS_ERRORMSG_CANTINITSSL, FZ_LOG_ERROR);
 						break;
 					}
-					if (!m_bSentClose)
-					{
-						m_nMode |= CSMODE_TRANSFERERROR;
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
+					EnsureSendClose(CSMODE_TRANSFERERROR);
 					break;
 				case SSL_VERIFY_CERT:
 					t_SslCertData data;
-					if (m_pSslLayer->GetPeerCertificateData(data))
+					LPTSTR CertError = NULL;
+					if (m_pSslLayer->GetPeerCertificateData(data, CertError))
 						m_pSslLayer->SetNotifyReply(data.priv_data, SSL_VERIFY_CERT, 1);
 					else
 					{
-						Close();
-						if (!m_bSentClose)
-						{
-							m_nMode |= CSMODE_TRANSFERERROR;
-							m_bSentClose = TRUE;
-							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-						}
+						CString str;
+						str.Format(TLS_CERT_DECODE_ERROR, CertError);
+						m_pOwner->ShowStatus(str, FZ_LOG_ERROR);
+						CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
 					}
 					break;
 				}
@@ -1337,12 +1186,7 @@ int CTransferSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
 					LogMessageRaw(FZ_LOG_APIERROR, A2CT(iter->str));
 					break;
 				case GSS_SHUTDOWN_COMPLETE:
-					Close();
-					if (!m_bSentClose)
-					{
-						m_bSentClose = TRUE;
-						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-					}
+					CloseAndEnsureSendClose(0);
 					break;
 				}
 			}
@@ -1450,16 +1294,7 @@ int CTransferSocket::ReadDataFromFile(char *buffer, int len)
 		TCHAR error[BUFSIZE];
 		if (e->GetErrorMessage(error, BUFSIZE))
 			m_pOwner->ShowStatus(error, FZ_LOG_ERROR);
-		if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
-		{
-			Close();
-			if (!m_bSentClose)
-			{
-				m_nMode |= CSMODE_TRANSFERERROR;
-				m_bSentClose = TRUE;
-				m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
-			}
-		}
+		CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
 		return -1;
 	}
 	END_CATCH_ALL;
@@ -1469,3 +1304,57 @@ void CTransferSocket::LogSocketMessage(int nMessageType, LPCTSTR pMsgFormat)
 {
 	LogMessage(nMessageType, pMsgFormat);
 }
+
+void CTransferSocket::EnsureSendClose(int Mode)
+{
+  if (!m_bSentClose)
+  {
+    if (Mode != 0)
+    {
+      m_nMode |= Mode;
+    }
+    m_bSentClose = TRUE;
+    VERIFY(m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode));
+  }
+}
+
+void CTransferSocket::CloseAndEnsureSendClose(int Mode)
+{
+  Close();
+  EnsureSendClose(Mode);
+}
+
+void CTransferSocket::CloseOnShutDownOrError(int Mode)
+{
+  if (ShutDown())
+  {
+    CloseAndEnsureSendClose(Mode);
+  }
+  else
+  {
+    int Error = GetLastError();
+    if (Error != WSAEWOULDBLOCK)
+    {
+      // Log always or only when (Mode & CSMODE_TRANSFERERROR)?
+      // Does it anyway make sense at all to call this with Mode == 0?
+      LogError(Error);
+      CloseAndEnsureSendClose(Mode);
+    }
+  }
+}
+
+void CTransferSocket::LogError(int Error)
+{
+  wchar_t * Buffer;
+  int Len = FormatMessage(
+    FORMAT_MESSAGE_FROM_SYSTEM |
+    FORMAT_MESSAGE_IGNORE_INSERTS |
+    FORMAT_MESSAGE_ARGUMENT_ARRAY |
+    FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, Error, 0, (LPTSTR)&Buffer, 0, NULL);
+  if (Len > 0)
+  {
+    m_pOwner->ShowStatus(Buffer, FZ_LOG_ERROR);
+    LocalFree(Buffer);
+  }
+}
+

+ 4 - 0
source/filezilla/TransferSocket.h

@@ -127,6 +127,10 @@ protected:
 	BOOL m_bShutDown;
 
 	void Transfered(int count, CTime time);
+	void CloseAndEnsureSendClose(int Mode);
+	void EnsureSendClose(int Mode);
+	void CloseOnShutDownOrError(int Mode);
+	void LogError(int Error);
 
 	DWORD m_Transfered[SPEED_SECONDS];
 	bool m_UsedForTransfer[SPEED_SECONDS];

+ 13 - 2
source/forms/About.cpp

@@ -52,8 +52,8 @@ __fastcall TAboutDialog::TAboutDialog(TComponent * AOwner,
   ApplicationLabel->Caption = AppName;
   PuttyVersionLabel->Caption = FMTLOAD(PUTTY_BASED_ON, (LoadStr(PUTTY_VERSION)));
   PuttyCopyrightLabel->Caption = LoadStr(PUTTY_COPYRIGHT);
-  FileZillaVersionLabel->Caption = FMTLOAD(FILEZILLA_BASED_ON, (LoadStr(FILEZILLA_VERSION)));
-  FileZillaCopyrightLabel->Caption = LoadStr(FILEZILLA_COPYRIGHT);
+  FileZillaVersionLabel->Caption = LoadStr(FILEZILLA_BASED_ON2);
+  FileZillaCopyrightLabel->Caption = LoadStr(FILEZILLA_COPYRIGHT2);
   OpenSSLVersionLabel->Caption = FMTLOAD(OPENSSL_BASED_ON, (LoadStr(OPENSSL_VERSION)));
   OpenSSLCopyrightLabel->Caption = LoadStr(OPENSSL_COPYRIGHT);
   WinSCPCopyrightLabel->Caption = LoadStr(WINSCP_COPYRIGHT);
@@ -161,10 +161,21 @@ __fastcall TAboutDialog::TAboutDialog(TComponent * AOwner,
   #endif
   #endif
 
+  // VCL wrongly autosize these, even when AutoSize is off
+  // WORKAROUND
+  FixWrappedLabelSize(Label7);
+  FixWrappedLabelSize(RegistrationSubjectLabel);
+  FixWrappedLabelSize(OpenSSLVersionLabel);
+
   LicenseButton->Visible = AllowLicense;
   LoadData();
 }
 //---------------------------------------------------------------------------
+void __fastcall TAboutDialog::FixWrappedLabelSize(TLabel * Label)
+{
+  Label->Width = Label->Parent->ClientWidth - (2 * Label->Left);
+}
+//---------------------------------------------------------------------------
 void __fastcall TAboutDialog::LoadData()
 {
   UnicodeString Version = FConfiguration->VersionStr;

+ 29 - 33
source/forms/About.dfm

@@ -9,11 +9,7 @@ object AboutDialog: TAboutDialog
   ClientHeight = 484
   ClientWidth = 388
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = True
   Position = poOwnerFormCenter
   DesignSize = (
@@ -31,28 +27,28 @@ object AboutDialog: TAboutDialog
   object VersionLabel: TLabel
     Left = 72
     Top = 28
-    Width = 126
+    Width = 127
     Height = 13
     Caption = 'Version 2.0.0 (Build 12) XX'
   end
   object WinSCPCopyrightLabel: TLabel
     Left = 72
     Top = 56
-    Width = 173
+    Width = 180
     Height = 13
     Caption = 'Copyright '#169' 2000-2003 Martin Prikryl'
   end
   object ProductSpecificMessageLabel: TLabel
     Left = 72
     Top = 100
-    Width = 269
+    Width = 277
     Height = 13
     Caption = 'To send comments and report bugs use support forum at:'
   end
   object TranslatorLabel: TLabel
     Left = 72
     Top = 144
-    Width = 73
+    Width = 74
     Height = 13
     Caption = 'TranslatorLabel'
   end
@@ -3493,7 +3489,7 @@ object AboutDialog: TAboutDialog
   object Label3: TLabel
     Left = 72
     Top = 303
-    Width = 87
+    Width = 91
     Height = 13
     Anchors = [akLeft, akBottom]
     Caption = 'Portions copyright:'
@@ -3501,7 +3497,7 @@ object AboutDialog: TAboutDialog
   object RegistrationLabel: TLabel
     Left = 72
     Top = 188
-    Width = 126
+    Width = 127
     Height = 13
     Anchors = [akLeft, akBottom]
     Caption = 'This product is licensed to:'
@@ -3509,7 +3505,7 @@ object AboutDialog: TAboutDialog
   object HomepageLabel: TStaticText
     Left = 72
     Top = 72
-    Width = 133
+    Width = 128
     Height = 17
     Caption = 'http://XXXXXXwinscp.net/'
     TabOrder = 2
@@ -3518,7 +3514,7 @@ object AboutDialog: TAboutDialog
   object ForumUrlLabel: TStaticText
     Left = 72
     Top = 116
-    Width = 150
+    Width = 148
     Height = 17
     Caption = 'http://XXXXwinscp.net/forum/'
     TabOrder = 3
@@ -3527,7 +3523,7 @@ object AboutDialog: TAboutDialog
   object TranslatorUrlLabel: TStaticText
     Left = 72
     Top = 160
-    Width = 150
+    Width = 148
     Height = 17
     Caption = 'http://XXXXwinscp.net/forum/'
     TabOrder = 4
@@ -3552,7 +3548,7 @@ object AboutDialog: TAboutDialog
     object Label7: TLabel
       Left = 8
       Top = 8
-      Width = 274
+      Width = 232
       Height = 41
       Anchors = [akLeft, akTop, akRight]
       AutoSize = False
@@ -3564,56 +3560,56 @@ object AboutDialog: TAboutDialog
     object PuttyVersionLabel: TLabel
       Left = 8
       Top = 48
-      Width = 196
+      Width = 189
       Height = 13
       Caption = 'SSH and SCP code based on PuTTY xxx'
     end
     object PuttyCopyrightLabel: TLabel
       Left = 8
       Top = 64
-      Width = 145
+      Width = 151
       Height = 13
       Caption = 'Copyright '#169' xxx Simon Tatham'
     end
     object Label8: TLabel
       Left = 8
       Top = 365
-      Width = 181
+      Width = 186
       Height = 13
       Caption = 'Filemanager Toolset library Version 2.6'
     end
     object Label10: TLabel
       Left = 8
       Top = 381
-      Width = 137
+      Width = 139
       Height = 13
       Caption = 'Copyright '#169' 1999 Ingo Eckel'
     end
     object Label1: TLabel
       Left = 8
       Top = 253
-      Width = 117
+      Width = 122
       Height = 13
       Caption = 'Toolbar2000 library 2.1.6'
     end
     object Label2: TLabel
       Left = 8
       Top = 269
-      Width = 182
+      Width = 187
       Height = 13
       Caption = 'Copyright '#169' 1998-2005 Jordan Russell'
     end
     object Label5: TLabel
       Left = 8
       Top = 309
-      Width = 69
+      Width = 70
       Height = 13
       Caption = 'TBX library 2.1'
     end
     object Label6: TLabel
       Left = 8
       Top = 325
-      Width = 188
+      Width = 194
       Height = 13
       Caption = 'Copyright '#169' 2001-2005 Alex A. Denisov'
     end
@@ -3627,7 +3623,7 @@ object AboutDialog: TAboutDialog
     object FileZillaCopyrightLabel: TLabel
       Left = 8
       Top = 144
-      Width = 126
+      Width = 131
       Height = 13
       Caption = 'Copyright '#169' xxx Tim Kosse'
     end
@@ -3645,7 +3641,7 @@ object AboutDialog: TAboutDialog
     object OpenSSLCopyrightLabel: TLabel
       Left = 8
       Top = 213
-      Width = 186
+      Width = 191
       Height = 13
       Caption = 'Copyright '#169' xxxx The OpenSSL Project'
     end
@@ -3653,7 +3649,7 @@ object AboutDialog: TAboutDialog
       Tag = 1
       Left = 8
       Top = 80
-      Width = 74
+      Width = 73
       Height = 17
       Caption = 'Display license'
       TabOrder = 0
@@ -3663,7 +3659,7 @@ object AboutDialog: TAboutDialog
     object PuttyHomepageLabel: TStaticText
       Left = 8
       Top = 96
-      Width = 281
+      Width = 286
       Height = 17
       Caption = 'http://XXXwww.chiark.greenend.org.uk/~sgtatham/putty/'
       TabOrder = 1
@@ -3672,7 +3668,7 @@ object AboutDialog: TAboutDialog
     object Toolbar2000HomepageLabel: TStaticText
       Left = 8
       Top = 285
-      Width = 180
+      Width = 189
       Height = 17
       Caption = 'http://www.jrsoftware.org/tb2kdl.php'
       TabOrder = 4
@@ -3681,7 +3677,7 @@ object AboutDialog: TAboutDialog
     object TBXHomepageLabel: TStaticText
       Left = 8
       Top = 341
-      Width = 142
+      Width = 146
       Height = 17
       Caption = 'http://indasoftware.com/tbx/'
       TabOrder = 5
@@ -3690,7 +3686,7 @@ object AboutDialog: TAboutDialog
     object FileZillaHomepageLabel: TStaticText
       Left = 8
       Top = 160
-      Width = 168
+      Width = 171
       Height = 17
       Caption = 'http://XXXfilezilla.sourceforge.net/'
       TabOrder = 2
@@ -3754,7 +3750,7 @@ object AboutDialog: TAboutDialog
     object RegistrationSubjectLabel: TLabel
       Left = 8
       Top = 8
-      Width = 285
+      Width = 277
       Height = 65
       Anchors = [akLeft, akTop, akRight]
       AutoSize = False
@@ -3764,14 +3760,14 @@ object AboutDialog: TAboutDialog
     object RegistrationLicensesLabel: TLabel
       Left = 8
       Top = 43
-      Width = 107
+      Width = 106
       Height = 13
       Caption = 'Number of Licenses: X'
     end
     object RegistrationProductIdLabel: TStaticText
       Left = 8
       Top = 65
-      Width = 132
+      Width = 148
       Height = 17
       Caption = 'Product ID: xxxx-xxxx-xxxxx'
       TabOrder = 0

+ 1 - 0
source/forms/About.h

@@ -61,6 +61,7 @@ private:
   TNotifyEvent FOnRegistrationLink;
   void __fastcall FirstScrollingControlEnter(TObject * Sender);
   void __fastcall LastScrollingControlEnter(TObject * Sender);
+  void __fastcall FixWrappedLabelSize(TLabel * Label);
 public:
   virtual __fastcall TAboutDialog(TComponent * AOwner,
     TConfiguration * Configuration, bool AllowLicense, TRegistration * Registration);

+ 7 - 2
source/forms/Authenticate.cpp

@@ -10,6 +10,7 @@
 #include <TextsWin.h>
 #include <Terminal.h>
 #include <CoreMain.h>
+#include <PasTools.hpp>
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma link "PasswordEdit"
@@ -30,6 +31,7 @@ void __fastcall TAuthenticateForm::Init(TTerminal * Terminal)
   UseSystemSettings(this);
   FShowAsModalStorage = NULL;
   FFocusControl = NULL;
+  UseDesktopFont(LogView);
 
   FPromptParent = InstructionsLabel->Parent;
   FPromptLeft = InstructionsLabel->Left;
@@ -38,7 +40,7 @@ void __fastcall TAuthenticateForm::Init(TTerminal * Terminal)
   FPromptEditGap = PromptEdit1->Top - PromptLabel1->Top - PromptLabel1->Height;
   FPromptsGap = PromptLabel2->Top - PromptEdit1->Top - PromptEdit1->Height;
 
-  ClientHeight = 270;
+  ClientHeight = ScaleByTextHeight(this, 270);
 
   ClearLog();
 }
@@ -320,6 +322,7 @@ bool __fastcall TAuthenticateForm::Execute(UnicodeString Status, TPanel * Panel,
   TWinControl * FocusControl, TButton * DefaultButton, TButton * CancelButton,
   bool FixHeight, bool Zoom, bool ForceLog)
 {
+  TModalResult DefaultButtonResult;
   TAlign Align = Panel->Align;
   try
   {
@@ -328,6 +331,8 @@ bool __fastcall TAuthenticateForm::Execute(UnicodeString Status, TPanel * Panel,
     DefaultButton->Default = true;
     CancelButton->Cancel = true;
 
+    DefaultButtonResult = DefaultResult(this);
+
     if (Zoom)
     {
       Panel->Align = alClient;
@@ -430,7 +435,7 @@ bool __fastcall TAuthenticateForm::Execute(UnicodeString Status, TPanel * Panel,
     AdjustControls();
   }
 
-  bool Result = (ModalResult != mrCancel);
+  bool Result = (ModalResult == DefaultButtonResult);
 
   if (!Result)
   {

+ 1 - 9
source/forms/Authenticate.dfm

@@ -11,11 +11,7 @@ object AuthenticateForm: TAuthenticateForm
   Color = clBtnFace
   Constraints.MinHeight = 200
   Constraints.MinWidth = 280
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnResize = FormResize
@@ -33,10 +29,6 @@ object AuthenticateForm: TAuthenticateForm
         Width = 100
       end>
     DoubleBuffered = True
-    Items.ItemData = {
-      033C0000000100000000000000FFFFFFFFFFFFFFFF00000000FFFFFFFF000000
-      001141007500740068006E0065007400690063006100740069006E0067002E00
-      2E002E00}
     ReadOnly = True
     RowSelect = True
     ParentDoubleBuffered = False

+ 45 - 39
source/forms/Cleanup.cpp

@@ -23,7 +23,7 @@ Boolean __fastcall DoCleanupDialog(TStoredSessionList *SessionList,
     CleanupDialog->SessionList = SessionList;
     CleanupDialog->Configuration = Configuration;
 
-    Result = (CleanupDialog->ShowModal() == mrOk);
+    Result = (CleanupDialog->ShowModal() == DefaultResult(CleanupDialog));
     if (Result)
     {
       for (int i = wdConfiguration; i <= wdTemporaryFolders; i++)
@@ -80,34 +80,58 @@ __fastcall TCleanupDialog::TCleanupDialog(TComponent* AOwner)
 //---------------------------------------------------------------------
 void __fastcall TCleanupDialog::InitControls()
 {
-  static const int Captions[] = {
-    CLEANUP_CONFIG, CLEANUP_SESSIONS, CLEANUP_HOSTKEYS, CLEANUP_INIFILE,
-    CLEANUP_SEEDFILE, CLEANUP_TEMP_FOLDERS };
-
-  int I = 0;
-  while (I < DataListView->Items->Count)
+  for (int i = wdConfiguration; i <= wdTemporaryFolders; i++)
   {
-    TListItem *Item = DataListView->Items->Item[I];
+    UnicodeString Caption;
     UnicodeString Location;
-    Item->Caption = LoadStr(Captions[Item->ImageIndex - 1]);
-    switch (Item->ImageIndex) {
-      case wdConfiguration: Location = Configuration->ConfigurationSubKey; break;
-      case wdStoredSessions: Location = Configuration->StoredSessionsSubKey; break;
-      case wdHostKeys: Location = Configuration->SshHostKeysSubKey; break;
-      case wdConfigurationIniFile: Location = ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading); break;
-      case wdRandomSeedFile: Location = ExpandEnvironmentVariables(Configuration->RandomSeedFile); break;
-      case wdTemporaryFolders: Location = WinConfiguration->TemporaryDir(true); break;
-      default: Location = L""; break;
+
+    switch (i)
+    {
+      case wdConfiguration:
+        Caption = LoadStr(CLEANUP_CONFIG);
+        Location = Configuration->ConfigurationSubKey;
+        break;
+
+      case wdStoredSessions:
+        Caption = LoadStr(CLEANUP_SESSIONS);
+        Location = Configuration->StoredSessionsSubKey;
+        break;
+
+      case wdHostKeys:
+        Caption = LoadStr(CLEANUP_HOSTKEYS);
+        Location = Configuration->SshHostKeysSubKey;
+        break;
+
+      case wdConfigurationIniFile:
+        Caption = LoadStr(CLEANUP_INIFILE);
+        Location = ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading);
+        break;
+
+      case wdRandomSeedFile:
+        Caption = LoadStr(CLEANUP_SEEDFILE);
+        Location = ExpandEnvironmentVariables(Configuration->RandomSeedFile);
+        break;
+
+      case wdTemporaryFolders:
+        Caption = LoadStr(CLEANUP_TEMP_FOLDERS);
+        Location = WinConfiguration->TemporaryDir(true);
+        break;
+
+      default:
+        FAIL;
+        break;
     }
 
-    if (Item->ImageIndex < wdConfigurationIniFile)
+    TListItem * Item = DataListView->Items->Add();
+    Item->Caption = Caption;
+    if (i < wdConfigurationIniFile)
     {
       Location = Configuration->RootKeyStr + L'\\' +
         Configuration->RegistryStorageKey + L'\\' + Location;
     }
 
     Item->SubItems->Add(Location);
-    I++;
+    assert(Item->Index == i - 1);
   }
 }
 //---------------------------------------------------------------------
@@ -148,27 +172,9 @@ void __fastcall TCleanupDialog::DataListViewInfoTip(TObject * /*Sender*/,
     ARRAYOFCONST((Item->Caption, Item->SubItems->Strings[0])));
 }
 //---------------------------------------------------------------------------
-void __fastcall TCleanupDialog::SetCleanupData(TWinSCPData Data, Boolean value)
+bool __fastcall TCleanupDialog::GetCleanupData(TWinSCPData Data)
 {
-  for (Integer Index = 0; Index < DataListView->Items->Count; Index ++)
-  {
-    TListItem *Item = DataListView->Items->Item[Index];
-    if ((Item->ImageIndex == Data) && (Item->Checked != value))
-    {
-      Item->Checked = value;
-      UpdateControls();
-    }
-  }
-}
-//---------------------------------------------------------------------------
-Boolean __fastcall TCleanupDialog::GetCleanupData(TWinSCPData Data)
-{
-  for (Integer Index = 0; Index < DataListView->Items->Count; Index ++)
-  {
-    TListItem *Item = DataListView->Items->Item[Index];
-    if (Item->ImageIndex == Data) return Item->Checked;
-  }
-  return False;
+  return DataListView->Items->Item[Data - 1]->Checked;
 }
 //---------------------------------------------------------------------------
 void __fastcall TCleanupDialog::HelpButtonClick(TObject * /*Sender*/)

+ 1 - 14
source/forms/Cleanup.dfm

@@ -75,19 +75,6 @@ object CleanupDialog: TCleanupDialog
     ColumnClick = False
     DoubleBuffered = True
     HideSelection = False
-    Items.ItemData = {
-      056A0100000600000001000000FFFFFFFFFFFFFFFF00000000FFFFFFFF000000
-      0016470065006E006500720061006C00200063006F006E006600690067007500
-      72006100740069006F006E00580002000000FFFFFFFFFFFFFFFF00000000FFFF
-      FFFF000000000653006900740065007300580003000000FFFFFFFFFFFFFFFF00
-      000000FFFFFFFF0000000011430061006300680065006400200068006F007300
-      740020006B00650079007300580004000000FFFFFFFFFFFFFFFF00000000FFFF
-      FFFF000000001743006F006E00660069006700750072006100740069006F006E
-      00200049004E0049002000660069006C006500580005000000FFFFFFFFFFFFFF
-      FF00000000FFFFFFFF0000000011520061006E0064006F006D00200073006500
-      650064002000660069006C006500580006000000FFFFFFFFFFFFFFFF00000000
-      FFFFFFFF0000000012540065006D0070006F007200610072007900200066006F
-      006C0064006500720073005800}
     ReadOnly = True
     RowSelect = True
     ParentDoubleBuffered = False
@@ -102,7 +89,7 @@ object CleanupDialog: TCleanupDialog
   object CheckAllButton: TButton
     Left = 8
     Top = 266
-    Width = 89
+    Width = 108
     Height = 25
     Anchors = [akLeft, akBottom]
     Caption = 'Un/check &all'

+ 2 - 3
source/forms/Cleanup.h

@@ -37,13 +37,12 @@ private:
   TConfiguration * FConfiguration;
   void __fastcall InitControls();
   void __fastcall UpdateControls();
-  void __fastcall SetCleanupData(TWinSCPData Data, Boolean value);
-  Boolean __fastcall GetCleanupData(TWinSCPData Data);
+  bool __fastcall GetCleanupData(TWinSCPData Data);
 public:
   virtual __fastcall TCleanupDialog(TComponent* AOwner);
   __property TStoredSessionList *SessionList  = { read=FSessionList, write=FSessionList };
   __property TConfiguration * Configuration  = { read=FConfiguration, write=FConfiguration };
-  __property Boolean CleanupData[TWinSCPData Data]  = { read=GetCleanupData, write=SetCleanupData };
+  __property Boolean CleanupData[TWinSCPData Data]  = { read=GetCleanupData };
 };
 //----------------------------------------------------------------------------
 #endif

+ 7 - 11
source/forms/Console.cpp

@@ -11,6 +11,7 @@
 
 #include "Console.h"
 #include <Tools.h>
+#include <PasTools.hpp>
 //---------------------------------------------------------------------
 #pragma link "HistoryComboBox"
 #pragma link "PathLabel"
@@ -44,16 +45,11 @@ __fastcall TConsoleDialog::TConsoleDialog(TComponent* AOwner)
   FLastTerminal = NULL;
   FDirectoryChanged = false;
   OutputMemo->Color = clBlack;
-  OutputMemo->Font->Color = (TColor)0x00BBBBBB; //clGray;
+  OutputMemo->Font->Color = (TColor)0x00BBBBBB;
   FixComboBoxResizeBug(CommandEdit);
   UseSystemSettings(this);
-  try
-  {
-    OutputMemo->Font->Name = L"Courier New";
-  }
-  catch(...)
-  {
-  }
+  OutputMemo->Font->Name = CustomWinConfiguration->DefaultFixedWidthFontName;
+  OutputMemo->Font->Size = CustomWinConfiguration->DefaultFixedWidthFontSize;
 }
 //---------------------------------------------------------------------
 __fastcall TConsoleDialog::~TConsoleDialog()
@@ -293,9 +289,9 @@ void __fastcall TConsoleDialog::DoAdjustWindow()
   }
 
   // 10 is surplus to cover any borders, etc.
-  int RequiredWidth = (TM.tmAveCharWidth * Columns) + 10;
-  // thre is always one line more
-  int RequiredHeight = (TM.tmHeight + TM.tmExternalLeading) * (Rows + 1) + 10;
+  int RequiredWidth = (TM.tmAveCharWidth * Columns) + ScaleByTextHeight(this, 10);
+  // there is always one line more
+  int RequiredHeight = (TM.tmHeight + TM.tmExternalLeading) * (Rows + 1) + ScaleByTextHeight(this, 10);
 
   int CurrentWidth = (Rect.Right - Rect.Left);
   int CurrentHeight = (Rect.Bottom - Rect.Top);

+ 7 - 11
source/forms/Copy.cpp

@@ -364,7 +364,7 @@ bool __fastcall TCopyDialog::Execute()
   FPreset = GUIConfiguration->CopyParamCurrent;
   DirectoryEdit->Items = CustomWinConfiguration->History[
     FToRemote ? L"RemoteTarget" : L"LocalTarget"];
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
     Configuration->BeginUpdate();
@@ -390,7 +390,7 @@ bool __fastcall TCopyDialog::Execute()
 void __fastcall TCopyDialog::FormCloseQuery(TObject * /*Sender*/,
       bool &CanClose)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     if (!RemotePaths() && ((FOptions & coTemp) == 0))
     {
@@ -455,9 +455,7 @@ void __fastcall TCopyDialog::TransferSettingsButtonClick(TObject * /*Sender*/)
 {
   if (FLAGCLEAR(FOptions, coDoNotUsePresets) && !SupportsSplitButton())
   {
-    CopyParamListPopup(
-      TransferSettingsButton->ClientToScreen(TPoint(0, TransferSettingsButton->Height)),
-      0);
+    CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);
   }
   else
   {
@@ -505,16 +503,16 @@ void __fastcall TCopyDialog::CopyParamGroupContextPopup(TObject * /*Sender*/,
 {
   if (FLAGCLEAR(FOptions, coDoNotUsePresets))
   {
-    CopyParamListPopup(CopyParamGroup->ClientToScreen(MousePos), cplCustomizeDefault);
+    CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault);
     Handled = true;
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TCopyDialog::CopyParamListPopup(TPoint P, int AdditionalOptions)
+void __fastcall TCopyDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
 {
   bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
 
-  ::CopyParamListPopup(P, FPresetsMenu,
+  ::CopyParamListPopup(R, FPresetsMenu,
     FCopyParams, FPreset, CopyParamClick,
     cplCustomize | AdditionalOptions |
       FLAGMASK(
@@ -526,9 +524,7 @@ void __fastcall TCopyDialog::CopyParamListPopup(TPoint P, int AdditionalOptions)
 //---------------------------------------------------------------------------
 void __fastcall TCopyDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
 {
-  CopyParamListPopup(
-    TransferSettingsButton->ClientToScreen(TPoint(0, TransferSettingsButton->Height)),
-    cplCustomizeDefault);
+  CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
 }
 //---------------------------------------------------------------------------
 void __fastcall TCopyDialog::NeverShowAgainCheckClick(TObject * /*Sender*/)

+ 3 - 7
source/forms/Copy.dfm

@@ -9,11 +9,7 @@ object CopyDialog: TCopyDialog
   ClientHeight = 189
   ClientWidth = 511
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnCloseQuery = FormCloseQuery
@@ -160,7 +156,7 @@ object CopyDialog: TCopyDialog
   object DirectoryLabel: TLabel
     Left = 46
     Top = 8
-    Width = 187
+    Width = 195
     Height = 13
     Caption = 'Copy 2 selected files to remote directory'
   end
@@ -918,7 +914,7 @@ object CopyDialog: TCopyDialog
   object TransferSettingsButton: TButton
     Left = 8
     Top = 136
-    Width = 129
+    Width = 161
     Height = 25
     Caption = 'Transfer settin&gs...'
     TabOrder = 6

+ 1 - 1
source/forms/Copy.h

@@ -75,7 +75,7 @@ protected:
   void __fastcall AdjustControls();
   void __fastcall AdjustTransferControls();
   bool __fastcall RemotePaths();
-  void __fastcall CopyParamListPopup(TPoint P, int AdditionalOptions);
+  void __fastcall CopyParamListPopup(TRect R, int AdditionalOptions);
 public:
   __fastcall TCopyDialog(TComponent* Owner, bool ToRemote, bool Move, TStrings * FileList, int Options, int CopyParamAttrs);
   virtual __fastcall ~TCopyDialog();

+ 2 - 2
source/forms/CopyParamCustom.cpp

@@ -47,7 +47,7 @@ bool __fastcall TCopyParamCustomDialog::Execute(TCopyParamType & CopyParam)
   CopyParamsFrame->Params = CopyParam;
 
   CopyParamsFrame->BeforeExecute();
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
 
   if (Result)
   {
@@ -62,7 +62,7 @@ bool __fastcall TCopyParamCustomDialog::Execute(TCopyParamType & CopyParam)
 void __fastcall TCopyParamCustomDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     ExitActiveControl(this);
   }

+ 1 - 5
source/forms/CopyParamCustom.dfm

@@ -9,11 +9,7 @@ object CopyParamCustomDialog: TCopyParamCustomDialog
   ClientHeight = 463
   ClientWidth = 420
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnCloseQuery = FormCloseQuery

+ 2 - 2
source/forms/CopyParamPreset.cpp

@@ -98,7 +98,7 @@ bool __fastcall TCopyParamPresetDialog::Execute(TCopyParamList * CopyParamList,
   }
 
   CopyParamsFrame->BeforeExecute();
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
 
   if (Result)
   {
@@ -169,7 +169,7 @@ void __fastcall TCopyParamPresetDialog::FormShow(TObject * /*Sender*/)
 void __fastcall TCopyParamPresetDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     UnicodeString Description = DescriptionEdit->Text;
     TCopyParamList::ValidateName(Description);

+ 4 - 8
source/forms/CopyParamPreset.dfm

@@ -9,11 +9,7 @@ object CopyParamPresetDialog: TCopyParamPresetDialog
   ClientHeight = 509
   ClientWidth = 675
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnCloseQuery = FormCloseQuery
@@ -26,7 +22,7 @@ object CopyParamPresetDialog: TCopyParamPresetDialog
   object Label1: TLabel
     Left = 10
     Top = 13
-    Width = 87
+    Width = 90
     Height = 13
     Caption = 'Preset &description:'
     FocusControl = DescriptionEdit
@@ -100,7 +96,7 @@ object CopyParamPresetDialog: TCopyParamPresetDialog
     object Label4: TLabel
       Left = 16
       Top = 116
-      Width = 111
+      Width = 114
       Height = 13
       Caption = 'Remote director&y mask:'
       FocusControl = RemoteDirectoryEdit
@@ -108,7 +104,7 @@ object CopyParamPresetDialog: TCopyParamPresetDialog
     object Label5: TLabel
       Left = 16
       Top = 164
-      Width = 100
+      Width = 101
       Height = 13
       Caption = '&Local directory mask:'
       FocusControl = LocalDirectoryEdit

+ 4 - 4
source/forms/CopyParams.dfm

@@ -282,7 +282,7 @@ object CopyParamsFrame: TCopyParamsFrame
     object IncludeFileMaskCombo: THistoryComboBox
       Left = 15
       Top = 36
-      Width = 302
+      Width = 294
       Height = 21
       AutoComplete = False
       Anchors = [akLeft, akTop, akRight]
@@ -292,9 +292,9 @@ object CopyParamsFrame: TCopyParamsFrame
       OnExit = ValidateMaskComboExit
     end
     object IncludeFileMaskButton: TButton
-      Left = 323
+      Left = 315
       Top = 33
-      Width = 72
+      Width = 80
       Height = 25
       Caption = '&Edit...'
       TabOrder = 1
@@ -312,7 +312,7 @@ object CopyParamsFrame: TCopyParamsFrame
       OnClick = ControlChange
     end
     object IncludeFileMaskHintText: TStaticText
-      Left = 263
+      Left = 255
       Top = 58
       Width = 54
       Height = 17

+ 2 - 2
source/forms/CreateDirectory.cpp

@@ -71,7 +71,7 @@ bool __fastcall TCreateDirectoryDialog::Execute(UnicodeString & Directory,
     RightsFrame->Rights = Properties->Rights;
   }
 
-  bool Result = (ShowModal() != mrCancel);
+  bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
     Directory = DirectoryEdit->Text;
@@ -112,7 +112,7 @@ void __fastcall TCreateDirectoryDialog::HelpButtonClick(TObject * /*Sender*/)
 void __fastcall TCreateDirectoryDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     ExitActiveControl(this);
   }

+ 13 - 10
source/forms/Custom.cpp

@@ -11,6 +11,7 @@
 #include <TextsWin.h>
 #include <HelpWin.h>
 #include <CoreMain.h>
+#include <PasTools.hpp>
 
 #include "Custom.h"
 //---------------------------------------------------------------------
@@ -24,7 +25,7 @@ __fastcall TCustomDialog::TCustomDialog(UnicodeString AHelpKeyword)
 {
   UseSystemSettings(this);
 
-  FPos = 8;
+  FPos = ScaleByTextHeight(this, 8);
 
   HelpKeyword = AHelpKeyword;
 
@@ -47,7 +48,7 @@ __fastcall TCustomDialog::TCustomDialog(UnicodeString AHelpKeyword)
 bool __fastcall TCustomDialog::Execute()
 {
   Changed();
-  return (ShowModal() == mrOk);
+  return (ShowModal() == DefaultResult(this));
 }
 //---------------------------------------------------------------------
 void __fastcall TCustomDialog::DoChange(bool & /*CanSubmit*/)
@@ -88,7 +89,7 @@ void __fastcall TCustomDialog::DoValidate()
 //---------------------------------------------------------------------------
 bool __fastcall TCustomDialog::CloseQuery()
 {
-  if (ModalResult == mrOk)
+  if (ModalResult == DefaultResult(this))
   {
     DoValidate();
   }
@@ -112,17 +113,17 @@ void __fastcall TCustomDialog::AddEditLikeControl(TWinControl * Edit, TLabel * L
 {
   int PrePos = FPos;
   Label->Parent = this;
-  Label->Left = 8;
+  Label->Left = ScaleByTextHeight(this, 8);
   Label->Top = FPos;
-  FPos += 16;
+  FPos += Label->Height + ScaleByTextHeight(this, 4);
 
   Edit->Parent = this;
-  Edit->Left = 8;
+  Edit->Left = ScaleByTextHeight(this, 8);
   Edit->Top = FPos;
   Edit->Width = ClientWidth - (Edit->Left * 2);
   // this updates Height property to real value
   Edit->HandleNeeded();
-  FPos += Edit->Height + 8;
+  FPos += Edit->Height + ScaleByTextHeight(this, 8);
 
   if (Label->FocusControl == NULL)
   {
@@ -164,12 +165,14 @@ void __fastcall TCustomDialog::AddButtonControl(TButtonControl * Control)
 {
   int PrePos = FPos;
   Control->Parent = this;
-  Control->Left = 14;
+  Control->Left = ScaleByTextHeight(this, 14);
   Control->Top = FPos;
-  Control->Width = ClientWidth - Control->Left - 8;
+  Control->Width = ClientWidth - Control->Left - ScaleByTextHeight(this, 8);
   // this updates Height property to real value
   Control->HandleNeeded();
-  FPos += Control->Height + 8;
+  // buttons do not scale with text on their own
+  Control->Height = ScaleByTextHeight(Control, Control->Height);
+  FPos += Control->Height + ScaleByTextHeight(this, 8);
 
   ClientHeight = ClientHeight + (FPos - PrePos);
 

+ 2 - 2
source/forms/CustomCommand.cpp

@@ -182,7 +182,7 @@ bool __fastcall TCustomCommandDialog::Execute(TCustomCommandType & Command)
     SetShortCutCombo(ShortCutCombo, Command.ShortCut);
   }
 
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
     GetCommand(Command);
@@ -196,7 +196,7 @@ bool __fastcall TCustomCommandDialog::Execute(TCustomCommandType & Command)
 void __fastcall TCustomCommandDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     if ((FMode == ccmAdd) || (FMode == ccmEdit))
     {

+ 4 - 8
source/forms/CustomCommand.dfm

@@ -9,11 +9,7 @@ object CustomCommandDialog: TCustomCommandDialog
   ClientHeight = 282
   ClientWidth = 396
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnCloseQuery = FormCloseQuery
@@ -36,7 +32,7 @@ object CustomCommandDialog: TCustomCommandDialog
     object DescriptionLabel: TLabel
       Left = 11
       Top = 16
-      Width = 56
+      Width = 57
       Height = 13
       Anchors = [akLeft, akTop, akRight]
       Caption = '&Description:'
@@ -45,7 +41,7 @@ object CustomCommandDialog: TCustomCommandDialog
     object Label1: TLabel
       Left = 11
       Top = 64
-      Width = 87
+      Width = 88
       Height = 13
       Anchors = [akLeft, akTop, akRight]
       Caption = '&Custom command:'
@@ -54,7 +50,7 @@ object CustomCommandDialog: TCustomCommandDialog
     object ShortCutLabel: TLabel
       Left = 16
       Top = 205
-      Width = 89
+      Width = 93
       Height = 13
       Caption = '&Keyboard shortcut:'
       FocusControl = ShortCutCombo

+ 167 - 62
source/forms/CustomScpExplorer.cpp

@@ -134,6 +134,12 @@ public:
   }
 };
 //---------------------------------------------------------------------------
+class TTerminalNoteData : public TObject
+{
+public:
+  TTerminal * Terminal;
+};
+//---------------------------------------------------------------------------
 __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
     FFormRestored(false),
     TForm(Owner)
@@ -242,8 +248,13 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   assert(ColorPalette != NULL);
   ColorPalette->OnChange = NonVisualDataModule->SessionColorPaletteChange;
 
-  RemoteDirView->Font = Screen->IconFont;
-  QueueView3->Font = Screen->IconFont;
+  UseDesktopFont(SessionsPageControl);
+  SessionsPageControl->Height =SessionsPageControl->GetTabsHeight();
+  UseDesktopFont(RemoteDirView);
+  UseDesktopFont(RemoteDriveView);
+  UseDesktopFont(QueueView3);
+  UseDesktopFont(QueueLabel);
+  UseDesktopFont(RemoteStatusBar);
 
   reinterpret_cast<TLabel*>(QueueSplitter)->OnDblClick = QueueSplitterDblClick;
 
@@ -942,7 +953,7 @@ bool __fastcall TCustomScpExplorerForm::CopyParamDialog(
           if (WinConfiguration->DDTransferConfirmation == asAuto)
           {
             PopupTrayBalloon(NULL, LoadStr(DD_TRANSFER_CONFIRM_OFF), qtInformation,
-              NULL, 0, EnableDDTransferConfirmation);
+              NULL, 0, EnableDDTransferConfirmation, NULL);
           }
           WinConfiguration->DDTransferConfirmation = asOff;
         }
@@ -1063,7 +1074,7 @@ void __fastcall TCustomScpExplorerForm::RestoreParams()
 
   ConfigurationChanged();
 
-  QueuePanel->Height = WinConfiguration->QueueView.Height;
+  QueuePanel->Height = LoadDimension(WinConfiguration->QueueView.Height, WinConfiguration->QueueView.HeightPixelsPerInch);
   LoadListViewStr(QueueView3, WinConfiguration->QueueView.Layout);
   QueueDock->Visible = WinConfiguration->QueueView.ToolBar;
   QueueLabel->Visible = WinConfiguration->QueueView.Label;
@@ -1072,6 +1083,7 @@ void __fastcall TCustomScpExplorerForm::RestoreParams()
 void __fastcall TCustomScpExplorerForm::StoreParams()
 {
   WinConfiguration->QueueView.Height = QueuePanel->Height;
+  WinConfiguration->QueueView.HeightPixelsPerInch = Screen->PixelsPerInch;
   WinConfiguration->QueueView.Layout = GetListViewStr(QueueView3);
   WinConfiguration->QueueView.ToolBar = QueueDock->Visible;
   WinConfiguration->QueueView.Label = QueueLabel->Visible;
@@ -1721,7 +1733,7 @@ void __fastcall TCustomScpExplorerForm::BothCustomCommand(
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::CustomCommandMenu(
-  TObject * Sender, const TPoint & MousePos,
+  TObject * Sender, TRect Rect,
   TStrings * LocalFileList, TStrings * RemoteFileList)
 {
   FCustomCommandMenu->Items->Clear();
@@ -1734,7 +1746,7 @@ void __fastcall TCustomScpExplorerForm::CustomCommandMenu(
 
   NonVisualDataModule->CreateCustomCommandsMenu(FCustomCommandMenu->Items, false, false, true);
 
-  MenuPopup(FCustomCommandMenu, MousePos, dynamic_cast<TComponent *>(Sender));
+  MenuPopup(FCustomCommandMenu, Rect, dynamic_cast<TComponent *>(Sender));
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::TerminalCaptureLog(
@@ -3704,7 +3716,7 @@ void __fastcall TCustomScpExplorerForm::ApplicationTitleChanged()
   UpdateTrayIcon();
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::TrayIconClick(TObject * /*Sender*/)
+void __fastcall TCustomScpExplorerForm::RestoreApp()
 {
   // workaround
   // TApplication.WndProc sets TApplication.FAppIconic to false,
@@ -3714,16 +3726,20 @@ void __fastcall TCustomScpExplorerForm::TrayIconClick(TObject * /*Sender*/)
   // (after another application was previously active)
   if (::IsIconic(Handle))
   {
-    bool * AppIconic = reinterpret_cast<bool *>((reinterpret_cast<char *>(Application)) + 56);
-    if (!*AppIconic)
+    if (!IsAppIconic())
     {
-      *AppIconic = true;
+      SetAppIconic(true);
     }
   }
   Application->Restore();
   Application->BringToFront();
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::TrayIconClick(TObject * /*Sender*/)
+{
+  RestoreApp();
+}
+//---------------------------------------------------------------------------
 bool __fastcall TCustomScpExplorerForm::OpenInNewWindow()
 {
   return FLAGSET(GetAsyncKeyState(VK_SHIFT), 0x8000);
@@ -4005,7 +4021,7 @@ void __fastcall TCustomScpExplorerForm::SetComponentVisible(Byte Component, Bool
         }
       }
 
-      static int Reserve = 32;
+      int Reserve = ScaleByTextHeight(this, 32);
       // queue in explorer, trees in commander
       if (Control->Height > RemainingHeight - Reserve)
       {
@@ -4717,7 +4733,7 @@ void __fastcall TCustomScpExplorerForm::ToolbarGetBaseSize(
     if (DropDownItem != NULL)
     {
       ASize.x -= DropDownItem->EditWidth;
-      ASize.x += 50 /* minimal combo width */;
+      ASize.x += ScaleByTextHeight(this, 50) /* minimal combo width */;
     }
   }
 }
@@ -4790,18 +4806,18 @@ void __fastcall TCustomScpExplorerForm::DoOpenDirectoryDialog(
   if (Mode == odAddBookmark)
   {
     TMessageParams Params(mpNeverAskAgainCheck);
-    Params.NewerAskAgainTitle = LoadStr(ADD_BOOKMARK_SHARED);
-    Params.NewerAskAgainCheckedInitially = WinConfiguration->UseSharedBookmarks;
+    Params.NeverAskAgainTitle = LoadStr(ADD_BOOKMARK_SHARED);
+    Params.NeverAskAgainCheckedInitially = WinConfiguration->UseSharedBookmarks;
 
     unsigned int Answer =
       MessageDialog(FMTLOAD(ADD_BOOKMARK_CONFIRM, (DirView(Side)->PathName)),
-        qtConfirmation, qaYes | qaNo, HELP_ADD_BOOKMARK_CONFIRM, &Params);
+        qtConfirmation, qaOK | qaCancel, HELP_ADD_BOOKMARK_CONFIRM, &Params);
     if (Answer == qaNeverAskAgain)
     {
       Continue = true;
       WinConfiguration->UseSharedBookmarks = true;
     }
-    else if (Answer == qaYes)
+    else if (Answer == qaOK)
     {
       Continue = true;
       WinConfiguration->UseSharedBookmarks = false;
@@ -5104,7 +5120,7 @@ void __fastcall TCustomScpExplorerForm::TerminalListChanged(TObject * /*Sender*/
     while (!ListChanged && (Index < TerminalList->Count))
     {
       ListChanged =
-        (SessionsPageControl->Pages[Index]->Tag != reinterpret_cast<int>(TerminalList->Objects[Index])) ||
+        (GetSessionTabTerminal(SessionsPageControl->Pages[Index]) != TerminalList->Objects[Index]) ||
         (SessionsPageControl->Pages[Index]->Caption != TerminalList->Strings[Index]);
       Index++;
     }
@@ -5161,12 +5177,17 @@ void __fastcall TCustomScpExplorerForm::UpdateNewSessionTab()
       UnicodeString();
 }
 //---------------------------------------------------------------------------
+TTerminal * __fastcall TCustomScpExplorerForm::GetSessionTabTerminal(TTabSheet * TabSheet)
+{
+  return reinterpret_cast<TTerminal *>(TabSheet->Tag);
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::UpdateSessionTab(TTabSheet * TabSheet)
 {
   if (ALWAYS_TRUE(TabSheet != NULL))
   {
     TManagedTerminal * ManagedTerminal =
-      dynamic_cast<TManagedTerminal *>(reinterpret_cast<TTerminal *>(TabSheet->Tag));
+      dynamic_cast<TManagedTerminal *>(GetSessionTabTerminal(TabSheet));
     if (ALWAYS_TRUE(ManagedTerminal != NULL))
     {
       TColor Color =
@@ -5184,11 +5205,12 @@ void __fastcall TCustomScpExplorerForm::UpdateSessionTab(TTabSheet * TabSheet)
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::SessionsPageControlChange(TObject * /*Sender*/)
+bool __fastcall TCustomScpExplorerForm::SessionTabSwitched()
 {
   assert(SessionsPageControl->ActivePage != NULL);
-  TTerminal * Terminal = reinterpret_cast<TTerminal *>(SessionsPageControl->ActivePage->Tag);
-  if (Terminal != NULL)
+  TTerminal * Terminal = GetSessionTabTerminal(SessionsPageControl->ActivePage);
+  bool Result = (Terminal != NULL);
+  if (Result)
   {
     TTerminalManager::Instance()->ActiveTerminal = Terminal;
   }
@@ -5205,6 +5227,12 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlChange(TObject * /*Se
 
     FSessionsPageControlNewSessionTime = Now();
   }
+  return Result;
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::SessionsPageControlChange(TObject * /*Sender*/)
+{
+  SessionTabSwitched();
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::TransferListChange(TObject * Sender)
@@ -5263,7 +5291,7 @@ void __fastcall TCustomScpExplorerForm::UpdateTransferLabel()
         GUIConfiguration->CopyParamPreset[Name].
           GetInfoStr(L"; ",
             FLAGMASK(Terminal != NULL, Terminal->UsableCopyParamAttrs(0).General));
-      int MaxWidth = TransferList->MinWidth - (2 * TransferLabel->Margin) - 10;
+      int MaxWidth = TransferList->MinWidth - (2 * TransferLabel->Margin) - ScaleByTextHeight(this, 10);
       if (Canvas->TextExtent(InfoStr).cx > MaxWidth)
       {
         UnicodeString Ellipsis = L"...";
@@ -5352,6 +5380,27 @@ void __fastcall TCustomScpExplorerForm::WMSysCommand(TMessage & Message)
   TForm::Dispatch(&Message);
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::WMQueryEndSession(TMessage & Message)
+{
+  // We were actually never able to make ENDSESSION_CRITICAL happen.
+  // Also there no point returning TRUE as we are not able to
+  // handle the abrupt termination caused by subsequent WM_ENDSESSION cleanly.
+  // Hence the process termination might be safer :)
+  if ((Message.LParam != ENDSESSION_CRITICAL) &&
+      (!FQueue->IsEmpty || (FProgressForm != NULL)))
+  {
+    Message.Result = FALSE;
+  }
+  else
+  {
+    Message.Result = TRUE;
+  }
+  // Do not call default handling as that triggers OnCloseQuery,
+  // where our implementation will popup configuration dialogs, what we do not want,
+  // as per Vista guidelines:
+  // msdn.microsoft.com/en-us/library/ms700677.aspx
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::SysResizing(unsigned int /*Cmd*/)
 {
 }
@@ -5378,7 +5427,7 @@ void __fastcall TCustomScpExplorerForm::DoShow()
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::PopupTrayBalloon(TTerminal * Terminal,
   const UnicodeString & Str, TQueryType Type, Exception * E, unsigned int Seconds,
-  TNotifyEvent OnBalloonClick)
+  TNotifyEvent OnBalloonClick, TObject * UserData)
 {
   bool Do;
   UnicodeString Message;
@@ -5407,7 +5456,7 @@ void __fastcall TCustomScpExplorerForm::PopupTrayBalloon(TTerminal * Terminal,
     {
       Seconds = WinConfiguration->NotificationsTimeout;
     }
-    FTrayIcon->PopupBalloon(Title, Message, Type, Seconds * MSecsPerSec, OnBalloonClick);
+    FTrayIcon->PopupBalloon(Title, Message, Type, Seconds * MSecsPerSec, OnBalloonClick, UserData);
   }
 }
 //---------------------------------------------------------------------------
@@ -5490,7 +5539,7 @@ void __fastcall TCustomScpExplorerForm::TerminalReady()
 void __fastcall TCustomScpExplorerForm::InactiveTerminalException(
   TTerminal * Terminal, Exception * E)
 {
-  Notify(Terminal, L"", qtError, false, NULL, E);
+  Notify(Terminal, L"", qtError, false, NULL, NULL, E);
 
   if (!Terminal->Active)
   {
@@ -5504,7 +5553,7 @@ void __fastcall TCustomScpExplorerForm::InactiveTerminalException(
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::Notify(TTerminal * Terminal,
   UnicodeString Message, TQueryType Type,
-  bool Important, TNotifyEvent OnClick, Exception * E)
+  bool Important, TNotifyEvent OnClick, TObject * UserData, Exception * E)
 {
   if ((E == NULL) ||
       ExceptionMessage(E, Message))
@@ -5522,16 +5571,33 @@ void __fastcall TCustomScpExplorerForm::Notify(TTerminal * Terminal,
         (TTerminalManager::Instance()->TerminalTitle(Terminal), NoteMessage));
     }
 
-    if (WinConfiguration->BalloonNotifications &&
-        ::TTrayIcon::SupportsBalloons())
+    if (WinConfiguration->BalloonNotifications)
     {
       AddNote(NoteMessage);
-      PopupTrayBalloon(Terminal, Message, Type, NULL, Seconds);
+      PopupTrayBalloon(Terminal, Message, Type, NULL, Seconds, OnClick, UserData);
     }
     else
     {
       FlashOnBackground();
-      PostNote(NoteMessage, Seconds, OnClick, NULL);
+      PostNote(NoteMessage, Seconds, OnClick, UserData);
+    }
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::QueueEmptyNoteClicked(TObject * Sender)
+{
+  RestoreApp();
+
+  TTerminalNoteData * TerminalNoteData = dynamic_cast<TTerminalNoteData *>(Sender);
+  if (ALWAYS_TRUE(TerminalNoteData != NULL) &&
+      !NonVisualDataModule->Busy)
+  {
+    TTerminal * Terminal = TerminalNoteData->Terminal;
+    TTerminalManager::Instance()->ActiveTerminal = Terminal;
+    if (!ComponentVisible[fcQueueView])
+    {
+      ToggleQueueVisibility();
+      GoToQueue();
     }
   }
 }
@@ -5540,12 +5606,18 @@ void __fastcall TCustomScpExplorerForm::QueueEvent(TTerminal * ATerminal,
   TTerminalQueue * /*Queue*/, TQueueEvent Event)
 {
   UnicodeString Message;
+  TNotifyEvent OnClick = NULL;
+  TObject * UserData = NULL;
   switch (Event)
   {
     case qeEmpty:
       if ((ATerminal != Terminal) || !ComponentVisible[fcQueueView])
       {
         Message = LoadStr(BALLOON_QUEUE_EMPTY);
+        OnClick = QueueEmptyNoteClicked;
+        TTerminalNoteData * TerminalNoteData = new TTerminalNoteData();
+        TerminalNoteData->Terminal = ATerminal;
+        UserData = TerminalNoteData;
       }
       break;
 
@@ -5563,7 +5635,7 @@ void __fastcall TCustomScpExplorerForm::QueueEvent(TTerminal * ATerminal,
 
   if (!Message.IsEmpty())
   {
-    Notify(ATerminal, Message, qtInformation);
+    Notify(ATerminal, Message, qtInformation, false, OnClick, UserData);
   }
 }
 //---------------------------------------------------------------------------
@@ -5847,7 +5919,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDTargetDrop()
       TPoint Point = SessionsPageControl->ScreenToClient(Mouse->CursorPos);
       int Index = SessionsPageControl->IndexOfTabAt(Point.X, Point.Y);
       // do not allow dropping on the "+" tab
-      TargetTerminal = reinterpret_cast<TTerminal *>(SessionsPageControl->Pages[Index]->Tag);
+      TargetTerminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]);
       if (TargetTerminal != NULL)
       {
         if ((FLastDropEffect == DROPEFFECT_MOVE) &&
@@ -6108,13 +6180,20 @@ bool __fastcall TCustomScpExplorerForm::AllowQueueOperation(
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::GoToQueue()
+{
+  if (ALWAYS_TRUE(QueueView3->Visible))
+  {
+    QueueView3->SetFocus();
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::ExecuteQueueOperation(
   TQueueOperation Operation, void * Param)
 {
   if (Operation == qoGoTo)
   {
-    assert(QueueView3->Visible);
-    QueueView3->SetFocus();
+    GoToQueue();
   }
   else if (Operation == qoPreferences)
   {
@@ -6705,7 +6784,12 @@ void __fastcall TCustomScpExplorerForm::UpdatesChecked()
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::UpdatesNoteClicked(TObject * /*Sender*/)
 {
-  CheckForUpdates(true);
+  RestoreApp();
+
+  if (!NonVisualDataModule->Busy)
+  {
+    CheckForUpdates(true);
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::GetTransferPresetAutoSelectData(
@@ -6831,9 +6915,16 @@ void __fastcall TCustomScpExplorerForm::TransferPresetNoteMessage(
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::TransferPresetNoteClicked(TObject * /*Sender*/)
+void __fastcall TCustomScpExplorerForm::TransferPresetNoteClicked(TObject * Sender)
 {
-  TransferPresetNoteMessage(dynamic_cast<TTransferPresetNoteData *>(FNoteData), false);
+  // as of now useless, as this is used for notes only, never for balloons, ...
+  RestoreApp();
+
+  // .. and we should never be busy here
+  if (ALWAYS_TRUE(!NonVisualDataModule->Busy))
+  {
+    TransferPresetNoteMessage(NOT_NULL(dynamic_cast<TTransferPresetNoteData *>(Sender)), false);
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::PreferencesDialog(
@@ -6952,6 +7043,10 @@ void __fastcall TCustomScpExplorerForm::Dispatch(void * Message)
       WMSysCommand(*M);
       break;
 
+    case WM_QUERYENDSESSION:
+      WMQueryEndSession(*M);
+      break;
+
     case WM_COMPONENT_HIDE:
       {
         Byte Component = static_cast<Byte>(M->WParam);
@@ -7076,18 +7171,19 @@ void __fastcall TCustomScpExplorerForm::SessionColorPick()
   }
 }
 //---------------------------------------------------------------------------
-bool __fastcall TCustomScpExplorerForm::CancelNote()
+bool __fastcall TCustomScpExplorerForm::CancelNote(bool Force)
 {
   bool Result = FNoteTimer->Enabled;
   if (Result)
   {
     // cannot cancel note too early
-    if (Now() - FNoteShown >
-          EncodeTimeVerbose(0, 0, (unsigned short)(WinConfiguration->NotificationsStickTime), 0))
+    bool NotEarly =
+      (Now() - FNoteShown >
+          EncodeTimeVerbose(0, 0, (unsigned short)(WinConfiguration->NotificationsStickTime), 0));
+    if (Force || NotEarly)
     {
       FNoteTimer->Enabled = false;
       FNote = "";
-      // beware that OnNoteClick may being executed
       SAFE_DESTROY(FNoteData);
       FOnNoteClick = NULL;
       FNoteHints = FNotes->Text;
@@ -7101,7 +7197,7 @@ bool __fastcall TCustomScpExplorerForm::CancelNote()
 void __fastcall TCustomScpExplorerForm::NoteTimer(TObject * /*Sender*/)
 {
   assert(FNoteTimer->Enabled);
-  CancelNote();
+  CancelNote(true);
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::AddNote(UnicodeString Note, bool UpdateNow)
@@ -7139,7 +7235,6 @@ void __fastcall TCustomScpExplorerForm::PostNote(UnicodeString Note,
   FNoteHints = FNotes->Text;
   FNoteHints.Delete(FNoteHints.Length() - 1, 2);
   FNote = Note;
-  // beware that OnNoteClick may being executed
   SAFE_DESTROY(FNoteData);
   FNoteData = NoteData;
   FOnNoteClick = OnNoteClick;
@@ -7201,7 +7296,14 @@ void __fastcall TCustomScpExplorerForm::StatusBarPanelDblClick(
   {
     if (FOnNoteClick != NULL)
     {
-      FOnNoteClick(NULL);
+      // prevent the user data from being freed by possible call
+      // to CancelNote or PostNote during call to OnNoteClick
+      std::auto_ptr<TObject> NoteData(FNoteData);
+      TNotifyEvent OnNoteClick = FOnNoteClick;
+      FNoteData = NULL;
+      // need to cancel the note as we are going to delete its user data
+      CancelNote(true);
+      OnNoteClick(NoteData.get());
     }
   }
   else
@@ -7434,19 +7536,22 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlMouseDown(
     if (Button == mbRight)
     {
       SessionsPageControl->ActivePageIndex = Index;
-      SessionsPageControlChange(NULL);
-
-      // copied from TControl.WMContextMenu
-      SendCancelMode(SessionsPageControl);
+      // do not popup menu when we click "New session" tab
+      // (it would popup only after login dialog > auth dialog, what is strange)
+      if (SessionTabSwitched())
+      {
+        // copied from TControl.WMContextMenu
+        SendCancelMode(SessionsPageControl);
 
-      // explicit popup instead of using PopupMenu property
-      // to avoid menu to popup somewhere within SessionsPageControlChange above,
-      // while connecting yet not-connected session and hence
-      // allowing an access to commands over not-completelly connected session
-      TPoint Point = SessionsPageControl->ClientToScreen(TPoint(X, Y));
-      TPopupMenu * PopupMenu = NonVisualDataModule->SessionsPopup;
-      PopupMenu->PopupComponent = SessionsPageControl;
-      PopupMenu->Popup(Point.x, Point.y);
+        // explicit popup instead of using PopupMenu property
+        // to avoid menu to popup somewhere within SessionTabSwitched above,
+        // while connecting yet not-connected session and hence
+        // allowing an access to commands over not-completelly connected session
+        TPoint Point = SessionsPageControl->ClientToScreen(TPoint(X, Y));
+        TPopupMenu * PopupMenu = NonVisualDataModule->SessionsPopup;
+        PopupMenu->PopupComponent = SessionsPageControl;
+        PopupMenu->Popup(Point.x, Point.y);
+      }
     }
     else if (Button == mbLeft)
     {
@@ -7462,7 +7567,7 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlMouseDown(
         // starts, prevent that
         if (MilliSecondsBetween(Now(), FSessionsPageControlNewSessionTime) > 500)
         {
-          TTerminal * Terminal = reinterpret_cast<TTerminal *>(SessionsPageControl->Pages[Index]->Tag);
+          TTerminal * Terminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]);
           if (Terminal != NULL)
           {
             SessionsPageControl->BeginDrag(false);
@@ -7478,7 +7583,7 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlDragDrop(
 {
   int Index = SessionsPageControl->IndexOfTabAt(X, Y);
   // do not allow dropping on the "+" tab
-  TTerminal * TargetTerminal = reinterpret_cast<TTerminal *>(SessionsPageControl->Pages[Index]->Tag);
+  TTerminal * TargetTerminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]);
   if ((TargetTerminal != NULL) &&
       (SessionsPageControl->ActivePage->PageIndex != Index))
   {
@@ -7486,7 +7591,7 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlDragDrop(
     // this is almost redundant as we would recreate tabs in TerminalListChanged,
     // but we want to actually prevent that to avoid flicker
     SessionsPageControl->ActivePage->PageIndex = Index;
-    TTerminal * Terminal = reinterpret_cast<TTerminal *>(SessionsPageControl->ActivePage->Tag);
+    TTerminal * Terminal = GetSessionTabTerminal(SessionsPageControl->ActivePage);
     TTerminalManager::Instance()->Move(Terminal, TargetTerminal);
   }
 }
@@ -7499,7 +7604,7 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlDragOver(
   if (Accept)
   {
     int Index = SessionsPageControl->IndexOfTabAt(X, Y);
-    TTerminal * Terminal = reinterpret_cast<TTerminal *>(SessionsPageControl->Pages[Index]->Tag);
+    TTerminal * Terminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]);
     // do not allow dragging to the "+" tab
     Accept = (Terminal != NULL);
   }
@@ -7515,7 +7620,7 @@ void __fastcall TCustomScpExplorerForm::SessionsDDDragOver(int /*KeyState*/,
   }
   else
   {
-    TTerminal * TargetTerminal = reinterpret_cast<TTerminal *>(SessionsPageControl->Pages[Index]->Tag);
+    TTerminal * TargetTerminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]);
     // do not allow dropping on the "+" tab
     if (TargetTerminal == NULL)
     {
@@ -7531,7 +7636,7 @@ void __fastcall TCustomScpExplorerForm::SessionsDDProcessDropped(
   {
     int Index = SessionsPageControl->IndexOfTabAt(Point.X, Point.Y);
     // do not allow dropping on the "+" tab
-    TTerminal * TargetTerminal = reinterpret_cast<TTerminal *>(SessionsPageControl->Pages[Index]->Tag);
+    TTerminal * TargetTerminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]);
     if (TargetTerminal != NULL)
     {
       assert(!IsFileControl(DropSourceControl, osRemote));

+ 6 - 6
source/forms/CustomScpExplorer.dfm

@@ -20,7 +20,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
     Top = 289
     Width = 620
     Height = 3
-    Cursor = crVSplit
+    Cursor = crSizeNS
     Hint = 'Drag to resize queue list. Double click to hide queue list.'
     Align = alBottom
     AutoSnap = False
@@ -49,6 +49,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
       Left = 169
       Top = 0
       Height = 240
+      Cursor = crSizeWE
       AutoSnap = False
       Color = clBtnFace
       MinSize = 70
@@ -106,7 +107,6 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
       OnHistoryChange = DirViewHistoryChange
       OnDisplayProperties = RemoteDirViewDisplayProperties
       OnRead = RemoteDirViewRead
-      Items.ItemData = {}
     end
     object RemoteDriveView: TUnixDriveView
       Left = 0
@@ -149,7 +149,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
       Left = 0
       Top = 0
       Width = 620
-      Height = 15
+      Height = 19
       IndentVertical = 3
       AutoSizeVertical = True
       AutoSize = False
@@ -157,9 +157,9 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
     end
     object QueueView3: TListView
       Left = 0
-      Top = 41
+      Top = 45
       Width = 620
-      Height = 99
+      Height = 95
       Align = alClient
       Columns = <
         item
@@ -217,7 +217,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
     object QueueDock: TTBXDock
       Tag = 1
       Left = 0
-      Top = 15
+      Top = 19
       Width = 620
       Height = 26
       AllowDrag = False

+ 10 - 4
source/forms/CustomScpExplorer.h

@@ -339,6 +339,7 @@ protected:
   inline void __fastcall CMAppSysCommand(TMessage & Message);
   inline void __fastcall WMAppCommand(TMessage & Message);
   inline void __fastcall WMSysCommand(TMessage & Message);
+  void __fastcall WMQueryEndSession(TMessage & Message);
   virtual void __fastcall SysResizing(unsigned int Cmd);
   DYNAMIC void __fastcall DoShow();
   TStrings * __fastcall CreateVisitedDirectories(TOperationSide Side);
@@ -432,7 +433,7 @@ protected:
   void __fastcall TransferPresetAutoSelect();
   virtual void __fastcall GetTransferPresetAutoSelectData(TCopyParamRuleData & Data);
   inline bool __fastcall CustomCommandRemoteAllowed();
-  void __fastcall CustomCommandMenu(TObject * Sender, const TPoint & MousePos,
+  void __fastcall CustomCommandMenu(TObject * Sender, TRect Rect,
     TStrings * LocalFileList, TStrings * RemoteFileList);
   void __fastcall LoadToolbarsLayoutStr(UnicodeString LayoutStr);
   UnicodeString __fastcall GetToolbarsLayoutStr();
@@ -451,7 +452,7 @@ protected:
   void __fastcall AddNote(UnicodeString Note, bool UpdateNow = true);
   void __fastcall PostNote(UnicodeString Note, unsigned int Seconds,
     TNotifyEvent OnNoteClick, TObject * NoteData);
-  bool __fastcall CancelNote();
+  bool __fastcall CancelNote(bool Force);
   void __fastcall UpdatesChecked();
   void __fastcall UpdatesNoteClicked(TObject * Sender);
   void __fastcall TransferPresetNoteClicked(TObject * Sender);
@@ -461,7 +462,7 @@ protected:
   void __fastcall TrayIconClick(TObject * Sender);
   void __fastcall Notify(TTerminal * Terminal, UnicodeString Message,
     TQueryType Type, bool Important = false, TNotifyEvent OnClick = NULL,
-    Exception * E = NULL);
+    TObject * UserData = NULL, Exception * E = NULL);
   virtual void __fastcall UpdateSessionData(TSessionData * Data);
   virtual void __fastcall UpdateRemotePathComboBox(
     TTBXComboBoxItem * RemotePathComboBox, bool TextOnly);
@@ -495,6 +496,10 @@ protected:
   bool __fastcall CommandLineFromAnotherInstance(const UnicodeString & CommandLine);
   void __fastcall SetQueueProgress();
   void __fastcall UpdateQueueLabel();
+  TTerminal * __fastcall GetSessionTabTerminal(TTabSheet * TabSheet);
+  bool __fastcall SessionTabSwitched();
+  void __fastcall RestoreApp();
+  void __fastcall GoToQueue();
 
 public:
   virtual __fastcall ~TCustomScpExplorerForm();
@@ -569,6 +574,7 @@ public:
   void __fastcall InactiveTerminalException(TTerminal * Terminal, Exception * E);
   void __fastcall TerminalReady();
   void __fastcall QueueEvent(TTerminal * Terminal, TTerminalQueue * Queue, TQueueEvent Event);
+  void __fastcall QueueEmptyNoteClicked(TObject * Sender);
   bool __fastcall DoSynchronizeDirectories(UnicodeString & LocalDirectory,
     UnicodeString & RemoteDirectory, bool UseDefaults);
   bool __fastcall DoFullSynchronizeDirectories(UnicodeString & LocalDirectory,
@@ -591,7 +597,7 @@ public:
   void __fastcall ToggleAutoReadDirectoryAfterOp();
   void __fastcall PopupTrayBalloon(TTerminal * Terminal, const UnicodeString & Str,
     TQueryType Type, Exception * E = NULL, unsigned int Seconds = 0,
-    TNotifyEvent OnBalloonClick = NULL);
+    TNotifyEvent OnBalloonClick = NULL, TObject * UserData = NULL);
   void __fastcall RemoteFindFiles();
   virtual void __fastcall HistoryGo(TOperationSide Side, int Index);
   void __fastcall UpdateTaskbarList(ITaskbarList3 * TaskbarList);

+ 3 - 3
source/forms/EditMask.cpp

@@ -44,7 +44,7 @@ __fastcall TEditMaskDialog::TEditMaskDialog(TComponent* Owner)
 void __fastcall TEditMaskDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     ExitActiveControl(this);
   }
@@ -53,7 +53,7 @@ void __fastcall TEditMaskDialog::FormCloseQuery(TObject * /*Sender*/,
 bool __fastcall TEditMaskDialog::Execute(TFileMasks & Mask)
 {
   LoadFileMasks(Mask);
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
     SaveFileMasks(Mask);
@@ -155,7 +155,7 @@ void __fastcall TEditMaskDialog::FormKeyDown(
   }
   else if ((Key == VK_RETURN) && Shift.Contains(ssCtrl))
   {
-    ModalResult = mrOk;
+    ModalResult = DefaultResult(this);
     Key = 0;
   }
 }

+ 8 - 7
source/forms/Editor.cpp

@@ -65,7 +65,7 @@ public:
 
   bool __fastcall LoadFromStream(TStream * Stream, TEncoding * Encoding, bool & EncodingError);
 
-  void __fastcall SetFormat(UnicodeString FontName, int FontHeight,
+  void __fastcall SetFormat(UnicodeString FontName, int FontSize,
     TFontCharset FontCharset, TFontStyles FontStyles, unsigned int TabSize,
     bool AWordWrap);
   void __fastcall ResetFormat();
@@ -109,7 +109,7 @@ __fastcall TRichEdit20::TRichEdit20(TComponent * AOwner) :
 {
 }
 //---------------------------------------------------------------------------
-void __fastcall TRichEdit20::SetFormat(UnicodeString FontName, int FontHeight,
+void __fastcall TRichEdit20::SetFormat(UnicodeString FontName, int FontSize,
   TFontCharset FontCharset, TFontStyles FontStyles, unsigned int TabSize,
   bool AWordWrap)
 {
@@ -130,12 +130,12 @@ void __fastcall TRichEdit20::SetFormat(UnicodeString FontName, int FontHeight,
   // do not change, so avoid that if not necessary
   if (!FInitialized ||
       (Font->Name != FontName) ||
-      (Font->Height != FontHeight) ||
+      (Font->Size != FontSize) ||
       (Font->Charset != FontCharset) ||
       (Font->Style != FontStyles))
   {
     Font->Name = FontName;
-    Font->Height = FontHeight;
+    Font->Size = FontSize;
     Font->Charset = FontCharset;
     Font->Style = FontStyles;
     DefAttributes->Assign(Font);
@@ -599,6 +599,7 @@ __fastcall TEditorForm::TEditorForm(TComponent* Owner)
   InitCodePage();
 
   UseSystemSettings(this);
+  UseDesktopFont(StatusBar);
   SetFormIcons(this, L"Z_ICON_EDITOR_BIG", L"Z_ICON_EDITOR_SMALL");
 }
 //---------------------------------------------------------------------------
@@ -839,7 +840,7 @@ void __fastcall TEditorForm::ApplyConfiguration()
   bool PrevModified = EditorMemo->Modified;
   assert(Configuration);
   EditorMemo->SetFormat(WinConfiguration->Editor.FontName,
-    WinConfiguration->Editor.FontHeight, (TFontCharset)WinConfiguration->Editor.FontCharset,
+    WinConfiguration->Editor.FontSize, (TFontCharset)WinConfiguration->Editor.FontCharset,
     IntToFontStyles(WinConfiguration->Editor.FontStyle), WinConfiguration->Editor.TabSize,
     WinConfiguration->Editor.WordWrap);
   EditorMemo->Modified = PrevModified;
@@ -1231,10 +1232,10 @@ void __fastcall TEditorForm::PositionFindDialog(bool VerticalOnly)
   assert(FLastFindDialog);
   if (!VerticalOnly)
   {
-    FLastFindDialog->Left = Left + EditorMemo->Left + EditorMemo->Width / 2 - 100;
+    FLastFindDialog->Left = Left + EditorMemo->Left + EditorMemo->Width / 2 - ScaleByTextHeight(this, 100);
   }
   FLastFindDialog->Top = Top + EditorMemo->Top + (EditorMemo->Height / 4) +
-    (CursorInUpperPart() ? (EditorMemo->Height / 2) : 0) - 40;
+    (CursorInUpperPart() ? (EditorMemo->Height / 2) : 0) - ScaleByTextHeight(this, 40);
 }
 //---------------------------------------------------------------------------
 void __fastcall TEditorForm::StartFind(bool Find)

+ 1 - 5
source/forms/Editor.dfm

@@ -8,11 +8,7 @@ object EditorForm: TEditorForm
   ClientHeight = 381
   ClientWidth = 609
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   KeyPreview = True
   OldCreateOrder = False
   OnActivate = FormActivate

+ 2 - 2
source/forms/EditorPreferences.cpp

@@ -116,7 +116,7 @@ bool __fastcall TEditorPreferencesDialog::Execute(TEditorData * Editor, bool & R
   RememberCheck->Checked = Remember;
   UpdateControls();
 
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
 
   if (Result)
   {
@@ -200,7 +200,7 @@ void __fastcall TEditorPreferencesDialog::UpdateControls()
 void __fastcall TEditorPreferencesDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     ExitActiveControl(this);
   }

+ 2 - 6
source/forms/EditorPreferences.dfm

@@ -9,11 +9,7 @@ object EditorPreferencesDialog: TEditorPreferencesDialog
   ClientHeight = 359
   ClientWidth = 403
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnCloseQuery = FormCloseQuery
@@ -122,7 +118,7 @@ object EditorPreferencesDialog: TEditorPreferencesDialog
     object MaskLabel: TLabel
       Left = 11
       Top = 20
-      Width = 150
+      Width = 157
       Height = 13
       Caption = 'Use this editor for &following files:'
       FocusControl = MaskEdit

+ 4 - 1
source/forms/FileFind.cpp

@@ -56,6 +56,9 @@ __fastcall TFileFindDialog::TFileFindDialog(TComponent * Owner, TFindEvent OnFin
   FSystemImageList = SharedSystemImageList(false);
   FileView->SmallImages = FSystemImageList;
 
+  UseDesktopFont(FileView);
+  UseDesktopFont(StatusBar);
+
   SetGlobalMinimizeHandler(this, GlobalMinimize);
 }
 //---------------------------------------------------------------------------
@@ -137,7 +140,7 @@ bool __fastcall TFileFindDialog::Execute(UnicodeString Directory, UnicodeString
   MaskEdit->Items = WinConfiguration->History[L"Mask"];
   RemoteDirectoryEdit->Items = CustomWinConfiguration->History[L"RemoteDirectory"];
 
-  bool Result = (ShowModal() != mrCancel);
+  bool Result = (ShowModal() == FocusButton->ModalResult);
   if (Result)
   {
     Path = static_cast<TRemoteFile *>(FileView->ItemFocused->Data)->FullFileName;

+ 11 - 9
source/forms/FileFind.dfm

@@ -10,11 +10,7 @@ object FileFindDialog: TFileFindDialog
   Color = clBtnFace
   Constraints.MinHeight = 240
   Constraints.MinWidth = 350
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   Icon.Data = {
     0000010001001010000001002000680400001600000028000000100000002000
     0000010020000000000040040000000000000000000000000000000000000000
@@ -105,7 +101,7 @@ object FileFindDialog: TFileFindDialog
     object MaskEdit: THistoryComboBox
       Left = 11
       Top = 36
-      Width = 361
+      Width = 353
       Height = 21
       AutoComplete = False
       Anchors = [akLeft, akTop, akRight]
@@ -116,7 +112,7 @@ object FileFindDialog: TFileFindDialog
       OnExit = MaskEditExit
     end
     object MaskHintText: TStaticText
-      Left = 275
+      Left = 267
       Top = 59
       Width = 97
       Height = 17
@@ -128,9 +124,9 @@ object FileFindDialog: TFileFindDialog
       TabStop = True
     end
     object MaskButton: TButton
-      Left = 378
+      Left = 370
       Top = 33
-      Width = 72
+      Width = 80
       Height = 25
       Anchors = [akTop, akRight]
       Caption = '&Edit...'
@@ -210,10 +206,16 @@ object FileFindDialog: TFileFindDialog
     Top = 398
     Width = 562
     Height = 19
+    Font.Charset = DEFAULT_CHARSET
+    Font.Color = clBtnText
+    Font.Height = -12
+    Font.Name = 'Segoe UI'
+    Font.Style = []
     Panels = <>
     ParentShowHint = False
     ShowHint = True
     SimplePanel = True
+    UseSystemFont = False
   end
   object FocusButton: TButton
     Left = 476

+ 7 - 11
source/forms/FullSynchronize.cpp

@@ -163,7 +163,7 @@ bool __fastcall TFullSynchronizeDialog::Execute()
   FPreset = GUIConfiguration->CopyParamCurrent;
   LocalDirectoryEdit->Items = CustomWinConfiguration->History[L"LocalDirectory"];
   RemoteDirectoryEdit->Items = CustomWinConfiguration->History[L"RemoteDirectory"];
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
     LocalDirectoryEdit->SaveToHistory();
@@ -306,13 +306,13 @@ void __fastcall TFullSynchronizeDialog::SetOptions(int value)
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TFullSynchronizeDialog::CopyParamListPopup(TPoint P, int AdditionalOptions)
+void __fastcall TFullSynchronizeDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
 {
   // We pass in FCopyParams, although it may not be the exact copy param
   // that will be used (because of Preservetime). The reason is to
   // display checkbox next to user-selected preset
   ::CopyParamListPopup(
-    P, FPresetsMenu, FCopyParams, FPreset, CopyParamClick,
+    R, FPresetsMenu, FCopyParams, FPreset, CopyParamClick,
     cplCustomize | AdditionalOptions,
     ActualCopyParamAttrs());
 }
@@ -322,9 +322,7 @@ void __fastcall TFullSynchronizeDialog::TransferSettingsButtonClick(
 {
   if (FLAGCLEAR(FOptions, fsoDoNotUsePresets) && !SupportsSplitButton())
   {
-    CopyParamListPopup(
-      TransferSettingsButton->ClientToScreen(TPoint(0, TransferSettingsButton->Height)),
-      0);
+    CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);
   }
   else
   {
@@ -357,7 +355,7 @@ void __fastcall TFullSynchronizeDialog::FormShow(TObject * /*Sender*/)
 void __fastcall TFullSynchronizeDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & CanClose)
 {
-  if ((ModalResult != mrCancel) &&
+  if ((ModalResult == DefaultResult(this)) &&
       SaveSettings && (FOrigMode != Mode) && !FSaveMode)
   {
     switch (MessageDialog(LoadStr(SAVE_SYNCHRONIZE_MODE),
@@ -398,7 +396,7 @@ void __fastcall TFullSynchronizeDialog::CopyParamGroupContextPopup(
 {
   if (FLAGCLEAR(FOptions, fsoDoNotUsePresets))
   {
-    CopyParamListPopup(CopyParamGroup->ClientToScreen(MousePos), cplCustomizeDefault);
+    CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault);
     Handled = true;
   }
 }
@@ -423,8 +421,6 @@ void __fastcall TFullSynchronizeDialog::HelpButtonClick(TObject * /*Sender*/)
 //---------------------------------------------------------------------------
 void __fastcall TFullSynchronizeDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
 {
-  CopyParamListPopup(
-    TransferSettingsButton->ClientToScreen(TPoint(0, TransferSettingsButton->Height)),
-    cplCustomizeDefault);
+  CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
 }
 //---------------------------------------------------------------------------

+ 54 - 47
source/forms/FullSynchronize.dfm

@@ -7,55 +7,49 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
   BorderStyle = bsDialog
   Caption = 'Synchronize'
   ClientHeight = 429
-  ClientWidth = 433
+  ClientWidth = 481
   Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   Position = poOwnerFormCenter
   OnCloseQuery = FormCloseQuery
   OnShow = FormShow
   DesignSize = (
-    433
+    481
     429)
   PixelsPerInch = 96
   TextHeight = 13
   object DirectoriesGroup: TGroupBox
     Left = 8
     Top = 6
-    Width = 417
+    Width = 465
     Height = 119
     Anchors = [akLeft, akTop, akRight]
     Caption = 'Directories'
     TabOrder = 0
     DesignSize = (
-      417
+      465
       119)
     object LocalDirectoryLabel: TLabel
       Left = 11
       Top = 19
-      Width = 72
+      Width = 74
       Height = 13
-      Anchors = [akLeft, akTop, akRight]
       Caption = 'Lo&cal directory:'
       FocusControl = LocalDirectoryEdit
     end
     object RemoteDirectoryLabel: TLabel
       Left = 11
       Top = 68
-      Width = 83
+      Width = 87
       Height = 13
-      Anchors = [akLeft, akTop, akRight]
       Caption = 'R&emote directory:'
       FocusControl = RemoteDirectoryEdit
     end
     object RemoteDirectoryEdit: THistoryComboBox
       Left = 11
       Top = 84
-      Width = 395
+      Width = 443
       Height = 21
       AutoComplete = False
       Anchors = [akLeft, akTop, akRight]
@@ -67,7 +61,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     object LocalDirectoryEdit: THistoryComboBox
       Left = 11
       Top = 35
-      Width = 312
+      Width = 360
       Height = 21
       AutoComplete = False
       Anchors = [akLeft, akTop, akRight]
@@ -77,7 +71,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
       OnChange = ControlChange
     end
     object LocalDirectoryBrowseButton: TButton
-      Left = 330
+      Left = 378
       Top = 33
       Width = 75
       Height = 25
@@ -88,7 +82,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     end
   end
   object OkButton: TButton
-    Left = 185
+    Left = 233
     Top = 396
     Width = 75
     Height = 25
@@ -99,7 +93,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     TabOrder = 8
   end
   object CancelButton: TButton
-    Left = 267
+    Left = 315
     Top = 396
     Width = 75
     Height = 25
@@ -112,33 +106,38 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
   object OptionsGroup: TGroupBox
     Left = 8
     Top = 238
-    Width = 268
+    Width = 303
     Height = 73
     Caption = 'Synchronize options'
     TabOrder = 3
+    DesignSize = (
+      303
+      73)
     object SynchronizeDeleteCheck: TCheckBox
       Left = 11
       Top = 20
-      Width = 126
+      Width = 130
       Height = 17
       Caption = '&Delete files'
       TabOrder = 0
       OnClick = ControlChange
     end
     object SynchronizeSelectedOnlyCheck: TCheckBox
-      Left = 139
+      Left = 155
       Top = 44
-      Width = 123
+      Width = 141
       Height = 17
+      Anchors = [akLeft, akTop, akRight]
       Caption = 'Selected files o&nly'
       TabOrder = 3
       OnClick = ControlChange
     end
     object SynchronizeExistingOnlyCheck: TCheckBox
-      Left = 139
+      Left = 155
       Top = 20
-      Width = 123
+      Width = 141
       Height = 17
+      Anchors = [akLeft, akTop, akRight]
       Caption = '&Existing files only'
       TabOrder = 1
       OnClick = ControlChange
@@ -146,7 +145,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     object SynchronizePreviewChangesCheck: TCheckBox
       Left = 11
       Top = 44
-      Width = 126
+      Width = 130
       Height = 17
       Caption = 'Pre&view changes'
       TabOrder = 2
@@ -156,7 +155,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
   object TransferSettingsButton: TButton
     Left = 8
     Top = 396
-    Width = 129
+    Width = 161
     Height = 25
     Anchors = [akLeft, akBottom]
     Caption = 'Transfer settin&gs...'
@@ -167,7 +166,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
   object DirectionGroup: TGroupBox
     Left = 8
     Top = 130
-    Width = 417
+    Width = 465
     Height = 49
     Anchors = [akLeft, akTop, akRight]
     Caption = 'Direction/Target directory'
@@ -175,25 +174,25 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     object SynchronizeBothButton: TRadioButton
       Left = 11
       Top = 20
-      Width = 102
+      Width = 138
       Height = 17
       Caption = '&Both'
       TabOrder = 0
       OnClick = ControlChange
     end
     object SynchronizeRemoteButton: TRadioButton
-      Left = 139
+      Left = 155
       Top = 20
-      Width = 102
+      Width = 143
       Height = 17
       Caption = '&Remote'
       TabOrder = 1
       OnClick = ControlChange
     end
     object SynchronizeLocalButton: TRadioButton
-      Left = 272
+      Left = 304
       Top = 20
-      Width = 137
+      Width = 154
       Height = 17
       Caption = '&Local'
       TabOrder = 2
@@ -201,17 +200,22 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     end
   end
   object CompareCriterionsGroup: TGroupBox
-    Left = 285
+    Left = 317
     Top = 238
-    Width = 140
+    Width = 156
     Height = 73
+    Anchors = [akLeft, akTop, akRight]
     Caption = 'Comparison criteria'
     TabOrder = 4
+    DesignSize = (
+      156
+      73)
     object SynchronizeByTimeCheck: TCheckBox
       Left = 11
       Top = 20
-      Width = 121
+      Width = 138
       Height = 17
+      Anchors = [akLeft, akTop, akRight]
       Caption = 'M&odification time'
       TabOrder = 0
       OnClick = ControlChange
@@ -219,8 +223,9 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     object SynchronizeBySizeCheck: TCheckBox
       Left = 11
       Top = 44
-      Width = 121
+      Width = 138
       Height = 17
+      Anchors = [akLeft, akTop, akRight]
       Caption = 'File si&ze'
       TabOrder = 1
       OnClick = ControlChange
@@ -229,27 +234,29 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
   object SaveSettingsCheck: TCheckBox
     Left = 19
     Top = 317
-    Width = 246
+    Width = 454
     Height = 17
+    Anchors = [akLeft, akTop, akRight]
     Caption = 'Use &same options next time'
     TabOrder = 5
   end
   object CopyParamGroup: TGroupBox
     Left = 8
     Top = 338
-    Width = 417
+    Width = 465
     Height = 50
+    Anchors = [akLeft, akTop, akRight]
     Caption = 'Transfer settings'
     TabOrder = 6
     OnClick = CopyParamGroupClick
     OnContextPopup = CopyParamGroupContextPopup
     DesignSize = (
-      417
+      465
       50)
     object CopyParamLabel: TLabel
       Left = 7
       Top = 15
-      Width = 403
+      Width = 451
       Height = 26
       Anchors = [akLeft, akTop, akRight, akBottom]
       AutoSize = False
@@ -259,7 +266,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     end
   end
   object HelpButton: TButton
-    Left = 349
+    Left = 397
     Top = 396
     Width = 75
     Height = 25
@@ -271,7 +278,7 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
   object ModeGroup: TGroupBox
     Left = 8
     Top = 184
-    Width = 417
+    Width = 465
     Height = 49
     Anchors = [akLeft, akTop, akRight]
     Caption = 'Mode'
@@ -279,25 +286,25 @@ object FullSynchronizeDialog: TFullSynchronizeDialog
     object SynchronizeFilesButton: TRadioButton
       Left = 11
       Top = 20
-      Width = 126
+      Width = 135
       Height = 17
       Caption = 'Synchronize &files'
       TabOrder = 0
       OnClick = ControlChange
     end
     object MirrorFilesButton: TRadioButton
-      Left = 139
+      Left = 155
       Top = 20
-      Width = 131
+      Width = 143
       Height = 17
       Caption = '&Mirror files'
       TabOrder = 1
       OnClick = ControlChange
     end
     object SynchronizeTimestampsButton: TRadioButton
-      Left = 272
+      Left = 304
       Top = 20
-      Width = 139
+      Width = 154
       Height = 17
       Caption = 'Synchronize &timestamps'
       TabOrder = 2

+ 1 - 1
source/forms/FullSynchronize.h

@@ -79,7 +79,7 @@ private:
   TCopyParamType __fastcall GetCopyParams();
   void __fastcall CopyParamClick(TObject * Sender);
   int __fastcall ActualCopyParamAttrs();
-  void __fastcall CopyParamListPopup(TPoint P, int AdditionalOptions);
+  void __fastcall CopyParamListPopup(TRect R, int AdditionalOptions);
 
 public:
   __fastcall TFullSynchronizeDialog(TComponent* Owner);

+ 1 - 1
source/forms/ImportSessions.cpp

@@ -190,7 +190,7 @@ bool __fastcall TImportSessionsDialog::Execute(bool & ImportKeys)
 {
   ImportKeysCheck->Checked = ImportKeys;
 
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
 
   if (Result)
   {

+ 1 - 1
source/forms/ImportSessions.dfm

@@ -77,7 +77,7 @@ object ImportSessionsDialog: TImportSessionsDialog
   object CheckAllButton: TButton
     Left = 8
     Top = 242
-    Width = 89
+    Width = 108
     Height = 25
     Anchors = [akLeft, akBottom]
     Caption = 'Un/check &all'

+ 31 - 26
source/forms/InputDlg.cpp

@@ -7,6 +7,7 @@
 #include <Windows.hpp>
 #include <Consts.hpp>
 #include <HistoryComboBox.hpp>
+#include <PasTools.hpp>
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 //---------------------------------------------------------------------------
@@ -43,15 +44,9 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
   const UnicodeString APrompt, UnicodeString & Value, UnicodeString HelpKeyword,
   TStrings * History, bool PathInput, TInputDialogInitialize OnInitialize)
 {
-  TForm * Form;
-  TLabel * Prompt;
-  TEdit * Edit;
-  THistoryComboBox * HistoryCombo;
-  TPoint DialogUnits;
-  int ButtonTop, ButtonWidth, ButtonHeight;
   bool Result = False;
   TInputDialogToken Token;
-  Form = new TForm(GetFormOwner(), 0); // bypass the VCL streaming (for Salamander)
+  TForm * Form = new TForm(GetFormOwner(), 0); // bypass the VCL streaming (for Salamander)
   try
   {
     // salam needs to override this in UseSystemSettings
@@ -59,6 +54,13 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
     SetCorrectFormParent(Form);
     UseSystemSettingsPre(Form);
 
+    // this is what TCustomForm.Loaded does
+    // Note that this is not needed as due to use of an alternative constructor above
+    // we are already set to default font
+    // See TMessageForm::Create for contrary
+    Form->Font->Assign(Application->DefaultFont);
+    Form->ParentFont = true;
+
     Token.OnInitialize = OnInitialize;
     Token.PathInput = PathInput;
 
@@ -68,11 +70,10 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
     Form->OnShow = OnShow;
 
     Form->Canvas->Font = Form->Font;
-    DialogUnits = GetAveCharSize(Form->Canvas);
     Form->BorderStyle = bsDialog;
     Form->Caption = ACaption;
-    Form->ClientWidth = MulDiv(220, DialogUnits.x, 4);
-    Form->ClientHeight = MulDiv(63, DialogUnits.y, 8);
+    Form->ClientWidth = ScaleByTextHeightRunTime(Form, 275);
+    Form->ClientHeight = ScaleByTextHeightRunTime(Form, 102);
     if (!HelpKeyword.IsEmpty())
     {
       Form->HelpKeyword = HelpKeyword;
@@ -80,13 +81,15 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
       Form->BorderIcons = TBorderIcons(Form->BorderIcons) << biHelp;
     }
 
-    Prompt = new TLabel(Form);
+    TLabel * Prompt = new TLabel(Form);
     Prompt->Parent = Form;
     Prompt->AutoSize = True;
-    Prompt->Left = MulDiv(8, DialogUnits.x, 4);
-    Prompt->Top = MulDiv(8, DialogUnits.y, 8);
+    Prompt->Left = ScaleByTextHeightRunTime(Form, 10);
+    Prompt->Top = ScaleByTextHeightRunTime(Form, 13);
     Prompt->Caption = APrompt;
 
+    TEdit * Edit;
+    THistoryComboBox * HistoryCombo;
     if (History == NULL)
     {
       Edit = new TEdit(Form);
@@ -109,15 +112,23 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
       Token.EditControl = HistoryCombo;
     }
     Token.EditControl->Left = Prompt->Left;
-    Token.EditControl->Top = MulDiv(19, DialogUnits.y, 8);
-    Token.EditControl->Width = MulDiv(204, DialogUnits.x, 4);
+    Token.EditControl->Top = ScaleByTextHeightRunTime(Form, 30);
+    Token.EditControl->Width = ScaleByTextHeightRunTime(Form, 255);
 
     Prompt->FocusControl = Token.EditControl;
 
-    ButtonTop = MulDiv(41, DialogUnits.y, 8);
-    ButtonWidth = MulDiv(50, DialogUnits.x, 4);
-    ButtonHeight = MulDiv(14, DialogUnits.y, 8);
-    int ButtonSpace = MulDiv(5, DialogUnits.x, 4);
+    int ButtonTop = ScaleByTextHeightRunTime(Form, 66);
+    int ButtonSpace = ScaleByTextHeightRunTime(Form, 6);
+
+    TButton * Button;
+    Button = new TButton(Form);
+    Button->Parent = Form;
+    Button->Caption = Vcl_Consts_SMsgDlgOK;
+    Button->ModalResult = mrOk;
+    Button->Default = True;
+
+    int ButtonHeight = ScaleByTextHeightRunTime(Button, Button->Height);
+    int ButtonWidth = ScaleByTextHeightRunTime(Button, Button->Width);
     int ButtonsStart;
     if (HelpKeyword.IsEmpty())
     {
@@ -128,12 +139,6 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
       ButtonsStart = (Form->ClientWidth / 2) - (3 * ButtonWidth / 2) - ButtonSpace;
     }
 
-    TButton * Button;
-    Button = new TButton(Form);
-    Button->Parent = Form;
-    Button->Caption = Vcl_Consts_SMsgDlgOK;
-    Button->ModalResult = mrOk;
-    Button->Default = True;
     Button->SetBounds(ButtonsStart, ButtonTop, ButtonWidth, ButtonHeight);
 
     Button = new TButton(Form);
@@ -159,7 +164,7 @@ bool __fastcall InputDialog(const UnicodeString ACaption,
 
     UseSystemSettingsPost(Form);
 
-    if (Form->ShowModal() == mrOk)
+    if (Form->ShowModal() == DefaultResult(Form))
     {
       if (History != NULL)
       {

+ 27 - 15
source/forms/LocationProfiles.cpp

@@ -409,23 +409,11 @@ void __fastcall TLocationProfilesDialog::LoadBookmarks(
 bool __fastcall TLocationProfilesDialog::Execute()
 {
   bool Result;
-  UnicodeString SessionKey;
-  if (Terminal)
-  {
-    // cache session key, in case terminal is closed while the window is open
-    SessionKey = Terminal->SessionData->SessionKey;
-    LoadBookmarks(SessionProfilesView, FSessionFolders, FSessionBookmarkList, WinConfiguration->Bookmarks[SessionKey]);
-    LoadBookmarks(SharedProfilesView, FSharedFolders, FSharedBookmarkList, WinConfiguration->SharedBookmarks);
-  }
-  if (Mode == odAddBookmark)
-  {
-    AddAsBookmark(GetProfilesSheet(), true);
-  }
   PageControl->ActivePage = GetProfilesSheet();
-  Result = (ShowModal() == mrOk);
+  Result = (ShowModal() == DefaultResult(this));
   if (Terminal)
   {
-    WinConfiguration->Bookmarks[SessionKey] = FSessionBookmarkList;
+    WinConfiguration->Bookmarks[FSessionKey] = FSessionBookmarkList;
     WinConfiguration->SharedBookmarks = FSharedBookmarkList;
     WinConfiguration->UseSharedBookmarks = (PageControl->ActivePage == SharedProfilesSheet);
   }
@@ -457,6 +445,10 @@ TBookmarkList * TLocationProfilesDialog::GetBookmarkList(TObject * Sender)
 //---------------------------------------------------------------------------
 TStringList * TLocationProfilesDialog::GetFolders(TObject * Sender)
 {
+  #ifdef _DEBUG
+  assert(FSessionProfilesViewHandle == SessionProfilesView->Handle);
+  assert(FSharedProfilesViewHandle == SharedProfilesView->Handle);
+  #endif
   return GetProfilesObject(Sender, FSessionFolders, FSharedFolders);
 }
 //---------------------------------------------------------------------------
@@ -761,12 +753,32 @@ void __fastcall TLocationProfilesDialog::ProfilesViewDblClick(TObject * Sender)
   TTreeNode * Node = ProfilesView->GetNodeAt(P.x, P.y);
   if (OKBtn->Enabled && Node && Node->Data && Node->Selected)
   {
-    ModalResult = mrOk;
+    ModalResult = DefaultResult(this);
   }
 }
 //---------------------------------------------------------------------------
 void __fastcall TLocationProfilesDialog::FormShow(TObject * /*Sender*/)
 {
+  if (Terminal)
+  {
+    // cache session key, in case terminal is closed while the window is open
+    FSessionKey = Terminal->SessionData->SessionKey;
+    // WORAROUND
+    // Has to load this only now (not in Execute before ShowModal),
+    // when the trees are finally (re)created,
+    // otherwise the references in *Folders would be invalid already
+    LoadBookmarks(SessionProfilesView, FSessionFolders, FSessionBookmarkList, WinConfiguration->Bookmarks[FSessionKey]);
+    LoadBookmarks(SharedProfilesView, FSharedFolders, FSharedBookmarkList, WinConfiguration->SharedBookmarks);
+    #ifdef _DEBUG
+    FSessionProfilesViewHandle = SessionProfilesView->Handle;
+    FSharedProfilesViewHandle = SharedProfilesView->Handle;
+    #endif
+  }
+  if (Mode == odAddBookmark)
+  {
+    AddAsBookmark(GetProfilesSheet(), true);
+  }
+
   InstallPathWordBreakProc(LocalDirectoryEdit);
   InstallPathWordBreakProc(RemoteDirectoryEdit);
 

+ 5 - 0
source/forms/LocationProfiles.h

@@ -119,6 +119,11 @@ private:
   UnicodeString FRemoteDirectory;
   TTreeViewScrollOnDragOver * FSessionScrollOnDragOver;
   TTreeViewScrollOnDragOver * FSharedScrollOnDragOver;
+  UnicodeString FSessionKey;
+  #ifdef _DEBUG
+  HWND FSessionProfilesViewHandle;
+  HWND FSharedProfilesViewHandle;
+  #endif
 
   void __fastcall SetLocalDirectory(UnicodeString value);
   UnicodeString __fastcall GetLocalDirectory();

+ 1 - 0
source/forms/Log.cpp

@@ -74,6 +74,7 @@ __fastcall TLogForm::TLogForm(TComponent* Owner)
   FSessionLog = NULL;
   ShowWindow(Handle, SW_SHOWNA);
   UseSystemSettings(this);
+  UseDesktopFont(StatusBar);
   SetFormIcons(this, L"Z_ICON_LOG_BIG", L"Z_ICON_LOG_SMALL");
 }
 //---------------------------------------------------------------------------

+ 1 - 5
source/forms/Log.dfm

@@ -10,11 +10,7 @@ object LogForm: TLogForm
   Color = clBtnFace
   Constraints.MinHeight = 170
   Constraints.MinWidth = 250
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
+  ParentFont = True
   OldCreateOrder = False
   OnClose = FormClose
   PixelsPerInch = 96

+ 49 - 31
source/forms/Login.cpp

@@ -100,6 +100,9 @@ void __fastcall TLoginDialog::Init(TStoredSessionList *SessionList,
   UnicodeString Dummy;
   RunPageantAction->Visible = FindTool(PageantTool, Dummy);
   RunPuttygenAction->Visible = FindTool(PuttygenTool, Dummy);
+  AdvancedButton->Style =
+    FLAGSET(FOptions, loExternalTools) ?
+      TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
   UpdateControls();
 }
 //---------------------------------------------------------------------
@@ -394,14 +397,22 @@ void __fastcall TLoginDialog::LoadSession(TSessionData * SessionData)
     FDefaultPort = DefaultPort();
     FUpdatePortWithProtocol = true;
 
-    // advanced
-    InvalidateSessionData();
-    // close advanced settings only when really needed,
-    // see also note in SessionAdvancedActionExecute
-    if (Editable)
+    if (SessionData != FSessionData)
+    {
+      // advanced
+      InvalidateSessionData();
+      // clone advanced settings only when really needed,
+      // see also note in SessionAdvancedActionExecute
+      if (Editable)
+      {
+        FSessionData = new TSessionData(L"");
+        FSessionData->Assign(SessionData);
+      }
+    }
+    else
     {
-      FSessionData = new TSessionData(L"");
-      FSessionData->Assign(SessionData);
+      // we should get here only when called from SessionAdvancedActionExecute
+      assert(Editable);
     }
   }
   __finally
@@ -595,30 +606,22 @@ TSessionData * __fastcall TLoginDialog::GetSessionData()
 //---------------------------------------------------------------------------
 void __fastcall TLoginDialog::SessionTreeDblClick(TObject * /*Sender*/)
 {
-  TPoint P = SessionTree->ScreenToClient(Mouse->CursorPos);
-  TTreeNode * Node = SessionTree->GetNodeAt(P.x, P.y);
-
-  if (IsSessionNode(Node))
+  if (CanLogin())
   {
-    TSessionData * Data = GetNodeSession(Node);
+    TPoint P = SessionTree->ScreenToClient(Mouse->CursorPos);
+    TTreeNode * Node = SessionTree->GetNodeAt(P.x, P.y);
+
     // this may be false, when collapsed folder was double-clicked,
     // it got expanded, view was shifted to accommodate folder contents,
     // so that cursor now points to a different node (site)
-    if (Data == SelectedSession)
+    if (Node == SessionTree->Selected)
     {
-      if (FStoredSessions->CanLogin(Data))
+      if (IsSessionNode(Node) || IsWorkspaceNode(Node))
       {
-        ModalResult = mrOk;
+        ModalResult = DefaultResult(this);
       }
     }
   }
-  else if (IsWorkspaceNode(Node))
-  {
-    if (HasNodeAnySession(Node, true))
-    {
-      ModalResult = mrOk;
-    }
-  }
 }
 //---------------------------------------------------------------------------
 TSessionData * __fastcall TLoginDialog::GetSelectedSession()
@@ -943,10 +946,7 @@ void __fastcall TLoginDialog::ActionListUpdate(TBasicAction * BasicAction,
   }
   else if (Action == LoginAction)
   {
-    TSessionData * Data = GetSessionData();
-    LoginAction->Enabled =
-      ((Data != NULL) && FStoredSessions->CanLogin(Data) && !FEditing) ||
-      (FolderOrWorkspaceSelected && HasNodeAnySession(SessionTree->Selected, true));
+    LoginAction->Enabled = CanLogin();
   }
   else if (Action == SaveSessionAction)
   {
@@ -987,6 +987,14 @@ void __fastcall TLoginDialog::ActionListUpdate(TBasicAction * BasicAction,
   Idle();
 }
 //---------------------------------------------------------------------------
+bool __fastcall TLoginDialog::CanLogin()
+{
+  TSessionData * Data = GetSessionData();
+  return
+    ((Data != NULL) && FStoredSessions->CanLogin(Data) && !FEditing) ||
+    (IsFolderOrWorkspaceNode(SessionTree->Selected) && HasNodeAnySession(SessionTree->Selected, true));
+}
+//---------------------------------------------------------------------------
 void __fastcall TLoginDialog::Idle()
 {
   if (SessionTree->IsEditing() != FRenaming)
@@ -1023,7 +1031,7 @@ bool __fastcall TLoginDialog::Execute(TList * DataList)
     Default();
   }
   LoadState();
-  bool Result = (ShowModal() == mrOk);
+  bool Result = IsDefaultResult(ShowModal());
   SaveState();
   if (Result)
   {
@@ -1471,10 +1479,16 @@ void __fastcall TLoginDialog::HelpButtonClick(TObject * /*Sender*/)
   FormHelp(this);
 }
 //---------------------------------------------------------------------------
+bool __fastcall TLoginDialog::IsDefaultResult(TModalResult Result)
+{
+  // When editing, there's no default button, so make sure we do not call DefaultResult
+  return !FEditing && (Result == DefaultResult(this));
+}
+//---------------------------------------------------------------------------
 void __fastcall TLoginDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (IsDefaultResult(ModalResult))
   {
     SaveDataList(FDataList);
   }
@@ -1552,7 +1566,7 @@ void __fastcall TLoginDialog::SessionTreeEdited(TObject * /*Sender*/,
       Session->Remove();
 
       TSessionData * NewSession = StoredSessions->NewSession(Path, Session);
-      // modified, only explicit
+      // modified only, explicit
       StoredSessions->Save(false, true);
       // the session may be the same, if only letter case has changed
       if (Session != NewSession)
@@ -1629,7 +1643,7 @@ void __fastcall TLoginDialog::SessionTreeEdited(TObject * /*Sender*/,
 
       if (AnySession)
       {
-        // modified, only explicit
+        // modified only, explicit
         StoredSessions->Save(false, true);
       }
     }
@@ -2022,7 +2036,7 @@ void __fastcall TLoginDialog::SessionTreeDragDrop(TObject * Sender,
     Session->Remove();
 
     TSessionData * NewSession = StoredSessions->NewSession(Path, Session);
-    // modified, only explicit
+    // modified only, explicit
     StoredSessions->Save(false, true);
     // this should aways be the case
     if (ALWAYS_TRUE(Session != NewSession))
@@ -2459,6 +2473,10 @@ void __fastcall TLoginDialog::SessionAdvancedActionExecute(TObject * /*Sender*/)
   {
     SaveSession(FSessionData);
     DoSiteAdvancedDialog(FSessionData, FOptions);
+    // not really need as advanced site dialog can only change between
+    // fsSFTP and fsSFTPonly, difference of the two not being visible on
+    // login dialog.
+    LoadSession(FSessionData);
   }
 }
 //---------------------------------------------------------------------------

+ 13 - 13
source/forms/Login.dfm

@@ -126,7 +126,7 @@ object LoginDialog: TLoginDialog
           FocusControl = UserNameEdit
         end
         object Label4: TLabel
-          Left = 164
+          Left = 178
           Top = 122
           Width = 50
           Height = 13
@@ -176,7 +176,7 @@ object LoginDialog: TLoginDialog
         object HostNameEdit: TEdit
           Left = 12
           Top = 89
-          Width = 228
+          Width = 236
           Height = 21
           Anchors = [akLeft, akTop, akRight]
           MaxLength = 100
@@ -187,7 +187,7 @@ object LoginDialog: TLoginDialog
         object UserNameEdit: TEdit
           Left = 12
           Top = 139
-          Width = 137
+          Width = 159
           Height = 21
           MaxLength = 100
           TabOrder = 7
@@ -195,9 +195,9 @@ object LoginDialog: TLoginDialog
           OnChange = DataChange
         end
         object PasswordEdit: TPasswordEdit
-          Left = 163
+          Left = 177
           Top = 139
-          Width = 173
+          Width = 159
           Height = 21
           Anchors = [akLeft, akTop, akRight]
           MaxLength = 100
@@ -221,7 +221,7 @@ object LoginDialog: TLoginDialog
         object TransferProtocolCombo: TComboBox
           Left = 12
           Top = 39
-          Width = 137
+          Width = 145
           Height = 21
           Style = csDropDownList
           TabOrder = 0
@@ -285,9 +285,9 @@ object LoginDialog: TLoginDialog
           TabOrder = 10
         end
         object AdvancedButton: TButton
-          Left = 240
+          Left = 238
           Top = 193
-          Width = 96
+          Width = 98
           Height = 25
           Action = SessionAdvancedAction
           Anchors = [akRight, akBottom]
@@ -307,7 +307,7 @@ object LoginDialog: TLoginDialog
           OnDropDownClick = SaveButtonDropDownClick
         end
         object EditCancelButton: TButton
-          Left = 114
+          Left = 116
           Top = 193
           Width = 82
           Height = 25
@@ -320,7 +320,7 @@ object LoginDialog: TLoginDialog
         object EditButton: TButton
           Left = 12
           Top = 193
-          Width = 96
+          Width = 98
           Height = 25
           Action = EditSessionAction
           Anchors = [akLeft, akBottom]
@@ -438,9 +438,9 @@ object LoginDialog: TLoginDialog
       Visible = False
     end
     object ManageButton: TButton
-      Left = 162
+      Left = 160
       Top = 401
-      Width = 96
+      Width = 98
       Height = 25
       Anchors = [akRight, akBottom]
       Caption = '&Manage'
@@ -450,7 +450,7 @@ object LoginDialog: TLoginDialog
     object ToolsMenuButton: TButton
       Left = 11
       Top = 401
-      Width = 96
+      Width = 98
       Height = 25
       Anchors = [akLeft, akBottom]
       Caption = '&Tools'

+ 2 - 0
source/forms/Login.h

@@ -302,6 +302,8 @@ private:
   TSessionData * __fastcall GetEditingSessionData();
   void __fastcall SaveAsSession(bool ForceDialog);
   void __fastcall InvalidateSessionData();
+  bool __fastcall CanLogin();
+  bool __fastcall IsDefaultResult(TModalResult Result);
 
 protected:
   void __fastcall Default();

+ 201 - 65
source/forms/MessageDlg.cpp

@@ -14,16 +14,57 @@
 #include <TextsCore.h>
 #include <Vcl.Imaging.pngimage.hpp>
 #include <StrUtils.hpp>
+#include <PasTools.hpp>
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 //---------------------------------------------------------------------------
+class TMessageButton : public TButton
+{
+public:
+  __fastcall TMessageButton(TComponent * Owner);
+protected:
+  virtual void __fastcall Dispatch(void * Message);
+private:
+  void __fastcall WMGetDlgCode(TWMGetDlgCode & Message);
+};
+//---------------------------------------------------------------------------
+__fastcall TMessageButton::TMessageButton(TComponent * Owner) :
+  TButton(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TMessageButton::Dispatch(void * Message)
+{
+  TMessage * M = reinterpret_cast<TMessage*>(Message);
+  if (M->Msg == WM_GETDLGCODE)
+  {
+    WMGetDlgCode(*((TWMGetDlgCode *)Message));
+  }
+  else
+  {
+    TButton::Dispatch(Message);
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TMessageButton::WMGetDlgCode(TWMGetDlgCode & Message)
+{
+  TButton::Dispatch(&Message);
+  // WORKAROUND
+  // Windows default handler returns DLGC_WANTARROWS for split buttons,
+  // what prevent left/right keys from being used for focusing next/previous buttons/controls.
+  // Overrwide that. Though note that we need to pass the up/down keys back to button
+  // to allow drop down, see TMessageForm::CMDialogKey
+  Message.Result = Message.Result & ~DLGC_WANTARROWS;
+}
+//---------------------------------------------------------------------------
 class TMessageForm : public TForm
 {
 public:
   static TForm * __fastcall Create(const UnicodeString & Msg, TStrings * MoreMessages,
     TMsgDlgType DlgType, unsigned int Answers,
     const TQueryButtonAlias * Aliases, unsigned int AliasesCount,
-    unsigned int TimeoutAnswer, TButton ** TimeoutButton, const UnicodeString & ImageName);
+    unsigned int TimeoutAnswer, TButton ** TimeoutButton, const UnicodeString & ImageName,
+    const UnicodeString & NeverAskAgainCaption);
 
 protected:
   __fastcall TMessageForm(TComponent * AOwner);
@@ -48,6 +89,7 @@ private:
   TMemo * MessageMemo;
   TShiftState FShiftState;
   TTimer * FUpdateForShiftStateTimer;
+  TForm * FDummyForm;
 
   void __fastcall HelpButtonClick(TObject * Sender);
   void __fastcall ReportButtonClick(TObject * Sender);
@@ -65,18 +107,15 @@ __fastcall TMessageForm::TMessageForm(TComponent * AOwner) : TForm(AOwner, 0)
   Message = NULL;
   MessageMemo = NULL;
   FUpdateForShiftStateTimer = NULL;
-  TNonClientMetrics NonClientMetrics;
-  NonClientMetrics.cbSize = sizeof(NonClientMetrics);
-  if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NonClientMetrics, 0))
-  {
-    Font->Handle = CreateFontIndirect(&NonClientMetrics.lfMessageFont);
-  }
   Position = poOwnerFormCenter;
   UseSystemSettingsPre(this);
+  FDummyForm = new TForm(this);
+  UseSystemSettings(FDummyForm);
 }
 //---------------------------------------------------------------------------
 __fastcall TMessageForm::~TMessageForm()
 {
+  SAFE_DESTROY(FDummyForm);
   SAFE_DESTROY(FUpdateForShiftStateTimer);
 }
 //---------------------------------------------------------------------------
@@ -271,6 +310,12 @@ void __fastcall TMessageForm::CMDialogKey(TWMKeyDown & Message)
       TForm::Dispatch(&Message);
     }
   }
+  else if ((Message.CharCode == VK_UP) || (Message.CharCode == VK_DOWN))
+  {
+    // WORKAROUND
+    // noop to make up/down be passed back to button to allow drop down,
+    // see TMessageButton::WMGetDlgCode
+  }
   else
   {
     TForm::Dispatch(&Message);
@@ -337,15 +382,15 @@ const ResourceString * Captions[] = { &_SMsgDlgWarning, &_SMsgDlgError, &_SMsgDl
   &_SMsgDlgConfirm, NULL };
 const wchar_t * IconIDs[] = { IDI_EXCLAMATION, IDI_HAND, IDI_ASTERISK,
   IDI_QUESTION, NULL };
-const int mcHorzMargin = 8;
-const int mcVertMargin = 8;
-const int mcHorzSpacing = 10;
-const int mcVertSpacing = 10;
-const int mcButtonWidth = 50;
-const int mcButtonHeight = 14;
-const int mcButtonSpacing = 4;
-const int mcMoreMessageWidth = 320;
-const int mcMoreMessageHeight = 80;
+const int mcHorzMargin = 10;
+const int mcVertMargin = 13;
+const int mcHorzSpacing = 12;
+const int mcVertSpacing = 24;
+const int mcButtonSpacing = 5;
+const int mcMoreMessageWidth = 400;
+const int mcMoreMessageHeight = 86;
+// approximately what Windows Vista task dialogs use
+const int mcMaxDialogWidth = 390;
 //---------------------------------------------------------------------------
 static UnicodeString __fastcall GetKeyNameStr(int Key)
 {
@@ -380,7 +425,7 @@ TButton * __fastcall TMessageForm::CreateButton(
     UnicodeString(MeasureCaption).c_str(), -1,
     &TextRect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE |
     DrawTextBiDiModeFlagsReadingOnly());
-  int CurButtonWidth = TextRect.Right - TextRect.Left + 8;
+  int CurButtonWidth = TextRect.Right - TextRect.Left + ScaleByTextHeightRunTime(this, 16);
 
   TButton * Button = NULL;
 
@@ -448,15 +493,20 @@ TButton * __fastcall TMessageForm::CreateButton(
     // Also we do not update the max button width for the default groupped
     // button caption. We just blindly hope that captions of advanced commands
     // are always longer than the caption of simple default command
-    CurButtonWidth += 15;
+    CurButtonWidth += ScaleByTextHeightRunTime(this, 15);
   }
   else
   {
-    Button = new TButton(this);
+    Button = new TMessageButton(this);
 
     Button->Name = Name;
     Button->Parent = this;
     Button->Caption = Caption;
+    // Scale buttons using regular font, so that they are as large as buttons
+    // on other dialogs (note that they are still higher than Windows Task dialog
+    // buttons)
+    Button->Height = ScaleByTextHeightRunTime(FDummyForm, Button->Height);
+    Button->Width = ScaleByTextHeightRunTime(FDummyForm, Button->Width);
 
     if (OnClick != NULL)
     {
@@ -471,6 +521,12 @@ TButton * __fastcall TMessageForm::CreateButton(
     {
       Button->Anchors = TAnchors() << akBottom << akLeft;
     }
+
+    // never shrink buttons below their default width
+    if (Button->Width > CurButtonWidth)
+    {
+      CurButtonWidth = Button->Width;
+    }
   }
 
   if (CurButtonWidth > ButtonWidth)
@@ -561,10 +617,17 @@ void __fastcall AnswerNameAndCaption(
   }
 }
 //---------------------------------------------------------------------------
+static int __fastcall CalculateWidthOnCanvas(UnicodeString Text, void * Arg)
+{
+  TCanvas * Canvas = static_cast<TCanvas *>(Arg);
+  return Canvas->TextWidth(Text);
+}
+//---------------------------------------------------------------------------
 TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
   TStrings * MoreMessages, TMsgDlgType DlgType, unsigned int Answers,
   const TQueryButtonAlias * Aliases, unsigned int AliasesCount,
-  unsigned int TimeoutAnswer, TButton ** TimeoutButton, const UnicodeString & ImageName)
+  unsigned int TimeoutAnswer, TButton ** TimeoutButton, const UnicodeString & ImageName,
+  const UnicodeString & NeverAskAgainCaption)
 {
   unsigned int DefaultAnswer;
   if (FLAGSET(Answers, qaOK))
@@ -588,17 +651,18 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
   }
 
   TMessageForm * Result = SafeFormCreate<TMessageForm>();
+  UseDesktopFont(Result);
 
   Result->BiDiMode = Application->BiDiMode;
   Result->BorderStyle = bsDialog;
   Result->Canvas->Font = Result->Font;
   Result->KeyPreview = true;
-  TPoint DialogUnits = GetAveCharSize(Result->Canvas);
-  int HorzMargin = MulDiv(mcHorzMargin, DialogUnits.x, 4);
-  int VertMargin = MulDiv(mcVertMargin, DialogUnits.y, 8);
-  int HorzSpacing = MulDiv(mcHorzSpacing, DialogUnits.x, 4);
-  int VertSpacing = MulDiv(mcVertSpacing, DialogUnits.y, 8);
-  int ButtonWidth = MulDiv(mcButtonWidth, DialogUnits.x, 4);
+  int HorzMargin = ScaleByTextHeightRunTime(Result, mcHorzMargin);
+  int VertMargin = ScaleByTextHeightRunTime(Result, mcVertMargin);
+  int HorzSpacing = ScaleByTextHeightRunTime(Result, mcHorzSpacing);
+  int VertSpacing = ScaleByTextHeightRunTime(Result, mcVertSpacing);
+  int ButtonWidth = -1;
+  int ButtonHeight = -1;
   std::vector<TButton *> ButtonControls;
   TAnswerButtons AnswerButtons;
   for (unsigned int Answer = qaFirst; Answer <= qaLast; Answer = Answer << 1)
@@ -671,6 +735,11 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
 
         Button->Default = (Answer == DefaultAnswer);
         Button->Cancel = (Answer == CancelAnswer);
+        if (ButtonHeight < 0)
+        {
+          ButtonHeight = Button->Height;
+        }
+        assert(ButtonHeight == Button->Height);
 
         AnswerButtons.insert(TAnswerButtons::value_type(Answer, Button));
 
@@ -682,57 +751,101 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
     }
   }
 
-  int ButtonHeight = MulDiv(mcButtonHeight, DialogUnits.y, 8);
-  int ButtonSpacing = MulDiv(mcButtonSpacing, DialogUnits.x, 4);
+  int NeverAskAgainWidth = 0;
+  if (!NeverAskAgainCaption.IsEmpty())
+  {
+    NeverAskAgainWidth =
+      ScaleByTextHeightRunTime(Result, 16) + // checkbox
+      Result->Canvas->TextWidth(NeverAskAgainCaption) +
+      ScaleByTextHeightRunTime(Result, 16); // margin
+  }
+
+  int ButtonSpacing = ScaleByTextHeightRunTime(Result, mcButtonSpacing);
+  int ButtonGroupWidth = NeverAskAgainWidth;
+  if (!ButtonControls.empty())
+  {
+    ButtonGroupWidth += ButtonWidth * ButtonControls.size() +
+      ButtonSpacing * (ButtonControls.size() - 1);
+  }
+
+  UnicodeString NormalizedMsg = Msg;
+  // Windows XP (not sure about Vista) does not support Hair space.
+  // For Windows XP, we still keep the existing hack by using hard-coded spaces
+  // in resource string
+  if (CheckWin32Version(6, 1))
+  {
+    // Have to be padding with spaces (the smallest space defined, hair space = 1px),
+    // as tabs actually do not tab, just expand to 8 spaces.
+    // Otherwise we would have to do custom drawing
+    // (using GetTabbedTextExtent and TabbedTextOut)
+    const wchar_t HairSpace = L'\x200A';
+    ApplyTabs(NormalizedMsg, HairSpace, CalculateWidthOnCanvas, Result->Canvas);
+  }
+
+  int IconWidth = 0;
+  const wchar_t * IconID = IconIDs[DlgType];
+  bool HasIcon = (IconID != NULL) || !ImageName.IsEmpty();
+  if (HasIcon)
+  {
+    IconWidth = 32 + HorzSpacing;
+  }
+  assert((ButtonHeight > 0) && (ButtonWidth > 0));
+  int MaxTextWidth = ScaleByTextHeightRunTime(Result, mcMaxDialogWidth);
+  // if the dialog would be wide anyway (overwrite confirmation on Windows XP),
+  // to fit the buttons, do not restrict the text
+  if (MaxTextWidth < ButtonGroupWidth - IconWidth)
+  {
+    MaxTextWidth = ButtonGroupWidth - IconWidth;
+  }
   TRect TextRect;
-  SetRect(&TextRect, 0, 0, Screen->Width / 2, 0);
-  DrawText(Result->Canvas->Handle, Msg.c_str(), Msg.Length() + 1, &TextRect,
+  SetRect(&TextRect, 0, 0, MaxTextWidth, 0);
+  DrawText(Result->Canvas->Handle, NormalizedMsg.c_str(), NormalizedMsg.Length() + 1, &TextRect,
     DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK |
     Result->DrawTextBiDiModeFlagsReadingOnly());
-  int MaxWidth = Screen->Width - HorzMargin * 2 - 32 - HorzSpacing - 30;
+  int MaxWidth = Screen->Width - HorzMargin * 2 - IconWidth - 30;
   if (TextRect.right > MaxWidth)
   {
     // this will truncate the text, we should implement something smarter eventually
     TextRect.right = MaxWidth;
   }
-  const wchar_t * IconID = IconIDs[DlgType];
-  int IconTextWidth = TextRect.Right;
+  int IconTextWidth = TextRect.Right + IconWidth;
   int IconTextHeight = TextRect.Bottom;
-  if ((IconID != NULL) || !ImageName.IsEmpty())
+  if (HasIcon && (IconTextHeight < 32))
   {
-    IconTextWidth += 32 + HorzSpacing;
-    if (IconTextHeight < 32)
-    {
-      IconTextHeight = 32;
-    }
+    IconTextHeight = 32;
   }
 
+  int MoreMessageWidth = (MoreMessages != NULL ?
+    ScaleByTextHeightRunTime(Result, mcMoreMessageWidth) : 0);
+  int MoreMessageHeight = (MoreMessages != NULL ?
+    ScaleByTextHeightRunTime(Result, mcMoreMessageHeight) : 0);
+
+  int ButtonTop = IconTextHeight + VertMargin + VertSpacing + MoreMessageHeight;
+  TPanel * Panel = new TPanel(Result);
+  Panel->Name = L"Panel";
+  Panel->Parent = Result;
+  Panel->Color = clWindow;
+  Panel->ParentBackground = false;
+  Panel->SetBounds(0, 0, Result->ClientWidth, ButtonTop - (VertSpacing / 2));
+  Panel->Anchors = TAnchors() << akLeft << akRight << akTop;
+  Panel->BevelOuter = bvNone;
+  Panel->BevelKind = bkNone;
+  Panel->Caption = L"";
+
   if (MoreMessages != NULL)
   {
-    TMemo * MessageMemo = new TMemo(Result);
-    MessageMemo->Parent = Result;
+    TMemo * MessageMemo = new TMemo(Panel);
+    MessageMemo->Name = L"MessageMemo";
+    MessageMemo->Parent = Panel;
     MessageMemo->ReadOnly = true;
     MessageMemo->WantReturns = False;
     MessageMemo->ScrollBars = ssVertical;
-    MessageMemo->Anchors = TAnchors() << akLeft << akRight << akTop; //akBottom;
-    MessageMemo->Color = clBtnFace;
+    MessageMemo->Anchors = TAnchors() << akLeft << akRight << akTop;
     MessageMemo->Lines->Text = MoreMessages->Text;
 
     Result->MessageMemo = MessageMemo;
   }
 
-  int ButtonGroupWidth = 0;
-  if (!ButtonControls.empty())
-  {
-    ButtonGroupWidth = ButtonWidth * ButtonControls.size() +
-      ButtonSpacing * (ButtonControls.size() - 1);
-  }
-
-  int MoreMessageWidth = (MoreMessages != NULL ?
-    MulDiv(mcMoreMessageWidth, DialogUnits.x, 4) : 0);
-  int MoreMessageHeight = (MoreMessages != NULL ?
-    MulDiv(mcMoreMessageHeight, DialogUnits.y, 12) : 0);
-
   int AClientWidth =
     (IconTextWidth > ButtonGroupWidth ? IconTextWidth : ButtonGroupWidth) +
     HorzMargin * 2;
@@ -753,9 +866,9 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
 
   if ((IconID != NULL) || !ImageName.IsEmpty())
   {
-    TImage * Image = new TImage(Result);
+    TImage * Image = new TImage(Panel);
     Image->Name = L"Image";
-    Image->Parent = Result;
+    Image->Parent = Panel;
     if (!ImageName.IsEmpty())
     {
       std::auto_ptr<TPngImage> Png(new TPngImage());
@@ -769,12 +882,12 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
     Image->SetBounds(HorzMargin, VertMargin, 32, 32);
   }
 
-  TLabel * Message = new TLabel(Result);
+  TLabel * Message = new TLabel(Panel);
   Result->Message = Message;
   Message->Name = L"Message";
-  Message->Parent = Result;
+  Message->Parent = Panel;
   Message->WordWrap = true;
-  Message->Caption = Msg;
+  Message->Caption = NormalizedMsg;
   Message->BoundsRect = TextRect;
   Message->BiDiMode = Result->BiDiMode;
   // added to show & as & for messages containing !& pattern of custom commands
@@ -782,7 +895,6 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
   Message->ShowAccelChar = false;
   int ALeft = IconTextWidth - TextRect.Right + HorzMargin;
   Message->SetBounds(ALeft, VertMargin, TextRect.Right, TextRect.Bottom);
-  int ButtonTop = IconTextHeight + VertMargin + VertSpacing + MoreMessageHeight;
 
   if (Result->MessageMemo != NULL)
   {
@@ -798,22 +910,46 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
     }
   }
 
-  int X = (Result->ClientWidth - ButtonGroupWidth) / 2;
+  int X = Result->ClientWidth - ButtonGroupWidth + NeverAskAgainWidth - HorzMargin;
   for (unsigned int i = 0; i < ButtonControls.size(); i++)
   {
     ButtonControls[i]->SetBounds(X,
-      ButtonTop, ButtonWidth, ButtonHeight);
+      ButtonTop, ButtonWidth, ButtonControls[i]->Height);
     X += ButtonWidth + ButtonSpacing;
   }
 
+  if (!NeverAskAgainCaption.IsEmpty() &&
+      !ButtonControls.empty())
+  {
+    TCheckBox * NeverAskAgainCheck = new TCheckBox(Result);
+    NeverAskAgainCheck->Name = L"NeverAskAgainCheck";
+    NeverAskAgainCheck->Parent = Result;
+    NeverAskAgainCheck->Caption = NeverAskAgainCaption;
+    NeverAskAgainCheck->Anchors = TAnchors() << akBottom << akLeft;
+
+    TButton * FirstButton = ButtonControls[0];
+    int NeverAskAgainHeight = ScaleByTextHeightRunTime(Result, NeverAskAgainCheck->Height);
+    int NeverAskAgainTop = FirstButton->Top + ((FirstButton->Height - NeverAskAgainHeight) / 2);
+    int NeverAskAgainLeft = ScaleByTextHeightRunTime(Result, mcHorzMargin);
+
+    NeverAskAgainCheck->BoundsRect =
+      TRect(
+        NeverAskAgainLeft,
+        NeverAskAgainTop,
+        NeverAskAgainLeft + NeverAskAgainWidth,
+        NeverAskAgainTop + NeverAskAgainHeight);
+  }
+
   return Result;
 }
 //---------------------------------------------------------------------------
 TForm * __fastcall CreateMoreMessageDialog(const UnicodeString & Msg,
   TStrings * MoreMessages, TMsgDlgType DlgType, unsigned int Answers,
   const TQueryButtonAlias * Aliases, unsigned int AliasesCount,
-  unsigned int TimeoutAnswer, TButton ** TimeoutButton, const UnicodeString & ImageName)
+  unsigned int TimeoutAnswer, TButton ** TimeoutButton, const UnicodeString & ImageName,
+  const UnicodeString & NeverAskAgainCaption)
 {
   return TMessageForm::Create(Msg, MoreMessages, DlgType, Answers,
-    Aliases, AliasesCount, TimeoutAnswer, TimeoutButton, ImageName);
+    Aliases, AliasesCount, TimeoutAnswer, TimeoutButton, ImageName,
+    NeverAskAgainCaption);
 }

+ 4 - 2
source/forms/NonVisual.cpp

@@ -147,8 +147,10 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   #define EnabledFocusedFileOperation (ScpExplorer->EnableFocusedFileOperation[osCurrent])
   #define EnabledLocalSelectedOperation (ScpExplorer->HasDirView[osLocal] && ScpExplorer->EnableSelectedOperation[osLocal])
   #define EnabledLocalFocusedOperation (ScpExplorer->HasDirView[osLocal] && ScpExplorer->EnableFocusedOperation[osLocal])
+  #define EnabledLocalSelectedFileOperation (ScpExplorer->HasDirView[osLocal] && ScpExplorer->EnableSelectedFileOperation[osLocal])
   #define EnabledRemoteSelectedOperation (ScpExplorer->EnableSelectedOperation[osRemote])
   #define EnabledRemoteFocusedOperation (ScpExplorer->EnableFocusedOperation[osRemote])
+  #define EnabledRemoteSelectedFileOperation (ScpExplorer->EnableSelectedFileOperation[osRemote])
   // focused operation
   UPD(CurrentDeleteFocusedAction, EnabledFocusedOperation)
   UPD(CurrentPropertiesFocusedAction, EnabledFocusedOperation)
@@ -191,7 +193,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   // local selected operation
   UPD(LocalCopyAction, EnabledLocalSelectedOperation)
   UPD(LocalRenameAction, EnabledLocalSelectedOperation)
-  UPD(LocalEditAction, EnabledLocalSelectedOperation && !WinConfiguration->DisableOpenEdit)
+  UPD(LocalEditAction, EnabledLocalSelectedFileOperation && !WinConfiguration->DisableOpenEdit)
   UPD(LocalMoveAction, EnabledLocalSelectedOperation)
   UPD(LocalCreateDirAction, true)
   UPD(LocalDeleteAction, EnabledLocalSelectedOperation)
@@ -204,7 +206,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(RemoteCopyAction, EnabledRemoteSelectedOperation)
   UPD(RemoteRenameAction, EnabledRemoteSelectedOperation &&
     ScpExplorer->Terminal->IsCapable[fcRename])
-  UPD(RemoteEditAction, EnabledRemoteSelectedOperation && !WinConfiguration->DisableOpenEdit)
+  UPD(RemoteEditAction, EnabledRemoteSelectedFileOperation && !WinConfiguration->DisableOpenEdit)
   UPD(RemoteMoveAction, EnabledRemoteSelectedOperation)
   UPD(RemoteCreateDirAction, true)
   UPD(RemoteDeleteAction, EnabledRemoteSelectedOperation)

+ 5 - 4
source/forms/OpenDirectory.cpp

@@ -8,6 +8,7 @@
 #include <VCLCommon.h>
 #include <TextsWin.h>
 #include <Common.h>
+#include <Math.hpp>
 
 #include "OpenDirectory.h"
 #include "WinConfiguration.h"
@@ -146,7 +147,7 @@ void __fastcall TOpenDirectoryDialog::UpdateBookmarkControls(
       }
     }
     BookmarksList->ScrollWidth = MaxWidth;
-    MaxWidth += 6;
+    MaxWidth += ScaleByTextHeight(this, 6);
     if (BookmarksList->Items->Count > BookmarksList->ClientHeight / BookmarksList->ItemHeight)
     {
       MaxWidth += GetSystemMetrics(SM_CXVSCROLL);
@@ -154,7 +155,7 @@ void __fastcall TOpenDirectoryDialog::UpdateBookmarkControls(
     if (MaxWidth > BookmarksList->Width)
     {
       int CWidth = ClientWidth + (MaxWidth - BookmarksList->Width);
-      ClientWidth = CWidth > 700 ? 700 : CWidth;
+      ClientWidth = Min(CWidth, ScaleByTextHeight(this, 700));
     }
   }
 }
@@ -248,7 +249,7 @@ bool __fastcall TOpenDirectoryDialog::Execute()
       AddAsBookmark(PageControl->ActivePage);
     }
   }
-  Result = (ShowModal() == mrOk);
+  Result = (ShowModal() == DefaultResult(this));
   if (Terminal)
   {
     WinConfiguration->Bookmarks[SessionKey] = FSessionBookmarkList;
@@ -492,7 +493,7 @@ void __fastcall TOpenDirectoryDialog::BookmarksListDblClick(TObject * Sender)
 {
   if (GetBookmarksList(Sender)->ItemIndex >= 0)
   {
-    ModalResult = mrOk;
+    ModalResult = DefaultResult(this);
   }
 }
 //---------------------------------------------------------------------------

+ 26 - 15
source/forms/Preferences.cpp

@@ -38,6 +38,10 @@ bool __fastcall DoPreferencesDialog(TPreferencesMode APreferencesMode,
   try
   {
     Result = PreferencesDialog->Execute(DialogData);
+    if (Result)
+    {
+      Configuration->SaveExplicit();
+    }
   }
   __finally
   {
@@ -109,7 +113,7 @@ bool __fastcall TPreferencesDialog::Execute(TPreferencesDialogData * DialogData)
   PuttyPathEdit->Items = CustomWinConfiguration->History[L"PuttyPath"];
   FDialogData = DialogData;
   LoadConfiguration();
-  bool Result = (ShowModal() == mrOk);
+  bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
     SaveConfiguration();
@@ -296,7 +300,7 @@ void __fastcall TPreferencesDialog::LoadConfiguration()
       EditorEncodingCombo->ItemIndex = 0;
     }
     FEditorFont->Name = WinConfiguration->Editor.FontName;
-    FEditorFont->Height = WinConfiguration->Editor.FontHeight;
+    FEditorFont->Size = WinConfiguration->Editor.FontSize;
     FEditorFont->Charset = (TFontCharset)WinConfiguration->Editor.FontCharset;
     FEditorFont->Style = IntToFontStyles(WinConfiguration->Editor.FontStyle);
     (*FEditorList) = *WinConfiguration->EditorList;
@@ -593,8 +597,6 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
       WinConfiguration->DDTemporaryDirectory = DDTemporaryDirectoryEdit->Text;
     }
 
-    Configuration->Storage = RegistryStorageButton->Checked ? stRegistry : stIniFile;
-
     // Commander
     TScpCommanderConfiguration ScpCommander = WinConfiguration->ScpCommander;
     if (NortonLikeModeCombo->ItemIndex == 2)
@@ -646,7 +648,7 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
         break;
     }
     WinConfiguration->Editor.FontName = FEditorFont->Name;
-    WinConfiguration->Editor.FontHeight = FEditorFont->Height;
+    WinConfiguration->Editor.FontSize = FEditorFont->Size;
     WinConfiguration->Editor.FontCharset = FEditorFont->Charset;
     WinConfiguration->Editor.FontStyle = FontStylesToInt(FEditorFont->Style);
     WinConfiguration->EditorList = FEditorList;
@@ -831,13 +833,6 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
     // security
     GUIConfiguration->SessionRememberPassword = SessionRememberPasswordCheck->Checked;
 
-    // languages
-    if (LanguagesView->ItemFocused != NULL)
-    {
-      GUIConfiguration->Locale =
-        reinterpret_cast<LCID>(LanguagesView->ItemFocused->Data);
-    }
-
     // logging
     Configuration->Logging = EnableLoggingCheck->Checked;
     Configuration->LogProtocol = LogProtocolCombo->ItemIndex;
@@ -853,6 +848,19 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
     Configuration->LogActions = EnableActionsLoggingCheck->Checked;
     Configuration->ActionsLogFileName = ActionsLogFileNameEdit->Text;
 
+    // languages
+    // As this dialog does not explicitly support run-time locale changing,
+    // make this last, otherwise we lose some settings (or even worse
+    // we end-up saving default text box values=control names as our configuration)
+    if (LanguagesView->ItemFocused != NULL)
+    {
+      GUIConfiguration->Locale =
+        reinterpret_cast<LCID>(LanguagesView->ItemFocused->Data);
+    }
+
+    // this possibly fails, make it last, so that the other settings are preserved
+    Configuration->Storage = RegistryStorageButton->Checked ? stRegistry : stIniFile;
+
     #undef BOOLPROP
   }
   __finally
@@ -919,7 +927,6 @@ void __fastcall TPreferencesDialog::UpdateControls()
   {
     EnableControl(BeepOnFinishAfterEdit, BeepOnFinishCheck->Checked);
     EnableControl(BeepOnFinishAfterText, BeepOnFinishCheck->Checked);
-    EnableControl(BalloonNotificationsCheck, ::TTrayIcon::SupportsBalloons());
 
     EnableControl(ResumeThresholdEdit, ResumeSmartButton->Checked);
     EnableControl(ResumeThresholdUnitLabel, ResumeThresholdEdit->Enabled);
@@ -1096,7 +1103,7 @@ void __fastcall TPreferencesDialog::EditorFontButtonClick(TObject * /*Sender*/)
 void __fastcall TPreferencesDialog::FormCloseQuery(TObject * /*Sender*/,
   bool & /*CanClose*/)
 {
-  if (ModalResult != mrCancel)
+  if (ModalResult == DefaultResult(this))
   {
     ExitActiveControl(this);
   }
@@ -1901,7 +1908,11 @@ bool __fastcall TPreferencesDialog::CanSetMasterPassword()
 void __fastcall TPreferencesDialog::MasterPasswordChanged(
   UnicodeString Message, TStrings * RecryptPasswordErrors)
 {
-  Configuration->Save();
+  // Save master password.
+  // This is unlikely to fail, as storage is written explicitly already
+  // when writting the recrypted passwords
+  Configuration->SaveExplicit();
+
   if (RecryptPasswordErrors->Count > 0)
   {
     Message = FMTLOAD(MASTER_PASSWORD_RECRYPT_ERRORS, (Message));

+ 0 - 2083
source/forms/Preferences.cpp.LOCAL

@@ -1,2083 +0,0 @@
-//---------------------------------------------------------------------
-#include <vcl.h>
-#pragma hdrstop
-
-#include <StrUtils.hpp>
-#include <Common.h>
-#include <math.h>
-
-#include "Preferences.h"
-
-#include <CoreMain.h>
-#include <Terminal.h>
-#include <Bookmarks.h>
-
-#include "VCLCommon.h"
-#include "GUITools.h"
-#include "Tools.h"
-#include "TextsWin.h"
-#include "HelpWin.h"
-#include "WinInterface.h"
-#include "WinConfiguration.h"
-#include "Setup.h"
-//---------------------------------------------------------------------
-#pragma link "CopyParams"
-#pragma link "UpDownEdit"
-#pragma link "ComboEdit"
-#ifndef NO_RESOURCES
-#pragma link "HistoryComboBox"
-#pragma resource "*.dfm"
-#endif
-//---------------------------------------------------------------------
-bool __fastcall DoPreferencesDialog(TPreferencesMode APreferencesMode,
-  TPreferencesDialogData * DialogData)
-{
-  CALLSTACK;
-  bool Result;
-  TPreferencesDialog * PreferencesDialog =
-    new TPreferencesDialog(GetFormOwner(), APreferencesMode);
-  try
-  {
-    Result = PreferencesDialog->Execute(DialogData);
-  }
-  __finally
-  {
-    delete PreferencesDialog;
-  }
-  return Result;
-}
-//---------------------------------------------------------------------
-__fastcall TPreferencesDialog::TPreferencesDialog(
-  TComponent* AOwner, TPreferencesMode PreferencesMode)
-  : TForm(AOwner)
-{
-  SetCorrectFormParent(this);
-
-  FNoUpdate = 0;
-  FPreferencesMode = PreferencesMode;
-  FEditorFont = new TFont();
-  FEditorFont->Color = clWindowText;
-  // color tends to reset in object inspector
-  EditorFontLabel->Color = clWindow;
-  // currently useless
-  FAfterFilenameEditDialog = false;
-  FCustomCommandList = new TCustomCommandList();
-  FCustomCommandChanging = false;
-  FListViewDragDest = -1;
-  FCopyParamList = new TCopyParamList();
-  FEditorList = new TEditorList();
-  UseSystemSettings(this);
-
-  FCustomCommandsScrollOnDragOver = new TListViewScrollOnDragOver(CustomCommandsView, true);
-  FCopyParamScrollOnDragOver = new TListViewScrollOnDragOver(CopyParamListView, true);
-  FEditorScrollOnDragOver = new TListViewScrollOnDragOver(EditorListView3, true);
-
-  ComboAutoSwitchInitialize(UpdatesBetaVersionsCombo);
-  EnableControl(UpdatesBetaVersionsCombo, !WinConfiguration->IsBeta);
-  EnableControl(UpdatesBetaVersionsLabel, UpdatesBetaVersionsCombo->Enabled);
-
-  HintLabel(LogFileNameHintText, LoadStr(LOG_FILE_HINT3));
-  HintLabel(ActionsLogFileNameHintText, LoadStr(LOG_FILE_HINT3));
-
-  HintLabel(ShellIconsText2);
-  HotTrackLabel(CopyParamLabel);
-  HintLabel(PuttyPathHintText, LoadStr(PUTTY_PATTERNS_HINT));
-
-  EditorEncodingCombo->Items->Add(DefaultEncodingName());
-  EditorEncodingCombo->Items->Add(LoadStr(UTF8_NAME));
-
-  std::auto_ptr<TStrings> Workspaces(StoredSessions->GetWorkspaces());
-  AutoWorkspaceCombo->Items->AddStrings(Workspaces.get());
-  AutoSaveWorkspacePasswordsCheck->Caption = LoadStr(SAVE_WORKSPACE_PASSWORDS);
-
-  PuttyRegistryStorageKeyEdit->Items->Add(OriginalPuttyRegistryStorageKey);
-  PuttyRegistryStorageKeyEdit->Items->Add(KittyRegistryStorageKey);
-}
-//---------------------------------------------------------------------------
-__fastcall TPreferencesDialog::~TPreferencesDialog()
-{
-  SAFE_DESTROY(FEditorScrollOnDragOver);
-  SAFE_DESTROY(FCopyParamScrollOnDragOver);
-  SAFE_DESTROY(FCustomCommandsScrollOnDragOver);
-  delete FEditorFont;
-  delete FCustomCommandList;
-  delete FCopyParamList;
-  delete FEditorList;
-}
-//---------------------------------------------------------------------
-bool __fastcall TPreferencesDialog::Execute(TPreferencesDialogData * DialogData)
-{
-  PuttyPathEdit->Items = CustomWinConfiguration->History[L"PuttyPath"];
-  FDialogData = DialogData;
-  LoadConfiguration();
-  bool Result = (ShowModal() == mrOk);
-  if (Result)
-  {
-    SaveConfiguration();
-    CustomWinConfiguration->History[L"PuttyPath"] = PuttyPathEdit->Items;
-  }
-  return Result;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::LoadLanguages()
-{
-  CALLSTACK;
-  if (!FLanguagesLoaded)
-  {
-    LanguagesView->Items->Clear();
-
-    TStrings * Locales = GUIConfiguration->Locales;
-    for (int Index = 0; Index < Locales->Count; Index++)
-    {
-      TListItem * Item = LanguagesView->Items->Add();
-      Item->Caption = Locales->Strings[Index];
-      Item->Data = Locales->Objects[Index];
-      Item->Focused =
-        (reinterpret_cast<LCID>(Locales->Objects[Index]) == GUIConfiguration->Locale);
-      Item->Selected = Item->Focused;
-    }
-
-    FLanguagesLoaded = false;
-  }
-}
-//---------------------------------------------------------------------------
-TTabSheet * __fastcall TPreferencesDialog::FindPageForTreeNode(TTreeNode * Node)
-{
-  for (int pi = 0; pi < PageControl->PageCount; pi++)
-  {
-    TTabSheet * Sheet = PageControl->Pages[pi];
-    if (Sheet->Tag == Node->SelectedIndex)
-    {
-      return Sheet;
-    }
-  }
-  FAIL;
-  return NULL;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PrepareNavigationTree(TTreeView * Tree)
-{
-  Tree->FullExpand();
-  int i = 0;
-  while (i < Tree->Items->Count)
-  {
-    TTreeNode * Node = Tree->Items->Item[i];
-    TTabSheet * Sheet = FindPageForTreeNode(Node);
-    if (NOT_NULL(Sheet))
-    {
-      if (Sheet->Enabled)
-      {
-        // gets called multiple times occasionally
-        // (e.g. when called from upload dialog invoked by /upload)
-        if (!Sheet->Caption.IsEmpty())
-        {
-          Node->Text = Sheet->Caption;
-          Sheet->Caption = L"";
-        }
-      }
-      else
-      {
-        Tree->Items->Delete(Node);
-        i--;
-      }
-    }
-    i++;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::LoadConfiguration()
-{
-  FNoUpdate++;
-  try
-  {
-    #define BOOLPROP(PROP) PROP ## Check->Checked = WinConfiguration->PROP;
-    BOOLPROP(DefaultDirIsHome);
-    BOOLPROP(PreservePanelState);
-    BOOLPROP(DeleteToRecycleBin);
-    BOOLPROP(DDTransferConfirmation);
-    BOOLPROP(DDWarnLackOfTempSpace);
-    BOOLPROP(ShowHiddenFiles);
-    BOOLPROP(FormatSizeBytes);
-    BOOLPROP(RenameWholeName);
-    BOOLPROP(ShowInaccesibleDirectories);
-    BOOLPROP(CopyOnDoubleClickConfirmation);
-    BOOLPROP(ConfirmTransferring);
-    BOOLPROP(ConfirmOverwriting);
-    BOOLPROP(ConfirmResume);
-    BOOLPROP(ConfirmDeleting);
-    BOOLPROP(ConfirmRecycling);
-    BOOLPROP(ConfirmClosingSession);
-    BOOLPROP(ConfirmExitOnCompletion);
-    BOOLPROP(ConfirmCommandSession);
-    BOOLPROP(ContinueOnError);
-    BOOLPROP(DDAllowMoveInit);
-    BOOLPROP(BeepOnFinish);
-    BOOLPROP(TemporaryDirectoryAppendSession);
-    BOOLPROP(TemporaryDirectoryAppendPath);
-    BOOLPROP(TemporaryDirectoryCleanup);
-    BOOLPROP(ConfirmTemporaryDirectoryCleanup);
-    BOOLPROP(FullRowSelect);
-
-    if (WinConfiguration->DDTransferConfirmation == asAuto)
-    {
-      // allow greayed state only initially,
-      // once the off state is confirmed, never allow returning
-      // to the undefined state
-      DDTransferConfirmationCheck->AllowGrayed = true;
-    }
-    CheckBoxAutoSwitchLoad(DDTransferConfirmationCheck, WinConfiguration->DDTransferConfirmation);
-
-    BeepOnFinishAfterEdit->AsInteger =
-      int(static_cast<double>(GUIConfiguration->BeepOnFinishAfter) * SecsPerDay);
-    BOOLPROP(BalloonNotifications);
-
-    DDExtEnabledButton->Checked = WinConfiguration->DDExtEnabled;
-    DDExtDisabledButton->Checked = !DDExtEnabledButton->Checked;
-    DDWarnOnMoveCheck->Checked = !WinConfiguration->DDAllowMove;
-
-    if (WinConfiguration->DDTemporaryDirectory.IsEmpty())
-    {
-      DDSystemTemporaryDirectoryButton->Checked = true;
-      DDTemporaryDirectoryEdit->Text = SystemTemporaryDirectory();
-    }
-    else
-    {
-      DDCustomTemporaryDirectoryButton->Checked = true;
-      DDTemporaryDirectoryEdit->Text = WinConfiguration->DDTemporaryDirectory;
-    }
-
-    // Commander
-    if (WinConfiguration->ScpCommander.NortonLikeMode == nlOff)
-    {
-      NortonLikeModeCombo->ItemIndex = 2;
-    }
-    else if (WinConfiguration->ScpCommander.NortonLikeMode == nlKeyboard)
-    {
-      NortonLikeModeCombo->ItemIndex = 1;
-    }
-    else
-    {
-      NortonLikeModeCombo->ItemIndex = 0;
-    }
-
-    SwappedPanelsCheck->Checked =
-      WinConfiguration->ScpCommander.SwappedPanels;
-    TreeOnLeftCheck->Checked = WinConfiguration->ScpCommander.TreeOnLeft;
-
-    ExplorerKeyboardShortcutsCombo->ItemIndex =
-      WinConfiguration->ScpCommander.ExplorerKeyboardShortcuts ? 1 : 0;
-    BOOLPROP(UseLocationProfiles);
-
-    CompareByTimeCheck->Checked = WinConfiguration->ScpCommander.CompareByTime;
-    CompareBySizeCheck->Checked = WinConfiguration->ScpCommander.CompareBySize;
-
-    // Local panel
-    PreserveLocalDirectoryCheck->Checked =
-      WinConfiguration->ScpCommander.PreserveLocalDirectory;
-    SystemContextMenuCheck->Checked =
-      WinConfiguration->ScpCommander.SystemContextMenu;
-
-    // Explorer
-    ShowFullAddressCheck->Checked =
-      WinConfiguration->ScpExplorer.ShowFullAddress;
-
-    RegistryStorageButton->Checked = (Configuration->Storage == stRegistry);
-    IniFileStorageButton2->Checked = (Configuration->Storage != stRegistry);
-
-    RandomSeedFileEdit->Text = Configuration->RandomSeedFile;
-
-    // editor
-    EditorWordWrapCheck->Checked = WinConfiguration->Editor.WordWrap;
-    EditorTabSizeEdit->AsInteger = WinConfiguration->Editor.TabSize;
-    if (WinConfiguration->Editor.Encoding == CP_UTF8)
-    {
-      EditorEncodingCombo->ItemIndex = 1;
-    }
-    else
-    {
-      EditorEncodingCombo->ItemIndex = 0;
-    }
-    FEditorFont->Name = WinConfiguration->Editor.FontName;
-    FEditorFont->Height = WinConfiguration->Editor.FontHeight;
-    FEditorFont->Charset = (TFontCharset)WinConfiguration->Editor.FontCharset;
-    FEditorFont->Style = IntToFontStyles(WinConfiguration->Editor.FontStyle);
-    (*FEditorList) = *WinConfiguration->EditorList;
-    UpdateEditorListView();
-
-    FCopyParams = GUIConfiguration->DefaultCopyParam;
-    ResumeOnButton->Checked = GUIConfiguration->DefaultCopyParam.ResumeSupport == rsOn;
-    ResumeSmartButton->Checked = GUIConfiguration->DefaultCopyParam.ResumeSupport == rsSmart;
-    ResumeOffButton->Checked = GUIConfiguration->DefaultCopyParam.ResumeSupport == rsOff;
-    ResumeThresholdEdit->Value = GUIConfiguration->DefaultCopyParam.ResumeThreshold / 1024;
-    SessionReopenAutoCheck->Checked = (Configuration->SessionReopenAuto > 0);
-    SessionReopenAutoEdit->Value = (Configuration->SessionReopenAuto > 0 ?
-      (Configuration->SessionReopenAuto / MSecsPerSec) : 5);
-    SessionReopenAutoIdleCheck->Checked = (GUIConfiguration->SessionReopenAutoIdle > 0);
-    SessionReopenAutoIdleEdit->Value = (GUIConfiguration->SessionReopenAutoIdle > 0 ?
-      (GUIConfiguration->SessionReopenAutoIdle / MSecsPerSec) : 5);
-    SessionReopenAutoStallCheck->Checked = (Configuration->SessionReopenAutoStall > 0);
-    SessionReopenAutoStallEdit->Value = (Configuration->SessionReopenAutoStall > 0 ?
-      (Configuration->SessionReopenAutoStall / MSecsPerSec) : SecsPerMin);
-    SessionReopenTimeoutEdit->Value = (Configuration->SessionReopenTimeout / MSecsPerSec);
-
-    GeneralSheet->Enabled = WinConfiguration->ExpertMode;
-    ExplorerSheet->Enabled = WinConfiguration->ExpertMode;
-    CommanderSheet->Enabled = WinConfiguration->ExpertMode;
-    EditorSheet->Enabled = WinConfiguration->ExpertMode && !WinConfiguration->DisableOpenEdit;
-
-    StorageGroup->Visible = WinConfiguration->ExpertMode;
-    RandomSeedFileLabel->Visible = WinConfiguration->ExpertMode;
-    RandomSeedFileEdit->Visible = WinConfiguration->ExpertMode;
-
-    FCustomCommandList->Assign(WinConfiguration->CustomCommandList);
-    UpdateCustomCommandsView();
-
-    PuttyPathEdit->Text = GUIConfiguration->PuttyPath;
-    PuttyPasswordCheck2->Checked = GUIConfiguration->PuttyPassword;
-    AutoOpenInPuttyCheck->Checked = WinConfiguration->AutoOpenInPutty;
-    TelnetForFtpInPuttyCheck->Checked = WinConfiguration->TelnetForFtpInPutty;
-    SelectPuttyRegistryStorageKey(GUIConfiguration->PuttyRegistryStorageKey);
-
-    // Queue
-    QueueTransferLimitEdit->AsInteger = GUIConfiguration->QueueTransfersLimit;
-    EnableQueueByDefaultCheck->Checked = WinConfiguration->EnableQueueByDefault;
-    QueueAutoPopupCheck->Checked = GUIConfiguration->QueueAutoPopup;
-    QueueCheck->Checked = GUIConfiguration->DefaultCopyParam.Queue;
-    QueueIndividuallyCheck->Checked = GUIConfiguration->DefaultCopyParam.QueueIndividually;
-    QueueNoConfirmationCheck->Checked = GUIConfiguration->DefaultCopyParam.QueueNoConfirmation;
-    if (!GUIConfiguration->QueueKeepDoneItems)
-    {
-      QueueKeepDoneItemsForCombo->ItemIndex = 0;
-    }
-    else if (GUIConfiguration->QueueKeepDoneItemsFor < 0)
-    {
-      QueueKeepDoneItemsForCombo->ItemIndex = 5;
-    }
-    else if (GUIConfiguration->QueueKeepDoneItemsFor <= 15)
-    {
-      QueueKeepDoneItemsForCombo->ItemIndex = 1;
-    }
-    else if (GUIConfiguration->QueueKeepDoneItemsFor <= 60)
-    {
-      QueueKeepDoneItemsForCombo->ItemIndex = 2;
-    }
-    else if (GUIConfiguration->QueueKeepDoneItemsFor <= 15 * 60)
-    {
-      QueueKeepDoneItemsForCombo->ItemIndex = 3;
-    }
-    else if (GUIConfiguration->QueueKeepDoneItemsFor <= 60 * 60)
-    {
-      QueueKeepDoneItemsForCombo->ItemIndex = 4;
-    }
-    if (WinConfiguration->QueueView.Show == qvShow)
-    {
-      QueueViewShowButton->Checked = true;
-    }
-    else if (WinConfiguration->QueueView.Show == qvHideWhenEmpty)
-    {
-      QueueViewHideWhenEmptyButton->Checked = true;
-    }
-    else
-    {
-      QueueViewHideButton->Checked = true;
-    }
-
-    // window
-    AutoSaveWorkspaceCheck->Checked = WinConfiguration->AutoSaveWorkspace;
-    AutoWorkspaceCombo->Text =
-      (WinConfiguration->AutoWorkspace.IsEmpty() ?
-        WinConfiguration->LastWorkspace : WinConfiguration->AutoWorkspace);
-    AutoSaveWorkspacePasswordsCheck->Checked = WinConfiguration->AutoSaveWorkspacePasswords;
-    if (WinConfiguration->PathInCaption == picFull)
-    {
-      PathInCaptionFullButton->Checked = true;
-    }
-    else if (WinConfiguration->PathInCaption == picShort)
-    {
-      PathInCaptionShortButton->Checked = true;
-    }
-    else
-    {
-      PathInCaptionNoneButton->Checked = true;
-    }
-    BOOLPROP(MinimizeToTray);
-
-    // panels
-    DoubleClickActionCombo->ItemIndex = WinConfiguration->DoubleClickAction;
-    BOOLPROP(AutoReadDirectoryAfterOp);
-    BOOLPROP(RefreshRemotePanel);
-    RefreshRemotePanelIntervalEdit->Value =
-      int(static_cast<double>(WinConfiguration->RefreshRemotePanelInterval) * SecsPerDay);
-
-    // updates
-    TUpdatesConfiguration Updates = WinConfiguration->Updates;
-    if (int(Updates.Period) <= 0)
-    {
-      UpdatesPeriodCombo->ItemIndex = 0;
-    }
-    else if (int(Updates.Period) <= 1)
-    {
-      UpdatesPeriodCombo->ItemIndex = 1;
-    }
-    else if (int(Updates.Period) <= 7)
-    {
-      UpdatesPeriodCombo->ItemIndex = 2;
-    }
-    else
-    {
-      UpdatesPeriodCombo->ItemIndex = 3;
-    }
-
-    CollectUsageCheck->Checked = Configuration->CollectUsage;
-
-    ComboAutoSwitchLoad(UpdatesBetaVersionsCombo, Updates.BetaVersions);
-
-    switch (Updates.ConnectionType)
-    {
-      case ctDirect:
-      default:
-        UpdatesDirectCheck->Checked = true;
-        break;
-
-      case ctAuto:
-        UpdatesAutoCheck->Checked = true;
-        break;
-
-      case ctProxy:
-        UpdatesProxyCheck->Checked = true;
-        break;
-    }
-
-    UpdatesProxyHostEdit->Text = Updates.ProxyHost;
-    UpdatesProxyPortEdit->AsInteger = Updates.ProxyPort;
-
-    // presets
-    (*FCopyParamList) = *WinConfiguration->CopyParamList;
-    UpdateCopyParamListView();
-    CopyParamListView->ItemIndex = 0;
-    BOOLPROP(CopyParamAutoSelectNotice);
-
-    // interface
-    switch (CustomWinConfiguration->Interface)
-    {
-      case ifCommander:
-        CommanderInterfaceButton2->Checked = true;
-        break;
-
-      case ifExplorer:
-        ExplorerInterfaceButton2->Checked = true;
-        break;
-
-      default:
-        FAIL;
-        break;
-    }
-
-    if (WinConfiguration->Theme == L"OfficeXP")
-    {
-      ThemeCombo->ItemIndex = 1;
-    }
-    else if (WinConfiguration->Theme == L"Office2003")
-    {
-      ThemeCombo->ItemIndex = 2;
-    }
-    else
-    {
-      ThemeCombo->ItemIndex = 0;
-    }
-
-    // security
-    UseMasterPasswordCheck->Checked = WinConfiguration->UseMasterPassword;
-    SessionRememberPasswordCheck->Checked = GUIConfiguration->SessionRememberPassword;
-
-    // network
-    RetrieveExternalIpAddressButton->Checked = Configuration->ExternalIpAddress.IsEmpty();
-    CustomExternalIpAddressButton->Checked = !RetrieveExternalIpAddressButton->Checked;
-    CustomExternalIpAddressEdit->Text = Configuration->ExternalIpAddress;
-    TryFtpWhenSshFailsCheck->Checked = Configuration->TryFtpWhenSshFails;
-
-    // logging
-    EnableLoggingCheck->Checked = Configuration->Logging;
-    LogProtocolCombo->ItemIndex = Configuration->LogProtocol;
-    LogToFileCheck->Checked = Configuration->LogToFile;
-    LogFileNameEdit3->Text =
-      !Configuration->LogFileName.IsEmpty() ? Configuration->LogFileName : Configuration->DefaultLogFileName;
-    if (Configuration->LogFileAppend)
-    {
-      LogFileAppendButton->Checked = true;
-    }
-    else
-    {
-      LogFileOverwriteButton->Checked = true;
-    }
-    LogShowWindowCheck->Checked = (CustomWinConfiguration->LogView == lvWindow);
-    if (Configuration->LogWindowComplete)
-    {
-      LogWindowCompleteButton->Checked = true;
-    }
-    else
-    {
-      LogWindowLinesButton->Checked = true;
-    }
-
-    if (!Configuration->LogWindowComplete)
-    {
-      LogWindowLinesEdit->AsInteger = Configuration->LogWindowLines;
-    }
-    else
-    {
-      LogWindowLinesEdit->AsInteger = 500;
-    }
-
-    EnableActionsLoggingCheck->Checked = Configuration->LogActions;
-    ActionsLogFileNameEdit->Text = Configuration->ActionsLogFileName;
-
-    #undef BOOLPROP
-  }
-  __finally
-  {
-    FNoUpdate--;
-  }
-
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::SaveConfiguration()
-{
-  Configuration->BeginUpdate();
-  try
-  {
-    TGUICopyParamType CopyParam = GUIConfiguration->DefaultCopyParam;
-
-    #define BOOLPROP(PROP) WinConfiguration->PROP = PROP ## Check->Checked
-    BOOLPROP(DefaultDirIsHome);
-    BOOLPROP(PreservePanelState);
-    BOOLPROP(DeleteToRecycleBin);
-    BOOLPROP(DDWarnLackOfTempSpace);
-    BOOLPROP(ShowHiddenFiles);
-    BOOLPROP(FormatSizeBytes);
-    BOOLPROP(RenameWholeName);
-    BOOLPROP(ShowInaccesibleDirectories);
-    BOOLPROP(CopyOnDoubleClickConfirmation);
-    BOOLPROP(ConfirmTransferring);
-    BOOLPROP(ConfirmOverwriting);
-    BOOLPROP(ConfirmResume);
-    BOOLPROP(ConfirmDeleting);
-    BOOLPROP(ConfirmRecycling);
-    BOOLPROP(ConfirmClosingSession);
-    BOOLPROP(ConfirmExitOnCompletion);
-    BOOLPROP(ConfirmCommandSession);
-    BOOLPROP(ContinueOnError);
-    BOOLPROP(DDAllowMoveInit);
-    BOOLPROP(BeepOnFinish);
-    BOOLPROP(TemporaryDirectoryAppendSession);
-    BOOLPROP(TemporaryDirectoryAppendPath);
-    BOOLPROP(TemporaryDirectoryCleanup);
-    BOOLPROP(ConfirmTemporaryDirectoryCleanup);
-    BOOLPROP(FullRowSelect);
-
-    WinConfiguration->DDTransferConfirmation =
-      CheckBoxAutoSwitchSave(DDTransferConfirmationCheck);
-
-    GUIConfiguration->BeepOnFinishAfter =
-      static_cast<double>(BeepOnFinishAfterEdit->Value / SecsPerDay);
-    BOOLPROP(BalloonNotifications);
-
-    WinConfiguration->DDAllowMove = !DDWarnOnMoveCheck->Checked;
-    WinConfiguration->DDExtEnabled = DDExtEnabledButton->Checked;
-
-    if (DDSystemTemporaryDirectoryButton->Checked)
-    {
-      WinConfiguration->DDTemporaryDirectory = L"";
-    }
-    else
-    {
-      WinConfiguration->DDTemporaryDirectory = DDTemporaryDirectoryEdit->Text;
-    }
-
-    Configuration->Storage = RegistryStorageButton->Checked ? stRegistry : stIniFile;
-
-    // Commander
-    TScpCommanderConfiguration ScpCommander = WinConfiguration->ScpCommander;
-    if (NortonLikeModeCombo->ItemIndex == 2)
-    {
-      ScpCommander.NortonLikeMode = nlOff;
-    }
-    else if (NortonLikeModeCombo->ItemIndex == 1)
-    {
-      ScpCommander.NortonLikeMode = nlKeyboard;
-    }
-    else
-    {
-      ScpCommander.NortonLikeMode = nlOn;
-    }
-    ScpCommander.SwappedPanels = SwappedPanelsCheck->Checked;
-    ScpCommander.TreeOnLeft = TreeOnLeftCheck->Checked;
-
-    ScpCommander.ExplorerKeyboardShortcuts =
-      (ExplorerKeyboardShortcutsCombo->ItemIndex != 0);
-    BOOLPROP(UseLocationProfiles);
-
-    WinConfiguration->ScpCommander.CompareByTime = CompareByTimeCheck->Checked;
-    WinConfiguration->ScpCommander.CompareBySize = CompareBySizeCheck->Checked;
-
-    // Local panel
-    ScpCommander.PreserveLocalDirectory = PreserveLocalDirectoryCheck->Checked;
-    ScpCommander.SystemContextMenu = SystemContextMenuCheck->Checked;
-
-    WinConfiguration->ScpCommander = ScpCommander;
-
-    // Explorer
-    TScpExplorerConfiguration ScpExplorer = WinConfiguration->ScpExplorer;
-    ScpExplorer.ShowFullAddress = ShowFullAddressCheck->Checked;
-    WinConfiguration->ScpExplorer = ScpExplorer;
-
-    Configuration->RandomSeedFile = RandomSeedFileEdit->Text;
-
-    // editor
-    WinConfiguration->Editor.WordWrap = EditorWordWrapCheck->Checked;
-    WinConfiguration->Editor.TabSize = EditorTabSizeEdit->AsInteger;
-    switch (EditorEncodingCombo->ItemIndex)
-    {
-      case 1:
-        WinConfiguration->Editor.Encoding = CP_UTF8;
-        break;
-
-      default:
-        WinConfiguration->Editor.Encoding = CP_ACP;
-        break;
-    }
-    WinConfiguration->Editor.FontName = FEditorFont->Name;
-    WinConfiguration->Editor.FontHeight = FEditorFont->Height;
-    WinConfiguration->Editor.FontCharset = FEditorFont->Charset;
-    WinConfiguration->Editor.FontStyle = FontStylesToInt(FEditorFont->Style);
-    WinConfiguration->EditorList = FEditorList;
-
-    // overwrites only TCopyParamType fields
-    CopyParam = FCopyParams;
-    if (ResumeOnButton->Checked) CopyParam.ResumeSupport = rsOn;
-    if (ResumeSmartButton->Checked) CopyParam.ResumeSupport = rsSmart;
-    if (ResumeOffButton->Checked) CopyParam.ResumeSupport = rsOff;
-    CopyParam.ResumeThreshold = ResumeThresholdEdit->AsInteger * 1024;
-
-    Configuration->SessionReopenAuto =
-      (SessionReopenAutoCheck->Checked ? (SessionReopenAutoEdit->AsInteger * MSecsPerSec) : 0);
-    GUIConfiguration->SessionReopenAutoIdle =
-      (SessionReopenAutoIdleCheck->Checked ? (SessionReopenAutoIdleEdit->AsInteger * MSecsPerSec) : 0);
-    Configuration->SessionReopenAutoStall =
-      (SessionReopenAutoStallCheck->Checked ? (SessionReopenAutoStallEdit->AsInteger * MSecsPerSec) : 0);
-    Configuration->SessionReopenTimeout = (SessionReopenTimeoutEdit->AsInteger * MSecsPerSec);
-
-    WinConfiguration->CustomCommandList = FCustomCommandList;
-
-    GUIConfiguration->PuttyPath = PuttyPathEdit->Text;
-    GUIConfiguration->PuttyPassword = PuttyPasswordCheck2->Checked;
-    WinConfiguration->AutoOpenInPutty = AutoOpenInPuttyCheck->Checked;
-    WinConfiguration->TelnetForFtpInPutty = TelnetForFtpInPuttyCheck->Checked;
-    // do not overwrite custom keys
-    if (PuttyRegistryStorageKeyEdit->ItemIndex >= 0)
-    {
-      GUIConfiguration->PuttyRegistryStorageKey = PuttyRegistryStorageKeyEdit->Text;
-    }
-
-    // Queue
-    GUIConfiguration->QueueTransfersLimit = QueueTransferLimitEdit->AsInteger;
-    WinConfiguration->EnableQueueByDefault = EnableQueueByDefaultCheck->Checked;
-    GUIConfiguration->QueueAutoPopup = QueueAutoPopupCheck->Checked;
-    CopyParam.Queue = QueueCheck->Checked;
-    CopyParam.QueueIndividually = QueueIndividuallyCheck->Checked;
-    CopyParam.QueueNoConfirmation = QueueNoConfirmationCheck->Checked;
-    GUIConfiguration->QueueKeepDoneItems = (QueueKeepDoneItemsForCombo->ItemIndex != 0);
-    switch (QueueKeepDoneItemsForCombo->ItemIndex)
-    {
-      case 0:
-        GUIConfiguration->QueueKeepDoneItemsFor = 0;
-        break;
-      case 1:
-        GUIConfiguration->QueueKeepDoneItemsFor = 15;
-        break;
-      case 2:
-        GUIConfiguration->QueueKeepDoneItemsFor = 60;
-        break;
-      case 3:
-        GUIConfiguration->QueueKeepDoneItemsFor = 15 * 60;
-        break;
-      case 4:
-        GUIConfiguration->QueueKeepDoneItemsFor = 60 * 60;
-        break;
-      default:
-        GUIConfiguration->QueueKeepDoneItemsFor = -1;
-        break;
-    }
-    if (QueueViewShowButton->Checked)
-    {
-      WinConfiguration->QueueView.Show = qvShow;
-    }
-    else if (QueueViewHideWhenEmptyButton->Checked)
-    {
-      WinConfiguration->QueueView.Show = qvHideWhenEmpty;
-    }
-    else
-    {
-      WinConfiguration->QueueView.Show = qvHide;
-    }
-
-    GUIConfiguration->DefaultCopyParam = CopyParam;
-
-    // window
-    WinConfiguration->AutoSaveWorkspace =
-      !AutoWorkspaceCombo->Text.IsEmpty() &&
-      AutoSaveWorkspaceCheck->Checked;
-    if (!AutoWorkspaceCombo->Text.IsEmpty())
-    {
-      WinConfiguration->AutoWorkspace = AutoWorkspaceCombo->Text;
-    }
-    WinConfiguration->AutoSaveWorkspacePasswords = AutoSaveWorkspacePasswordsCheck->Checked;
-    if (PathInCaptionFullButton->Checked)
-    {
-       WinConfiguration->PathInCaption = picFull;
-    }
-    else if (PathInCaptionShortButton->Checked)
-    {
-      WinConfiguration->PathInCaption = picShort;
-    }
-    else
-    {
-      WinConfiguration->PathInCaption = picNone;
-    }
-    BOOLPROP(MinimizeToTray);
-
-    // panels
-    WinConfiguration->DoubleClickAction = (TDoubleClickAction)DoubleClickActionCombo->ItemIndex;
-    BOOLPROP(AutoReadDirectoryAfterOp);
-    BOOLPROP(RefreshRemotePanel);
-    WinConfiguration->RefreshRemotePanelInterval =
-      static_cast<double>(RefreshRemotePanelIntervalEdit->Value / SecsPerDay);
-
-    // updates
-    TUpdatesConfiguration Updates = WinConfiguration->Updates;
-    if (UpdatesPeriodCombo->ItemIndex == 0)
-    {
-      Updates.Period = 0;
-    }
-    else if (UpdatesPeriodCombo->ItemIndex == 1)
-    {
-      Updates.Period = 1;
-    }
-    else if (UpdatesPeriodCombo->ItemIndex == 2)
-    {
-      Updates.Period = 7;
-    }
-    else
-    {
-      Updates.Period = 30;
-    }
-
-    Configuration->CollectUsage = CollectUsageCheck->Checked;
-
-    Updates.BetaVersions = ComboAutoSwitchSave(UpdatesBetaVersionsCombo);
-
-    if (UpdatesDirectCheck->Checked)
-    {
-      Updates.ConnectionType = ctDirect;
-    }
-    else if (UpdatesAutoCheck->Checked)
-    {
-      Updates.ConnectionType = ctAuto;
-    }
-    else if (UpdatesProxyCheck->Checked)
-    {
-      if (!UpdatesProxyHostEdit->Text.IsEmpty())
-      {
-        Updates.ConnectionType = ctProxy;
-      }
-      else
-      {
-        Updates.ConnectionType = ctDirect;
-      }
-    }
-    Updates.ProxyHost = UpdatesProxyHostEdit->Text;
-    Updates.ProxyPort = UpdatesProxyPortEdit->AsInteger;
-
-    WinConfiguration->Updates = Updates;
-
-    // presets
-    WinConfiguration->CopyParamList = FCopyParamList;
-    BOOLPROP(CopyParamAutoSelectNotice);
-
-    // interface
-    if (GetInterface() != CustomWinConfiguration->Interface)
-    {
-      Configuration->Usage->Inc(L"InterfaceChanges");
-    }
-    CustomWinConfiguration->Interface = GetInterface();
-
-    if (ThemeCombo->ItemIndex == 1)
-    {
-      WinConfiguration->Theme = L"OfficeXP";
-    }
-    else if (ThemeCombo->ItemIndex == 2)
-    {
-      WinConfiguration->Theme = L"Office2003";
-    }
-    else
-    {
-      WinConfiguration->Theme = L"Default";
-    }
-
-    // network
-    Configuration->ExternalIpAddress =
-      (CustomExternalIpAddressButton->Checked ? CustomExternalIpAddressEdit->Text : UnicodeString());
-    Configuration->TryFtpWhenSshFails = TryFtpWhenSshFailsCheck->Checked;
-
-    // security
-    GUIConfiguration->SessionRememberPassword = SessionRememberPasswordCheck->Checked;
-
-    // languages
-    if (LanguagesView->ItemFocused != NULL)
-    {
-      GUIConfiguration->Locale =
-        reinterpret_cast<LCID>(LanguagesView->ItemFocused->Data);
-    }
-
-    // logging
-    Configuration->Logging = EnableLoggingCheck->Checked;
-    Configuration->LogProtocol = LogProtocolCombo->ItemIndex;
-    Configuration->LogFileName = LogToFileCheck->Checked ? LogFileNameEdit3->Text : UnicodeString();
-    Configuration->LogFileAppend = LogFileAppendButton->Checked;
-    CustomWinConfiguration->LogView = LogShowWindowCheck->Checked ? lvWindow : lvNone;
-    Configuration->LogWindowComplete = LogWindowCompleteButton->Checked;
-    if (!LogWindowCompleteButton->Checked)
-    {
-      Configuration->LogWindowLines = LogWindowLinesEdit->AsInteger;
-    }
-
-    Configuration->LogActions = EnableActionsLoggingCheck->Checked;
-    Configuration->ActionsLogFileName = ActionsLogFileNameEdit->Text;
-
-    #undef BOOLPROP
-  }
-  __finally
-  {
-    Configuration->EndUpdate();
-  }
-}
-//---------------------------------------------------------------------------
-TInterface __fastcall TPreferencesDialog::GetInterface()
-{
-  return CommanderInterfaceButton2->Checked ? ifCommander : ifExplorer;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::FormShow(TObject * /*Sender*/)
-{
-  InstallPathWordBreakProc(RandomSeedFileEdit);
-  InstallPathWordBreakProc(DDTemporaryDirectoryEdit);
-  InstallPathWordBreakProc(PuttyPathEdit);
-  InstallPathWordBreakProc(LogFileNameEdit3);
-  InstallPathWordBreakProc(ActionsLogFileNameEdit);
-
-  PrepareNavigationTree(NavigationTree);
-
-  switch (FPreferencesMode) {
-    case pmEditor: PageControl->ActivePage = EditorSheet; break;
-    case pmCustomCommands: PageControl->ActivePage = CustomCommandsSheet; break;
-    case pmQueue: PageControl->ActivePage = QueueSheet; break;
-    case pmLogging: PageControl->ActivePage = LogSheet; break;
-    case pmUpdates: PageControl->ActivePage = UpdatesSheet; break;
-    case pmPresets: PageControl->ActivePage = CopyParamListSheet; break;
-    case pmEditors: PageControl->ActivePage = EditorSheet; break;
-    default: PageControl->ActivePage = PreferencesSheet; break;
-  }
-  PageControlChange(NULL);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ControlChange(TObject * /*Sender*/)
-{
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-UnicodeString __fastcall TPreferencesDialog::TabSample(UnicodeString Values)
-{
-  UnicodeString Result;
-  for (int Index = 1; Index <= Values.Length(); Index++)
-  {
-    if (Index > 1)
-    {
-      Result += L' ';
-      if (EditorTabSizeEdit->AsInteger > 2)
-      {
-        Result += UnicodeString::StringOfChar(L' ', EditorTabSizeEdit->AsInteger - 2);
-      }
-    }
-
-    Result += Values[Index];
-  }
-  return Result;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpdateControls()
-{
-  if (FNoUpdate == 0)
-  {
-    EnableControl(BeepOnFinishAfterEdit, BeepOnFinishCheck->Checked);
-    EnableControl(BeepOnFinishAfterText, BeepOnFinishCheck->Checked);
-    EnableControl(BalloonNotificationsCheck, ::TTrayIcon::SupportsBalloons());
-
-    EnableControl(ResumeThresholdEdit, ResumeSmartButton->Checked);
-    EnableControl(ResumeThresholdUnitLabel, ResumeThresholdEdit->Enabled);
-    EnableControl(SessionReopenAutoEdit, SessionReopenAutoCheck->Checked);
-    EnableControl(SessionReopenAutoLabel, SessionReopenAutoEdit->Enabled);
-    EnableControl(SessionReopenAutoSecLabel, SessionReopenAutoEdit->Enabled);
-    EnableControl(SessionReopenAutoIdleEdit, SessionReopenAutoIdleCheck->Checked);
-    EnableControl(SessionReopenAutoIdleLabel, SessionReopenAutoIdleEdit->Enabled);
-    EnableControl(SessionReopenAutoIdleSecLabel, SessionReopenAutoIdleEdit->Enabled);
-    EnableControl(SessionReopenAutoStallEdit, SessionReopenAutoStallCheck->Checked);
-    EnableControl(SessionReopenAutoStallLabel, SessionReopenAutoStallEdit->Enabled);
-    EnableControl(SessionReopenAutoStallSecLabel, SessionReopenAutoStallEdit->Enabled);
-    EnableControl(SessionReopenTimeoutEdit,
-      SessionReopenAutoEdit->Enabled || SessionReopenAutoStallCheck->Checked);
-    EnableControl(SessionReopenTimeoutLabel, SessionReopenTimeoutEdit->Enabled);
-    EnableControl(SessionReopenTimeoutSecLabel,SessionReopenTimeoutEdit->Enabled);
-
-    EnableControl(CopyOnDoubleClickConfirmationCheck,
-      (DoubleClickActionCombo->ItemIndex == 1) && ConfirmTransferringCheck->Checked);
-    EnableControl(RefreshRemotePanelIntervalEdit, RefreshRemotePanelCheck->Checked);
-    EnableControl(RefreshRemoteDirectoryUnitLabel, RefreshRemotePanelCheck->Checked);
-
-    UnicodeString EditorFontLabelText;
-    EditorFontLabelText = FMTLOAD(EDITOR_FONT_FMT,
-      (FEditorFont->Name, FEditorFont->Size)) + L"\n\n";
-    EditorFontLabelText += TabSample(L"ABCD") + L"\n";
-    EditorFontLabelText += TabSample(L"1234");
-    EditorFontLabel->Caption = EditorFontLabelText;
-    EditorFontLabel->Font = FEditorFont;
-
-    bool CommandSelected = (CustomCommandsView->Selected != NULL);
-    EnableControl(EditCommandButton, CommandSelected);
-    EnableControl(RemoveCommandButton, CommandSelected);
-    EnableControl(UpCommandButton, CommandSelected &&
-      CustomCommandsView->ItemIndex > 0);
-    EnableControl(DownCommandButton, CommandSelected &&
-      (CustomCommandsView->ItemIndex < CustomCommandsView->Items->Count - 1));
-
-    bool CopyParamSelected = (CopyParamListView->Selected != NULL);
-    EnableControl(EditCopyParamButton, CopyParamSelected);
-    EnableControl(DuplicateCopyParamButton,
-      CopyParamSelected && (CopyParamListView->ItemIndex >= 1));
-    EnableControl(RemoveCopyParamButton,
-      CopyParamSelected && (CopyParamListView->ItemIndex >= 1));
-    EnableControl(UpCopyParamButton,
-      CopyParamSelected && (CopyParamListView->ItemIndex > 1));
-    EnableControl(DownCopyParamButton,
-      CopyParamSelected &&
-      (CopyParamListView->ItemIndex >= 1) &&
-      (CopyParamListView->ItemIndex < CopyParamListView->Items->Count - 1));
-    EnableControl(CopyParamAutoSelectNoticeCheck, FCopyParamList->AnyRule);
-
-    UnicodeString InfoStr;
-    if (CopyParamSelected)
-    {
-      const TCopyParamType * SelectedCopyParam = GetCopyParam(CopyParamListView->ItemIndex);
-      InfoStr = SelectedCopyParam->GetInfoStr(L"; ", 0);
-      if (CopyParamListView->ItemIndex >= 1)
-      {
-        const TCopyParamRule * Rule = FCopyParamList->Rules[CopyParamListView->ItemIndex - 1];
-        if (Rule != NULL)
-        {
-          InfoStr += L"\n" + FORMAT(ReplaceStr(LoadStr(COPY_PARAM_RULE), L"\n", L" "), (Rule->GetInfoStr(L"; ")));
-        }
-      }
-    }
-    CopyParamLabel->Caption = InfoStr;
-    CopyParamLabel->Hint = InfoStr;
-    CopyParamLabel->ShowHint =
-      (CopyParamLabel->Canvas->TextWidth(InfoStr) > (CopyParamLabel->Width * 3 / 2));
-
-    EnableControl(DDExtEnabledButton, WinConfiguration->DDExtInstalled);
-    EnableControl(DDExtEnabledLabel, WinConfiguration->DDExtInstalled);
-    EnableControl(DDExtDisabledPanel, DDExtDisabledButton->Checked);
-    EnableControl(DDTemporaryDirectoryEdit, DDCustomTemporaryDirectoryButton->Enabled &&
-      DDCustomTemporaryDirectoryButton->Checked);
-    EnableControl(DDWarnOnMoveCheck, DDExtDisabledButton->Checked &&
-      DDAllowMoveInitCheck->Checked);
-    EnableControl(ConfirmTemporaryDirectoryCleanupCheck,
-      TemporaryDirectoryCleanupCheck->Checked);
-    IniFileStorageButton2->Caption =
-      AnsiReplaceStr(IniFileStorageButton2->Caption, L"winscp.ini",
-        ExtractFileName(ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading)));
-
-    EditorFontLabel->WordWrap = EditorWordWrapCheck->Checked;
-    bool EditorSelected = (EditorListView3->Selected != NULL);
-    EnableControl(EditEditorButton, EditorSelected);
-    EnableControl(RemoveEditorButton, EditorSelected);
-    EnableControl(UpEditorButton, EditorSelected &&
-      (EditorListView3->ItemIndex > 0));
-    EnableControl(DownEditorButton, EditorSelected &&
-      (EditorListView3->ItemIndex < EditorListView3->Items->Count - 1));
-
-    EnableControl(UsageViewButton, CollectUsageCheck->Checked);
-    EnableControl(UpdatesProxyHostEdit, UpdatesProxyCheck->Checked);
-    EnableControl(UpdatesProxyHostLabel, UpdatesProxyHostEdit->Enabled);
-    EnableControl(UpdatesProxyPortEdit, UpdatesProxyCheck->Checked);
-    EnableControl(UpdatesProxyPortLabel, UpdatesProxyPortEdit->Enabled);
-
-    bool IsSiteCommand = false;
-    try
-    {
-      TRemoteCustomCommand RemoteCustomCommand;
-      TInteractiveCustomCommand InteractiveCustomCommand(&RemoteCustomCommand);
-      UnicodeString PuttyPath = PuttyPathEdit->Text;
-      PuttyPath = InteractiveCustomCommand.Complete(PuttyPath, false);
-      IsSiteCommand = RemoteCustomCommand.IsSiteCommand(PuttyPath);
-    }
-    catch (...)
-    {
-      // noop
-    }
-    EnableControl(PuttyPasswordCheck2, !PuttyPathEdit->Text.IsEmpty());
-    EnableControl(AutoOpenInPuttyCheck, PuttyPasswordCheck2->Enabled);
-    EnableControl(TelnetForFtpInPuttyCheck,
-      PuttyPasswordCheck2->Enabled && !IsSiteCommand);
-    EnableControl(PuttyRegistryStorageKeyEdit,
-      PuttyPasswordCheck2->Enabled && !IsSiteCommand);
-    EnableControl(PuttyRegistryStorageKeyLabel, PuttyRegistryStorageKeyEdit->Enabled);
-
-    EnableControl(SetMasterPasswordButton, WinConfiguration->UseMasterPassword);
-
-    // network
-    EnableControl(CustomExternalIpAddressEdit, CustomExternalIpAddressButton->Checked);
-
-    // window
-    EnableControl(AutoWorkspaceCombo, AutoSaveWorkspaceCheck->Checked);
-    EnableControl(AutoSaveWorkspacePasswordsCheck,
-      !Configuration->DisablePasswordStoring &&
-      AutoWorkspaceCombo->Enabled);
-      
-    // integration
-    // There's no quick launch in Windows 7
-    EnableControl(QuickLaunchIconButton, !IsWin7());
-
-    // languages
-    LanguageChangeLabel->Visible =
-      !GUIConfiguration->CanApplyLocaleImmediately &&
-      (LanguagesView->ItemFocused != NULL) &&
-      (reinterpret_cast<LCID>(LanguagesView->ItemFocused->Data) != GUIConfiguration->AppliedLocale);
-
-    // logging
-    EnableControl(LogProtocolCombo, EnableLoggingCheck->Checked);
-    EnableControl(LogToFileCheck, LogProtocolCombo->Enabled);
-    EnableControl(LogFileNameEdit3, LogToFileCheck->Enabled && LogToFileCheck->Checked);
-    EnableControl(LogFileNameHintText, LogFileNameEdit3->Enabled);
-    EnableControl(LogFileAppendButton, LogFileNameEdit3->Enabled);
-    EnableControl(LogFileOverwriteButton, LogFileNameEdit3->Enabled);
-
-    EnableControl(LogShowWindowCheck, LogProtocolCombo->Enabled);
-    EnableControl(LogWindowCompleteButton, LogShowWindowCheck->Enabled && LogShowWindowCheck->Checked);
-    EnableControl(LogWindowLinesButton, LogWindowCompleteButton->Enabled);
-    EnableControl(LogWindowLinesEdit, LogWindowLinesButton->Enabled && LogWindowLinesButton->Checked);
-    EnableControl(LogWindowLinesText, LogWindowLinesEdit->Enabled);
-
-    EnableControl(ActionsLogFileNameEdit, EnableActionsLoggingCheck->Checked);
-    EnableControl(ActionsLogFileNameHintText, ActionsLogFileNameEdit->Enabled);
-
-    // interface
-    InterfaceChangeLabel->Visible =
-      !CustomWinConfiguration->CanApplyInterfaceImmediately &&
-      (GetInterface() != CustomWinConfiguration->AppliedInterface);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorFontButtonClick(TObject * /*Sender*/)
-{
-  if (FontDialog(FEditorFont))
-  {
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::FormCloseQuery(TObject * /*Sender*/,
-  bool & /*CanClose*/)
-{
-  if (ModalResult != mrCancel)
-  {
-    ExitActiveControl(this);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::IconButtonClick(TObject *Sender)
-{
-  UnicodeString IconName, Params;
-  int SpecialFolder;
-
-  if (Sender == DesktopIconButton)
-  {
-    IconName = AppName;
-    int Result =
-      MessageDialog(LoadStr(CREATE_DESKTOP_ICON), qtConfirmation,
-        qaYes | qaNo | qaCancel, HELP_CREATE_ICON);
-    switch (Result)
-    {
-      case qaYes:
-        SpecialFolder = CSIDL_COMMON_DESKTOPDIRECTORY;
-        break;
-
-      case qaNo:
-        SpecialFolder = CSIDL_DESKTOPDIRECTORY;
-        break;
-
-      default:
-        Abort();
-        break;
-    }
-  }
-  else
-  {
-    if (MessageDialog(LoadStr(CONFIRM_CREATE_ICON),
-          qtConfirmation, qaYes | qaNo, HELP_CREATE_ICON) == qaYes)
-    {
-      if (Sender == SendToHookButton)
-      {
-        IconName = FMTLOAD(SENDTO_HOOK_NAME, (AppName));
-        SpecialFolder = CSIDL_SENDTO;
-        Params = L"/upload";
-      }
-      else if (Sender == QuickLaunchIconButton)
-      {
-        IconName = L"Microsoft\\Internet Explorer\\Quick Launch\\" +
-          AppName;
-        SpecialFolder = CSIDL_APPDATA;
-      }
-    }
-    else
-    {
-      Abort();
-    }
-  }
-
-  CreateDesktopShortCut(IconName,
-    Application->ExeName, Params, L"", SpecialFolder);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CustomCommandsViewData(TObject * /*Sender*/,
-      TListItem * Item)
-{
-  assert(FCustomCommandList != NULL);
-  int Index = Item->Index;
-  assert(Index >= 0 && Index <= FCustomCommandList->Count);
-  const TCustomCommandType * Command = FCustomCommandList->Commands[Index];
-  UnicodeString Caption = StripHotkey(Command->Name);
-  if (Command->ShortCut != 0)
-  {
-    Caption = FORMAT(L"%s (%s)", (Caption, ShortCutToText(Command->ShortCut)));
-  }
-  Item->Caption = Caption;
-  assert(!Item->SubItems->Count);
-  Item->SubItems->Add(Command->Command);
-  int Params = Command->Params;
-  Item->SubItems->Add(LoadStr(
-    FLAGSET(Params, ccLocal) ? CUSTOM_COMMAND_LOCAL : CUSTOM_COMMAND_REMOTE));
-  UnicodeString ParamsStr;
-  #define ADDPARAM(PARAM, STR) \
-    if (FLAGSET(Params, PARAM)) \
-      ParamsStr += (ParamsStr.IsEmpty() ? L"" : L"/") + LoadStr(STR);
-  ADDPARAM(ccApplyToDirectories, CUSTOM_COMMAND_DIRECTORIES);
-  ADDPARAM(ccRecursive, CUSTOM_COMMAND_RECURSE);
-  #undef ADDPARAM
-  Item->SubItems->Add(ParamsStr);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ListViewSelectItem(
-  TObject * /*Sender*/, TListItem * /*Item*/, bool /*Selected*/)
-{
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpdateCustomCommandsView()
-{
-  CustomCommandsView->Items->Count = FCustomCommandList->Count;
-  AdjustListColumnsWidth(CustomCommandsView, FCustomCommandList->Count);
-  CustomCommandsView->Invalidate();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CustomCommandsViewKeyDown(
-      TObject * /*Sender*/, WORD & Key, TShiftState /*Shift*/)
-{
-  if (RemoveCommandButton->Enabled && (Key == VK_DELETE))
-  {
-    RemoveCommandButtonClick(NULL);
-  }
-
-  if (AddCommandButton->Enabled && (Key == VK_INSERT))
-  {
-    AddEditCommandButtonClick(AddCommandButton);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CustomCommandsViewDblClick(
-  TObject * /*Sender*/)
-{
-  if (EditCommandButton->Enabled)
-  {
-    AddEditCommandButtonClick(EditCommandButton);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::AddEditCommandButtonClick(TObject * Sender)
-{
-  CALLSTACK;
-  bool Edit = (Sender == EditCommandButton);
-  TCustomCommandType Command;
-
-  if (Edit)
-  {
-    TRACE("1");
-    int Index = CustomCommandsView->ItemIndex;
-    assert(Index >= 0 && Index <= FCustomCommandList->Count);
-
-    Command = *FCustomCommandList->Commands[Index];
-  }
-
-  TRACE("2");
-  TShortCuts ShortCuts;
-  if (WinConfiguration->SharedBookmarks != NULL)
-  {
-    WinConfiguration->SharedBookmarks->ShortCuts(ShortCuts);
-  }
-  FCustomCommandList->ShortCuts(ShortCuts);
-
-  TRACE("3");
-  if (DoCustomCommandDialog(Command, FCustomCommandList,
-        (Edit ? ccmEdit : ccmAdd), 0, NULL, &ShortCuts))
-  {
-    TRACE("4");
-    int Index = CustomCommandsView->ItemIndex;
-    TCustomCommandType * ACommand = new TCustomCommandType(Command);
-    if (Edit)
-    {
-      TRACE("5");
-      FCustomCommandList->Change(Index, ACommand);
-    }
-    else
-    {
-      TRACE("6");
-      if (Index >= 0)
-      {
-        TRACE("7");
-        FCustomCommandList->Insert(Index, ACommand);
-      }
-      else
-      {
-        TRACE("8");
-        FCustomCommandList->Add(ACommand);
-        Index = FCustomCommandList->Count - 1;
-      }
-    }
-
-    TRACE("9");
-    UpdateCustomCommandsView();
-    CustomCommandsView->ItemIndex = Index;
-    UpdateControls();
-  }
-  TRACE("/");
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::RemoveCommandButtonClick(
-      TObject * /*Sender*/)
-{
-  assert(CustomCommandsView->ItemIndex >= 0 &&
-    CustomCommandsView->ItemIndex < FCustomCommandList->Count);
-  FCustomCommandList->Delete(CustomCommandsView->ItemIndex);
-  UpdateCustomCommandsView();
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CustomCommandMove(int Source, int Dest)
-{
-  if (Source >= 0 && Source < FCustomCommandList->Count &&
-      Dest >= 0 && Dest < FCustomCommandList->Count)
-  {
-    FCustomCommandList->Move(Source, Dest);
-    // workaround for bug in VCL
-    CustomCommandsView->ItemIndex = -1;
-    CustomCommandsView->ItemFocused = CustomCommandsView->Selected;
-    CustomCommandsView->ItemIndex = Dest;
-    UpdateCustomCommandsView();
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpDownCommandButtonClick(TObject * Sender)
-{
-  CustomCommandMove(CustomCommandsView->ItemIndex,
-    CustomCommandsView->ItemIndex + (Sender == UpCommandButton ? -1 : 1));
-}
-//---------------------------------------------------------------------------
-TListViewScrollOnDragOver * __fastcall TPreferencesDialog::ScrollOnDragOver(TObject * ListView)
-{
-  if (ListView == CopyParamListView)
-  {
-    return FCopyParamScrollOnDragOver;
-  }
-  else if (ListView == CustomCommandsView)
-  {
-    return FCustomCommandsScrollOnDragOver;
-  }
-  else if (ListView == EditorListView3)
-  {
-    return FEditorScrollOnDragOver;
-  }
-  else
-  {
-    assert(false);
-    return NULL;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ListViewStartDrag(
-      TObject * Sender, TDragObject *& /*DragObject*/)
-{
-  FListViewDragSource = dynamic_cast<TListView*>(Sender)->ItemIndex;
-  FListViewDragDest = -1;
-  ScrollOnDragOver(Sender)->StartDrag();
-}
-//---------------------------------------------------------------------------
-bool __fastcall TPreferencesDialog::AllowListViewDrag(TObject * Sender, int X, int Y)
-{
-  TListItem * Item = dynamic_cast<TListView*>(Sender)->GetItemAt(X, Y);
-  FListViewDragDest = Item ? Item->Index : -1;
-  return (FListViewDragDest >= 0) && (FListViewDragDest != FListViewDragSource);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CustomCommandsViewDragDrop(
-      TObject * Sender, TObject * Source, int X, int Y)
-{
-  if (Source == CustomCommandsView)
-  {
-    if (AllowListViewDrag(Sender, X, Y))
-    {
-      CustomCommandMove(FListViewDragSource, FListViewDragDest);
-    }
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ListViewDragOver(
-  TObject * Sender, TObject * Source, int X, int Y,
-  TDragState /*State*/, bool & Accept)
-{
-  if (Source == Sender)
-  {
-    // cannot use AllowListViewDrag(X, Y) because of bug in VCL
-    // (when dropped on item itself, when it was dragged over another item before,
-    // that another item remains highlighted forever)
-    Accept = true;
-
-    ScrollOnDragOver(Source)->DragOver(TPoint(X, Y));
-  }
-}
-//---------------------------------------------------------------------------
-const TCopyParamType * TPreferencesDialog::GetCopyParam(int Index)
-{
-  if (Index == 0)
-  {
-    return &FCopyParams;
-  }
-  else
-  {
-    return FCopyParamList->CopyParams[Index - 1];
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamMove(int Source, int Dest)
-{
-  if (Source >= 1 && Source < (1 + FCopyParamList->Count) &&
-      Dest >= 0 && Dest < (1 + FCopyParamList->Count))
-  {
-    if (Dest == 0)
-    {
-      Dest = 1;
-    }
-    FCopyParamList->Move(Source - 1, Dest - 1);
-    // workaround for bug in VCL
-    CopyParamListView->ItemIndex = -1;
-    CopyParamListView->ItemFocused = CopyParamListView->Selected;
-    CopyParamListView->ItemIndex = Dest;
-    UpdateCopyParamListView();
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamListViewDragDrop(
-  TObject * Sender, TObject * Source, int X, int Y)
-{
-  if (Source == CopyParamListView)
-  {
-    if (AllowListViewDrag(Sender, X, Y))
-    {
-      CopyParamMove(FListViewDragSource, FListViewDragDest);
-    }
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpDownCopyParamButtonClick(TObject * Sender)
-{
-  CopyParamMove(CopyParamListView->ItemIndex,
-    CopyParamListView->ItemIndex + (Sender == UpCopyParamButton ? -1 : 1));
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::RemoveCopyParamButtonClick(
-  TObject * /*Sender*/)
-{
-  assert(CopyParamListView->ItemIndex >= 1 &&
-    CopyParamListView->ItemIndex < (1 + FCopyParamList->Count));
-  FCopyParamList->Delete(CopyParamListView->ItemIndex - 1);
-  UpdateCopyParamListView();
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::AddEditCopyParam(TCopyParamPresetMode Mode)
-{
-  CALLSTACK;
-  int Index = CopyParamListView->ItemIndex;
-  bool Result;
-  if ((Index == 0) && (Mode != cpmAdd))
-  {
-    Result = DoCopyParamCustomDialog(FCopyParams, 0);
-  }
-  else
-  {
-    if (Index == 0)
-    {
-      assert(Mode == cpmAdd);
-      Index = 1;
-    }
-
-    TCopyParamRuleData * CopyParamRuleData =
-      (FDialogData != NULL ? FDialogData->CopyParamRuleData : NULL);
-    Index--;
-    Result = DoCopyParamPresetDialog(FCopyParamList, Index, Mode, CopyParamRuleData);
-    if (Result)
-    {
-      UpdateCopyParamListView();
-      CopyParamListView->ItemIndex = Index + 1;
-      // when using duplicate button, focus remains on original item
-      CopyParamListView->ItemFocused = CopyParamListView->Selected;
-    }
-  }
-
-  if (Result)
-  {
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::AddCopyParamButtonClick(TObject * /*Sender*/)
-{
-  AddEditCopyParam(cpmAdd);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditCopyParamButtonClick(TObject * /*Sender*/)
-{
-  AddEditCopyParam(cpmEdit);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::DuplicateCopyParamButtonClick(TObject * /*Sender*/)
-{
-  if (ALWAYS_TRUE(CopyParamListView->ItemIndex >= 1))
-  {
-    AddEditCopyParam(cpmDuplicate);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamListViewDblClick(
-  TObject * /*Sender*/)
-{
-  if (EditCopyParamButton->Enabled)
-  {
-    AddEditCopyParam(cpmEdit);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamListViewKeyDown(
-  TObject * /*Sender*/, WORD & Key, TShiftState /*Shift*/)
-{
-  if (RemoveCopyParamButton->Enabled && (Key == VK_DELETE))
-  {
-    RemoveCopyParamButtonClick(NULL);
-  }
-
-  if (AddCopyParamButton->Enabled && (Key == VK_INSERT))
-  {
-    AddEditCopyParam(cpmAdd);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorMove(int Source, int Dest)
-{
-  if (Source >= 0 && Source < FEditorList->Count &&
-      Dest >= 0 && Dest < FEditorList->Count)
-  {
-    FEditorList->Move(Source, Dest);
-    // workaround for bug in VCL
-    EditorListView3->ItemIndex = -1;
-    EditorListView3->ItemFocused = EditorListView3->Selected;
-    EditorListView3->ItemIndex = Dest;
-    UpdateEditorListView();
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorListView3DragDrop(TObject * Sender,
-  TObject * Source, int X, int Y)
-{
-  if (Source == EditorListView3)
-  {
-    if (AllowListViewDrag(Sender, X, Y))
-    {
-      EditorMove(FListViewDragSource, FListViewDragDest);
-    }
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpDownEditorButtonClick(TObject *Sender)
-{
-  EditorMove(EditorListView3->ItemIndex,
-    EditorListView3->ItemIndex + (Sender == UpEditorButton ? -1 : 1));
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::RemoveEditorButtonClick(
-  TObject * /*Sender*/)
-{
-  assert(EditorListView3->ItemIndex >= 0 &&
-    EditorListView3->ItemIndex < FEditorList->Count);
-  FEditorList->Delete(EditorListView3->ItemIndex);
-  UpdateEditorListView();
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::AddEditEditorButtonClick(TObject * Sender)
-{
-  TEditorPreferencesMode Mode = (Sender == EditEditorButton ? epmEdit : epmAdd);
-  int Index = EditorListView3->ItemIndex;
-  TEditorPreferences * Editor;
-  if (Mode == epmEdit)
-  {
-    Editor = new TEditorPreferences(*FEditorList->Editors[Index]);
-  }
-  else
-  {
-    Editor = new TEditorPreferences();
-  }
-
-  try
-  {
-    bool DummyRemember = false;
-    if (DoEditorPreferencesDialog(Editor->GetData(), DummyRemember, Mode, true))
-    {
-      if (Mode == epmEdit)
-      {
-        FEditorList->Change(Index, Editor);
-      }
-      else
-      {
-        if (Index < 0)
-        {
-          Index = FEditorList->Count;
-          FEditorList->Add(Editor);
-        }
-        else
-        {
-          FEditorList->Insert(Index, Editor);
-        }
-      }
-      // ownership of the object lost
-      Editor = NULL;
-
-      UpdateEditorListView();
-      EditorListView3->ItemIndex = Index;
-      UpdateControls();
-    }
-  }
-  __finally
-  {
-    delete Editor;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorListView3DblClick(TObject * /*Sender*/)
-{
-  if (EditEditorButton->Enabled)
-  {
-    AddEditEditorButtonClick(EditEditorButton);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorListView3KeyDown(TObject * /*Sender*/,
-  WORD & Key, TShiftState /*Shift*/)
-{
-  if (RemoveEditorButton->Enabled && (Key == VK_DELETE))
-  {
-    RemoveEditorButtonClick(NULL);
-  }
-
-  if (AddEditorButton->Enabled && (Key == VK_INSERT))
-  {
-    AddEditEditorButtonClick(AddEditorButton);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpdateEditorListView()
-{
-  EditorListView3->Items->Count = FEditorList->Count;
-  AdjustListColumnsWidth(EditorListView3, FEditorList->Count);
-  EditorListView3->Invalidate();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorListView3Data(TObject * /*Sender*/,
-  TListItem * Item)
-{
-  int Index = Item->Index;
-  assert(Index >= 0 && Index <= FEditorList->Count);
-  const TEditorPreferences * Editor = FEditorList->Editors[Index];
-  Item->Caption = Editor->Name;
-  Item->SubItems->Add(Editor->Data->FileMask.Masks);
-  if (Editor->Data->Editor == edExternal)
-  {
-    Item->SubItems->Add(BooleanToStr(Editor->Data->ExternalEditorText));
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::NavigationTreeChange(TObject * /*Sender*/,
-  TTreeNode * Node)
-{
-  if (ALWAYS_TRUE(Node->SelectedIndex > 0))
-  {
-    PageControl->ActivePage = NOT_NULL(FindPageForTreeNode(Node));
-    // reshow the accelerators, etc
-    ResetSystemSettings(this);
-    // This is particularly here to enable EditCopyParamButton,
-    // as to some reason CopyParamListView->Selected is NULL until
-    // its page is shown for the first time
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PageControlChange(TObject * /*Sender*/)
-{
-  // this is probably only ever called from FormShow (explicitly)
-  bool Found = false;
-  if (ALWAYS_TRUE(PageControl->ActivePage->Tag > 0))
-  {
-    for (int Index = 0; Index < NavigationTree->Items->Count; Index++)
-    {
-      if (NavigationTree->Items->Item[Index]->SelectedIndex ==
-            PageControl->ActivePage->Tag)
-      {
-        NavigationTree->Items->Item[Index]->Selected = true;
-        Found = true;
-      }
-    }
-  }
-
-  if (ALWAYS_TRUE(Found))
-  {
-    UpdateControls();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CMDialogKey(TWMKeyDown & Message)
-{
-  if (Message.CharCode == VK_TAB)
-  {
-    TShiftState Shift = KeyDataToShiftState(Message.KeyData);
-    if (Shift.Contains(ssCtrl))
-    {
-      TTreeNode * Node = NavigationTree->Selected;
-      if (!Shift.Contains(ssShift))
-      {
-        Node = Node->GetNext();
-        if (!Node) Node = NavigationTree->Items->GetFirstNode();
-      }
-      else
-      {
-        if (Node->GetPrev()) Node = Node->GetPrev();
-          else
-        while (Node->GetNext()) Node = Node->GetNext();
-      }
-      Node->Selected = True;
-      Message.Result = 1;
-      return;
-    }
-  }
-  TForm::Dispatch(&Message);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::WMHelp(TWMHelp & Message)
-{
-  assert(Message.HelpInfo != NULL);
-
-  if (Message.HelpInfo->iContextType == HELPINFO_WINDOW)
-  {
-    // invoke help for active page (not for whole form), regardless of focus
-    // (e.g. even if focus is on control outside pagecontrol)
-    Message.HelpInfo->hItemHandle = PageControl->ActivePage->Handle;
-  }
-  TForm::Dispatch(&Message);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::Dispatch(void *Message)
-{
-  TMessage * M = reinterpret_cast<TMessage*>(Message);
-  assert(M);
-  if (M->Msg == CM_DIALOGKEY)
-  {
-    CMDialogKey(*((TWMKeyDown *)Message));
-  }
-  else if (M->Msg == WM_HELP)
-  {
-    WMHelp(*((TWMHelp *)Message));
-  }
-  else
-  {
-    TForm::Dispatch(Message);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::RegisterAsUrlHandlerButtonClick(
-  TObject * /*Sender*/)
-{
-  if (MessageDialog(LoadStr(CONFIRM_REGISTER_URL),
-        qtConfirmation, qaYes | qaNo, HELP_REGISTER_URL) == qaYes)
-  {
-    RegisterAsUrlHandler();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::DDExtLabelClick(TObject * Sender)
-{
-  ((Sender == DDExtEnabledLabel) ? DDExtEnabledButton : DDExtDisabledButton)->
-    SetFocus();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::AddSearchPathButtonClick(
-  TObject * /*Sender*/)
-{
-  UnicodeString AppPath = ExtractFilePath(Application->ExeName);
-  if (MessageDialog(FMTLOAD(CONFIRM_ADD_SEARCH_PATH, (AppPath)),
-        qtConfirmation, qaYes | qaNo, HELP_ADD_SEARCH_PATH) == qaYes)
-  {
-    AddSearchPath(AppPath);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::EditorFontLabelDblClick(
-  TObject * Sender)
-{
-  EditorFontButtonClick(Sender);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UpdateCopyParamListView()
-{
-  CopyParamListView->Items->Count = 1 + FCopyParamList->Count;
-  AdjustListColumnsWidth(CopyParamListView, 1 + FCopyParamList->Count);
-  CopyParamListView->Invalidate();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamListViewData(TObject * /*Sender*/,
-  TListItem * Item)
-{
-  UnicodeString Name;
-  UnicodeString Rule;
-
-  int Index = Item->Index;
-  if (Index == 0)
-  {
-    Name = StripHotkey(LoadStr(COPY_PARAM_DEFAULT));
-  }
-  else
-  {
-    assert(Index >= 1 && Index <= 1 + FCopyParamList->Count);
-    Name = StripHotkey(FCopyParamList->Names[Index - 1]);
-    Rule = BooleanToStr(FCopyParamList->Rules[Index - 1] != NULL);
-  }
-
-  Item->Caption = Name;
-  Item->SubItems->Add(Rule);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::HelpButtonClick(TObject * /*Sender*/)
-{
-  FormHelp(this);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PuttyPathBrowseButtonClick(
-  TObject * /*Sender*/)
-{
-  CALLSTACK;
-  UnicodeString Executables = FORMAT("%s;%s", (OriginalPuttyExecutable, KittyExecutable));
-  BrowseForExecutable(PuttyPathEdit, LoadStr(PREFERENCES_SELECT_PUTTY2),
-    FMTLOAD(PREFERENCES_PUTTY_FILTER2, (Executables)), false, false);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PathEditBeforeDialog(
-  TObject * /*Sender*/, UnicodeString & Name, bool & /*Action*/)
-{
-  FBeforeDialogPath = Name;
-  Name = ExpandEnvironmentVariables(Name);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PathEditAfterDialog(
-  TObject * /*Sender*/, UnicodeString & Name, bool & /*Action*/)
-{
-  if (CompareFileName(Name, ExpandEnvironmentVariables(FBeforeDialogPath)))
-  {
-    Name = FBeforeDialogPath;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::NavigationTreeCollapsing(
-  TObject * /*Sender*/, TTreeNode * /*Node*/, bool & AllowCollapse)
-{
-  AllowCollapse = false;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ListViewEndDrag(
-  TObject * Sender, TObject * /*Target*/, int /*X*/, int /*Y*/)
-{
-  ScrollOnDragOver(Sender)->EndDrag();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PathEditCreateEditDialog(
-  TObject * Sender, TFileDialogKind DialogKind, TOpenDialog *& Dialog)
-{
-  USEDPARAM(DialogKind);
-  assert(DialogKind == dkOpen);
-  Dialog = new TOpenDialog(dynamic_cast<TComponent *>(Sender));
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::SessionReopenTimeoutEditSetValue(
-  TObject * /*Sender*/, Extended Value, UnicodeString & Text, bool & Handled)
-{
-  if (Value == 0)
-  {
-    Text = LoadStr(PREFERENCES_RECONNECT_TIMEOUT_UNLIMITED);
-    Handled = true;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::SessionReopenTimeoutEditGetValue(
-  TObject * /*Sender*/, UnicodeString Text, Extended & Value, bool & Handled)
-{
-  if (AnsiSameText(Text, LoadStr(PREFERENCES_RECONNECT_TIMEOUT_UNLIMITED)))
-  {
-    Value = 0;
-    Handled = true;
-  }
-}
-//---------------------------------------------------------------------------
-bool __fastcall TPreferencesDialog::CanSetMasterPassword()
-{
-  CALLSTACK;
-  bool Result = false;
-  bool Retry;
-  do
-  {
-    TRACE("1");
-    Retry = false;
-    Result = !AnyOtherInstanceOfSelf();
-
-    if (!Result)
-    {
-      TRACE("2");
-      unsigned int Answer =
-        MessageDialog(
-          LoadStr(MASTER_PASSWORD_OTHER_INSTANCE),
-          qtConfirmation, qaRetry | qaIgnore | qaCancel,
-          HELP_MASTER_PASSWORD);
-
-      switch (Answer)
-      {
-        case qaRetry:
-          Retry = true;
-          break;
-
-        case qaIgnore:
-          Result = true;
-          break;
-
-        case qaCancel:
-        default:
-          // noop
-          break;
-      }
-    }
-  }
-  while (Retry && !Result);
-
-  TRACE_EXIT;
-  return Result;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::MasterPasswordChanged(
-  UnicodeString Message, TStrings * RecryptPasswordErrors)
-{
-  CALLSTACK;
-  Configuration->Save();
-  if (RecryptPasswordErrors->Count > 0)
-  {
-    Message = FMTLOAD(MASTER_PASSWORD_RECRYPT_ERRORS, (Message));
-  }
-  MoreMessageDialog(
-    Message, RecryptPasswordErrors, qtInformation, qaOK, HELP_MASTER_PASSWORD);
-  TRACE_EXIT;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ChangeMasterPassword(UnicodeString Message)
-{
-  CALLSTACK;
-  UnicodeString NewPassword;
-  if (DoChangeMasterPasswordDialog(NewPassword))
-  {
-    TRACE("1");
-    std::auto_ptr<TStrings> RecryptPasswordErrors(new TStringList());
-    WinConfiguration->ChangeMasterPassword(NewPassword, RecryptPasswordErrors.get());
-    MasterPasswordChanged(Message, RecryptPasswordErrors.get());
-  }
-  TRACE_EXIT;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UseMasterPasswordCheckClick(
-  TObject * /*Sender*/)
-{
-  CALLSTACK;
-  if (UseMasterPasswordCheck->Checked != WinConfiguration->UseMasterPassword)
-  {
-    TRACE("1");
-    try
-    {
-      if (CanSetMasterPassword())
-      {
-        if (UseMasterPasswordCheck->Checked)
-        {
-          TRACE("2");
-          ChangeMasterPassword(LoadStr(MASTER_PASSWORD_SET));
-        }
-        else
-        {
-          TRACE("3");
-          if (DoMasterPasswordDialog())
-          {
-            TRACE("4");
-            std::auto_ptr<TStrings> RecryptPasswordErrors(new TStringList());
-            WinConfiguration->ClearMasterPassword(RecryptPasswordErrors.get());
-            MasterPasswordChanged(LoadStr(MASTER_PASSWORD_CLEARED), RecryptPasswordErrors.get());
-          }
-        }
-      }
-    }
-    __finally
-    {
-      TRACE("5");
-      UseMasterPasswordCheck->Checked = WinConfiguration->UseMasterPassword;
-      UpdateControls();
-    }
-  }
-  TRACE_EXIT;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::SetMasterPasswordButtonClick(
-  TObject * /*Sender*/)
-{
-  CALLSTACK;
-  if (CanSetMasterPassword())
-  {
-    ChangeMasterPassword(LoadStr(MASTER_PASSWORD_CHANGED));
-  }
-  TRACE_EXIT;
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::UsageViewButtonClick(TObject * /*Sender*/)
-{
-  TStrings * Data = new TStringList();
-  try
-  {
-    Data->Text = GetUsageData();
-    UnicodeString Message =
-      LoadStr(Data->Text.IsEmpty() ? USAGE_DATA_NONE : USAGE_DATA);
-    MoreMessageDialog(Message, Data, qtInformation, qaOK, HELP_USAGE);
-  }
-  __finally
-  {
-    delete Data;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamLabelClick(TObject * /*Sender*/)
-{
-  if (EditCopyParamButton->Enabled)
-  {
-    AddEditCopyParam(cpmEdit);
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CopyParamListViewCustomDrawItem(
-  TCustomListView * Sender, TListItem * Item,
-  TCustomDrawState /*State*/, bool & /*DefaultDraw*/)
-{
-  if (Item->Index == 0)
-  {
-    Sender->Canvas->Font->Style = Sender->Canvas->Font->Style << fsBold;
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::SelectPuttyRegistryStorageKey(const UnicodeString & Key)
-{
-  CALLSTACK;
-  PuttyRegistryStorageKeyEdit->ItemIndex =
-    PuttyRegistryStorageKeyEdit->Items->IndexOf(Key);
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::PuttyPathEditChange(TObject * /*Sender*/)
-{
-  CALLSTACK;
-  UnicodeString PuttyPath = PuttyPathEdit->Text;
-  if (ContainsText(PuttyPath, OriginalPuttyExecutable))
-  {
-    SelectPuttyRegistryStorageKey(OriginalPuttyRegistryStorageKey);
-  }
-  else if (ContainsText(PuttyPath, KittyExecutable))
-  {
-    SelectPuttyRegistryStorageKey(KittyRegistryStorageKey);
-  }
-
-  UpdateControls();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::NavigationTreeChanging(TObject * /*Sender*/,
-  TTreeNode * Node, bool & /*AllowChange*/)
-{
-  CALLSTACK;
-  TTabSheet * Sheet = FindPageForTreeNode(Node);
-  // delay load as this can be time consuming
-  if (Sheet == LanguagesSheet)
-  {
-    LoadLanguages();
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::LanguagesGetMoreButtonClick(TObject * /*Sender*/)
-{
-  CALLSTACK;
-  OpenBrowser(LoadStr(LOCALES_URL));
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::CommanderClick(TObject * /*Sender*/)
-{
-  CommanderInterfaceButton2->SetFocus();
-}
-//---------------------------------------------------------------------------
-void __fastcall TPreferencesDialog::ExplorerClick(TObject * /*Sender*/)
-{
-  ExplorerInterfaceButton2->SetFocus();
-}
-//---------------------------------------------------------------------------
-

Some files were not shown because too many files changed in this diff