From 0b4c19ead39da56d52c07e14e2d41f4a2d87fd75 Mon Sep 17 00:00:00 2001 From: Martin Prikryl Date: Mon, 16 Sep 2013 14:43:13 +0000 Subject: [PATCH] 5.2.4 --- build.bat | 8 +- ...up-chrome.txt => license.setup-chrome.txt} | 2 +- .../{licence.setup.txt => license.setup.txt} | 2 +- deployment/{licence.txt => license.txt} | 0 deployment/winscpsetup.iss | 28 +- dotnet/GlobalSuppressions.cs | 3 +- dotnet/internal/ExeSessionProcess.cs | 15 +- dotnet/internal/Job.cs | 45 +- dotnet/internal/Logger.cs | 7 + dotnet/internal/UnsafeNativeMethods.cs | 34 +- ...{licence-dotnet.txt => license-dotnet.txt} | 0 dotnet/properties/AssemblyInfo.cs | 6 +- libs/mfc/source/borland.mak2 | 525 ----- libs/mfc/source/borland.mak2.bak | 535 ----- licence.txt => license.txt | 0 readme.txt | 11 +- readme_mfc.txt | 4 +- source/Console.cbproj | 4 +- source/DragExt.cbproj | 2 +- source/DragExt64.rc | 4 +- source/WinSCP.cbproj | 10 +- source/WinSCP.cpp | 3 + source/components/ThemePageControl.cpp | 27 +- source/components/ThemePageControl.h | 2 + source/console/Main.cpp | 49 +- source/core/Common.cpp | 52 +- source/core/Common.h | 22 +- source/core/Configuration.cpp | 90 +- source/core/Configuration.h | 5 +- source/core/FtpFileSystem.cpp | 34 +- source/core/FtpFileSystem.h | 2 + source/core/HierarchicalStorage.cpp | 9 +- source/core/Queue.cpp | 22 +- source/core/Queue.h | 1 - source/core/ScpFileSystem.cpp | 2 +- source/core/SessionData.cpp | 2 +- source/core/SessionInfo.cpp | 10 +- source/core/SftpFileSystem.cpp | 10 +- source/core/Terminal.cpp | 6 +- source/core/WebDAVFileSystem.cpp | 2 +- source/filezilla/AsyncProxySocketLayer.cpp | 25 +- source/filezilla/AsyncSocketEx.cpp | 78 +- source/filezilla/AsyncSocketEx.h | 6 - source/filezilla/AsyncSocketExLayer.cpp | 39 +- source/filezilla/AsyncSslSocketLayer.cpp | 163 +- source/filezilla/AsyncSslSocketLayer.h | 4 +- source/filezilla/FtpControlSocket.cpp | 27 +- source/filezilla/FtpListResult.cpp | 4 +- source/filezilla/MainThread.cpp | 2 + source/filezilla/TransferSocket.cpp | 289 +-- source/filezilla/TransferSocket.h | 4 + source/forms/About.cpp | 15 +- source/forms/About.dfm | 62 +- source/forms/About.h | 1 + source/forms/Authenticate.cpp | 9 +- source/forms/Authenticate.dfm | 10 +- source/forms/Cleanup.cpp | 84 +- source/forms/Cleanup.dfm | 15 +- source/forms/Cleanup.h | 5 +- source/forms/Console.cpp | 18 +- source/forms/Copy.cpp | 18 +- source/forms/Copy.dfm | 10 +- source/forms/Copy.h | 2 +- source/forms/CopyParamCustom.cpp | 4 +- source/forms/CopyParamCustom.dfm | 6 +- source/forms/CopyParamPreset.cpp | 4 +- source/forms/CopyParamPreset.dfm | 12 +- source/forms/CopyParams.dfm | 8 +- source/forms/CreateDirectory.cpp | 4 +- source/forms/Custom.cpp | 23 +- source/forms/CustomCommand.cpp | 4 +- source/forms/CustomCommand.dfm | 12 +- source/forms/CustomScpExplorer.cpp | 229 +- source/forms/CustomScpExplorer.dfm | 12 +- source/forms/CustomScpExplorer.h | 14 +- source/forms/EditMask.cpp | 6 +- source/forms/Editor.cpp | 15 +- source/forms/Editor.dfm | 6 +- source/forms/EditorPreferences.cpp | 4 +- source/forms/EditorPreferences.dfm | 8 +- source/forms/FileFind.cpp | 5 +- source/forms/FileFind.dfm | 20 +- source/forms/FullSynchronize.cpp | 18 +- source/forms/FullSynchronize.dfm | 101 +- source/forms/FullSynchronize.h | 2 +- source/forms/ImportSessions.cpp | 2 +- source/forms/ImportSessions.dfm | 2 +- source/forms/InputDlg.cpp | 57 +- source/forms/LocationProfiles.cpp | 42 +- source/forms/LocationProfiles.h | 5 + source/forms/Log.cpp | 1 + source/forms/Log.dfm | 6 +- source/forms/Login.cpp | 80 +- source/forms/Login.dfm | 26 +- source/forms/Login.h | 2 + source/forms/MessageDlg.cpp | 266 ++- source/forms/NonVisual.cpp | 6 +- source/forms/OpenDirectory.cpp | 9 +- source/forms/Preferences.cpp | 41 +- source/forms/Preferences.cpp.LOCAL | 2083 ----------------- source/forms/Preferences.dfm | 595 ++--- source/forms/Properties.cpp | 4 +- source/forms/RemoteTransfer.cpp | 4 +- source/forms/ScpCommander.cpp | 147 +- source/forms/ScpCommander.dfm | 7 +- source/forms/ScpExplorer.cpp | 14 +- source/forms/SelectMask.cpp | 4 +- source/forms/SiteAdvanced.cpp | 32 +- source/forms/SiteAdvanced.dfm | 514 ++-- source/forms/SiteAdvanced.h | 1 + source/forms/Symlink.cpp | 2 +- source/forms/Symlink.dfm | 10 +- source/forms/Synchronize.cpp | 14 +- source/forms/Synchronize.dfm | 77 +- source/forms/Synchronize.h | 2 +- source/forms/SynchronizeChecklist.cpp | 27 +- source/forms/SynchronizeChecklist.dfm | 40 +- source/forms/SynchronizeChecklist.h | 1 - source/forms/SynchronizeProgress.dfm | 26 +- source/packages/filemng/BaseUtils.pas | 62 - source/packages/filemng/CustomDirView.pas | 10 +- source/packages/filemng/CustomDriveView.pas | 5 - source/packages/filemng/DirView.pas | 2 +- source/packages/filemng/DriveView.pas | 10 +- source/packages/filemng/IEDriveInfo.pas | 45 +- source/packages/my/ListViewColProperties.pas | 38 +- source/packages/my/NortonLikeListView.pas | 13 +- source/packages/my/PasTools.pas | 213 +- source/packages/my/PathLabel.pas | 66 +- source/packages/tb2k/TB2Acc.pas | 51 +- source/packages/tb2k/TB2Anim.pas | 13 +- source/packages/tb2k/TB2Common.pas | 38 +- source/packages/tb2k/TB2Dock.pas | 1 - source/packages/tb2k/TB2Item.pas | 26 +- source/packages/tbx/TBXStatusBars.pas | 19 + source/packages/tbx/TBXUtils.pas | 172 +- source/putty/MISC.C | 40 + source/putty/MISC.H | 2 + source/putty/PORTFWD.C | 1 + source/putty/PROXY.C | 1 + source/putty/SSHBN.C | 183 +- source/putty/SSHDSS.C | 95 +- source/putty/SSHPUBK.C | 47 +- source/putty/SSHRSA.C | 52 +- source/putty/windows/WINNET.C | 2 +- source/resource/TextsCore.h | 6 +- source/resource/TextsCore1.rc | 10 +- source/resource/TextsWin.h | 2 + source/resource/TextsWin1.rc | 2 + source/windows/ConsoleRunner.cpp | 52 +- source/windows/CustomWinConfiguration.cpp | 54 +- source/windows/CustomWinConfiguration.h | 6 + source/windows/GUIConfiguration.cpp | 11 +- source/windows/GUIConfiguration.h | 1 + source/windows/GUITools.cpp | 98 + source/windows/GUITools.h | 4 + source/windows/TerminalManager.cpp | 28 +- source/windows/TerminalManager.h | 2 + source/windows/Tools.cpp | 246 +- source/windows/UserInterface.cpp | 87 +- source/windows/VCLCommon.cpp | 137 +- source/windows/VCLCommon.h | 4 +- source/windows/WinConfiguration.cpp | 123 +- source/windows/WinConfiguration.h | 16 +- source/windows/WinInterface.cpp | 292 +-- source/windows/WinInterface.h | 26 +- source/windows/WinMain.cpp | 7 + source/windows/WinSCP.exe.manifest | 12 +- source/windows/Windows.rc | 2 - 169 files changed, 3666 insertions(+), 5920 deletions(-) rename deployment/{licence.setup-chrome.txt => license.setup-chrome.txt} (99%) rename deployment/{licence.setup.txt => license.setup.txt} (99%) rename deployment/{licence.txt => license.txt} (100%) rename dotnet/{licence-dotnet.txt => license-dotnet.txt} (100%) delete mode 100644 libs/mfc/source/borland.mak2 delete mode 100644 libs/mfc/source/borland.mak2.bak rename licence.txt => license.txt (100%) delete mode 100644 source/forms/Preferences.cpp.LOCAL diff --git a/build.bat b/build.bat index 556034652..b1c9f9eee 100644 --- a/build.bat +++ b/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= rem set DRAGEXT64INCL= rem set DRAGEXT64LIB= @@ -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 diff --git a/deployment/licence.setup-chrome.txt b/deployment/license.setup-chrome.txt similarity index 99% rename from deployment/licence.setup-chrome.txt rename to deployment/license.setup-chrome.txt index d55428e81..b92b2983d 100644 --- a/deployment/licence.setup-chrome.txt +++ b/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 diff --git a/deployment/licence.setup.txt b/deployment/license.setup.txt similarity index 99% rename from deployment/licence.setup.txt rename to deployment/license.setup.txt index c2104096c..db2f686ba 100644 --- a/deployment/licence.setup.txt +++ b/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 diff --git a/deployment/licence.txt b/deployment/license.txt similarity index 100% rename from deployment/licence.txt rename to deployment/license.txt diff --git a/deployment/winscpsetup.iss b/deployment/winscpsetup.iss index e9c501184..222a5748d 100644 --- a/deployment/winscpsetup.iss +++ b/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; diff --git a/dotnet/GlobalSuppressions.cs b/dotnet/GlobalSuppressions.cs index 931aa48dd..62d6a4ae8 100644 --- a/dotnet/GlobalSuppressions.cs +++ b/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()")] diff --git a/dotnet/internal/ExeSessionProcess.cs b/dotnet/internal/ExeSessionProcess.cs index cf82ad096..042af27d7 100644 --- a/dotnet/internal/ExeSessionProcess.cs +++ b/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; diff --git a/dotnet/internal/Job.cs b/dotnet/internal/Job.cs index afdefe0ad..aa6707da9 100644 --- a/dotnet/internal/Job.cs +++ b/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; } } diff --git a/dotnet/internal/Logger.cs b/dotnet/internal/Logger.cs index d5de41278..086e18641 100644 --- a/dotnet/internal/Logger.cs +++ b/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 _indents = new Dictionary(); diff --git a/dotnet/internal/UnsafeNativeMethods.cs b/dotnet/internal/UnsafeNativeMethods.cs index 758f8ef2a..be7042b55 100644 --- a/dotnet/internal/UnsafeNativeMethods.cs +++ b/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); } } diff --git a/dotnet/licence-dotnet.txt b/dotnet/license-dotnet.txt similarity index 100% rename from dotnet/licence-dotnet.txt rename to dotnet/license-dotnet.txt diff --git a/dotnet/properties/AssemblyInfo.cs b/dotnet/properties/AssemblyInfo.cs index 871eb2212..f59272b02 100644 --- a/dotnet/properties/AssemblyInfo.cs +++ b/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)] diff --git a/libs/mfc/source/borland.mak2 b/libs/mfc/source/borland.mak2 deleted file mode 100644 index 02914c84f..000000000 --- a/libs/mfc/source/borland.mak2 +++ /dev/null @@ -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 - -############################################################################# diff --git a/libs/mfc/source/borland.mak2.bak b/libs/mfc/source/borland.mak2.bak deleted file mode 100644 index 76c1a300e..000000000 --- a/libs/mfc/source/borland.mak2.bak +++ /dev/null @@ -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 - -############################################################################# diff --git a/licence.txt b/license.txt similarity index 100% rename from licence.txt rename to license.txt diff --git a/readme.txt b/readme.txt index 3f0f29a71..100f08013 100644 --- a/readme.txt +++ b/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. diff --git a/readme_mfc.txt b/readme_mfc.txt index 9b1b25075..95b439971 100644 --- a/readme_mfc.txt +++ b/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 diff --git a/source/Console.cbproj b/source/Console.cbproj index 8c0aa0ed4..2acfa3dd8 100644 --- a/source/Console.cbproj +++ b/source/Console.cbproj @@ -41,10 +41,10 @@ rtl.bpi;$(PackageImports) CppConsoleApplication true - 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/ + 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/ 1033 4 - 1 + 2 true diff --git a/source/DragExt.cbproj b/source/DragExt.cbproj index 069dd6b60..f4c622d99 100644 --- a/source/DragExt.cbproj +++ b/source/DragExt.cbproj @@ -42,7 +42,7 @@ CppDynamicLibrary true true - CompanyName=Martin Prikryl;FileDescription=Drag&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/ + CompanyName=Martin Prikryl;FileDescription=Drag&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/ 1033 2 1 diff --git a/source/DragExt64.rc b/source/DragExt64.rc index 3ea57a3a4..472a19abe 100644 --- a/source/DragExt64.rc +++ b/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" } diff --git a/source/WinSCP.cbproj b/source/WinSCP.cbproj index a356c9b93..59a803287 100644 --- a/source/WinSCP.cbproj +++ b/source/WinSCP.cbproj @@ -31,7 +31,7 @@ <_TCHARMapping>wchar_t - 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 + 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 true true true @@ -44,18 +44,18 @@ true windows\;forms\;packages\filemng;packages\tbx;packages\png;..\libs\lib;$(LIB_PATH);$(ILINK_LibraryPath) 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) - 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 - None + 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 + windows\WinSCP.exe.manifest true exe CppVCLApplication true true - 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/ + 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/ 1033 5 2 - 3 + 4 true diff --git a/source/WinSCP.cpp b/source/WinSCP.cpp index d7add91d3..be113bf3d 100644 --- a/source/WinSCP.cpp +++ b/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 { diff --git a/source/components/ThemePageControl.cpp b/source/components/ThemePageControl.cpp index 76109e189..238d668e9 100644 --- a/source/components/ThemePageControl.cpp +++ b/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 diff --git a/source/components/ThemePageControl.h b/source/components/ThemePageControl.h index 0689ffc4f..5c58efb06 100644 --- a/source/components/ThemePageControl.h +++ b/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(); diff --git a/source/console/Main.cpp b/source/console/Main.cpp index d12085248..320eb84ef 100644 --- a/source/console/Main.cpp +++ b/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) diff --git a/source/core/Common.cpp b/source/core/Common.cpp index 8dfc8ad35..7dddd2757 100644 --- a/source/core/Common.cpp +++ b/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; diff --git a/source/core/Common.h b/source/core/Common.h index 618edf6b2..d58316cbf 100644 --- a/source/core/Common.h +++ b/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 -{ -public: - __fastcall TBoolRestorer(bool & Target) : - TValueRestorer(Target, !Target) - { - } -}; -//--------------------------------------------------------------------------- class TAutoNestingCounter : TValueRestorer { public: __fastcall TAutoNestingCounter(int & Target) : - TValueRestorer(Target, Target) + TValueRestorer(Target) { assert(Target >= 0); ++Target; diff --git a/source/core/Configuration.cpp b/source/core/Configuration.cpp index b9318ee08..2e871d411 100644 --- a/source/core/Configuration.cpp +++ b/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); } } //--------------------------------------------------------------------------- diff --git a/source/core/Configuration.h b/source/core/Configuration.h index 99969b674..4f353f4d0 100644 --- a/source/core/Configuration.h +++ b/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); diff --git a/source/core/FtpFileSystem.cpp b/source/core/FtpFileSystem.cpp index 0fedb44a8..b3ed41218 100644 --- a/source/core/FtpFileSystem.cpp +++ b/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 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)); } } diff --git a/source/core/FtpFileSystem.h b/source/core/FtpFileSystem.h index 628ce8944..55f49ea89 100644 --- a/source/core/FtpFileSystem.h +++ b/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; diff --git a/source/core/HierarchicalStorage.cpp b/source/core/HierarchicalStorage.cpp index 255e8c242..624c054e9 100644 --- a/source/core/HierarchicalStorage.cpp +++ b/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 diff --git a/source/core/Queue.cpp b/source/core/Queue.cpp index 04c7573a7..35cbb2e8b 100644 --- a/source/core/Queue.cpp +++ b/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(List->Items[Index]); diff --git a/source/core/Queue.h b/source/core/Queue.h index d4ba688a3..2375053d2 100644 --- a/source/core/Queue.h +++ b/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); diff --git a/source/core/ScpFileSystem.cpp b/source/core/ScpFileSystem.cpp index 8b48df3aa..32f152638 100644 --- a/source/core/ScpFileSystem.cpp +++ b/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 ? */ } diff --git a/source/core/SessionData.cpp b/source/core/SessionData.cpp index 271e5b17d..c4b382cbd 100644 --- a/source/core/SessionData.cpp +++ b/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)); } } //--------------------------------------------------------------------------- diff --git a/source/core/SessionInfo.cpp b/source/core/SessionInfo.cpp index 53d1d7f79..a987a755a 100644 --- a/source/core/SessionInfo.cpp +++ b/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""); } @@ -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) { diff --git a/source/core/SftpFileSystem.cpp b/source/core/SftpFileSystem.cpp index 117325864..afbfb43e0 100644 --- a/source/core/SftpFileSystem.cpp +++ b/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)); ); } diff --git a/source/core/Terminal.cpp b/source/core/Terminal.cpp index 990aa060e..10aea76fc 100644 --- a/source/core/Terminal.cpp +++ b/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) { diff --git a/source/core/WebDAVFileSystem.cpp b/source/core/WebDAVFileSystem.cpp index 1fbea488d..9e648a193 100644 --- a/source/core/WebDAVFileSystem.cpp +++ b/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; diff --git a/source/filezilla/AsyncProxySocketLayer.cpp b/source/filezilla/AsyncProxySocketLayer.cpp index 81630ae2a..ab8169191 100644 --- a/source/filezilla/AsyncProxySocketLayer.cpp +++ b/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) diff --git a/source/filezilla/AsyncSocketEx.cpp b/source/filezilla/AsyncSocketEx.cpp index 141bb9350..2fca36091 100644 --- a/source/filezilla/AsyncSocketEx.cpp +++ b/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; } diff --git a/source/filezilla/AsyncSocketEx.h b/source/filezilla/AsyncSocketEx.h index eae3ff981..669e980d1 100644 --- a/source/filezilla/AsyncSocketEx.h +++ b/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 diff --git a/source/filezilla/AsyncSocketExLayer.cpp b/source/filezilla/AsyncSocketExLayer.cpp index 5523ef787..a1c3947ce 100644 --- a/source/filezilla/AsyncSocketExLayer.cpp +++ b/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; } diff --git a/source/filezilla/AsyncSslSocketLayer.cpp b/source/filezilla/AsyncSslSocketLayer.cpp index 07551677f..d4e43a96f 100644 --- a/source/filezilla/AsyncSslSocketLayer.cpp +++ b/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); + } } } diff --git a/source/filezilla/AsyncSslSocketLayer.h b/source/filezilla/AsyncSslSocketLayer.h index 7405add84..6cc83e43a 100644 --- a/source/filezilla/AsyncSslSocketLayer.h +++ b/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; diff --git a/source/filezilla/FtpControlSocket.cpp b/source/filezilla/FtpControlSocket.cpp index 9047d2b48..069e2c1c5 100644 --- a/source/filezilla/FtpControlSocket.cpp +++ b/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& 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& 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; } diff --git a/source/filezilla/FtpListResult.cpp b/source/filezilla/FtpListResult.cpp index 408adde6b..f19f02b87 100644 --- a/source/filezilla/FtpListResult.cpp +++ b/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(""); - 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; diff --git a/source/filezilla/MainThread.cpp b/source/filezilla/MainThread.cpp index e32d39c5a..cf35d7d84 100644 --- a/source/filezilla/MainThread.cpp +++ b/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(); diff --git a/source/filezilla/TransferSocket.cpp b/source/filezilla/TransferSocket.cpp index e0bb214c1..02abcfe58 100644 --- a/source/filezilla/TransferSocket.cpp +++ b/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& 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& 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& 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); + } +} + diff --git a/source/filezilla/TransferSocket.h b/source/filezilla/TransferSocket.h index 693657973..3bada8a1b 100644 --- a/source/filezilla/TransferSocket.h +++ b/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]; diff --git a/source/forms/About.cpp b/source/forms/About.cpp index 4d5ec8c82..fc5c6c7e3 100644 --- a/source/forms/About.cpp +++ b/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; diff --git a/source/forms/About.dfm b/source/forms/About.dfm index 4f0e98f94..83927e62d 100644 --- a/source/forms/About.dfm +++ b/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 diff --git a/source/forms/About.h b/source/forms/About.h index 151dbc9f8..7938d2931 100644 --- a/source/forms/About.h +++ b/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); diff --git a/source/forms/Authenticate.cpp b/source/forms/Authenticate.cpp index 2151883dc..3b6bca20c 100644 --- a/source/forms/Authenticate.cpp +++ b/source/forms/Authenticate.cpp @@ -10,6 +10,7 @@ #include #include #include +#include //--------------------------------------------------------------------------- #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) { diff --git a/source/forms/Authenticate.dfm b/source/forms/Authenticate.dfm index f700eba1f..415659853 100644 --- a/source/forms/Authenticate.dfm +++ b/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 diff --git a/source/forms/Cleanup.cpp b/source/forms/Cleanup.cpp index ebcb7aedb..ae83ec00c 100644 --- a/source/forms/Cleanup.cpp +++ b/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*/) diff --git a/source/forms/Cleanup.dfm b/source/forms/Cleanup.dfm index 1e0f53f76..84a26cb18 100644 --- a/source/forms/Cleanup.dfm +++ b/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' diff --git a/source/forms/Cleanup.h b/source/forms/Cleanup.h index bf4da3c61..bb15f2c43 100644 --- a/source/forms/Cleanup.h +++ b/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 diff --git a/source/forms/Console.cpp b/source/forms/Console.cpp index f6f6108c9..d0a8be923 100644 --- a/source/forms/Console.cpp +++ b/source/forms/Console.cpp @@ -11,6 +11,7 @@ #include "Console.h" #include +#include //--------------------------------------------------------------------- #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); diff --git a/source/forms/Copy.cpp b/source/forms/Copy.cpp index 584638f5b..ed60385c2 100644 --- a/source/forms/Copy.cpp +++ b/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*/) diff --git a/source/forms/Copy.dfm b/source/forms/Copy.dfm index 1d838e358..f267f9565 100644 --- a/source/forms/Copy.dfm +++ b/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 diff --git a/source/forms/Copy.h b/source/forms/Copy.h index 5705aa670..720382ced 100644 --- a/source/forms/Copy.h +++ b/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(); diff --git a/source/forms/CopyParamCustom.cpp b/source/forms/CopyParamCustom.cpp index d6298355a..e0ffd6b41 100644 --- a/source/forms/CopyParamCustom.cpp +++ b/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); } diff --git a/source/forms/CopyParamCustom.dfm b/source/forms/CopyParamCustom.dfm index 6d3ec7619..f0d6b2048 100644 --- a/source/forms/CopyParamCustom.dfm +++ b/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 diff --git a/source/forms/CopyParamPreset.cpp b/source/forms/CopyParamPreset.cpp index a7e212c06..983237de4 100644 --- a/source/forms/CopyParamPreset.cpp +++ b/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); diff --git a/source/forms/CopyParamPreset.dfm b/source/forms/CopyParamPreset.dfm index 1dcfa172a..28182bfc4 100644 --- a/source/forms/CopyParamPreset.dfm +++ b/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 diff --git a/source/forms/CopyParams.dfm b/source/forms/CopyParams.dfm index ef0e61ca6..4f303b987 100644 --- a/source/forms/CopyParams.dfm +++ b/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 diff --git a/source/forms/CreateDirectory.cpp b/source/forms/CreateDirectory.cpp index 87f914e76..de76ec3c7 100644 --- a/source/forms/CreateDirectory.cpp +++ b/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); } diff --git a/source/forms/Custom.cpp b/source/forms/Custom.cpp index 20779e4e3..fb20652cd 100644 --- a/source/forms/Custom.cpp +++ b/source/forms/Custom.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #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); diff --git a/source/forms/CustomCommand.cpp b/source/forms/CustomCommand.cpp index 10c5978e6..58a0c12f1 100644 --- a/source/forms/CustomCommand.cpp +++ b/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)) { diff --git a/source/forms/CustomCommand.dfm b/source/forms/CustomCommand.dfm index 29ad75909..37cd011e1 100644 --- a/source/forms/CustomCommand.dfm +++ b/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 diff --git a/source/forms/CustomScpExplorer.cpp b/source/forms/CustomScpExplorer.cpp index f47f36534..8644f847a 100644 --- a/source/forms/CustomScpExplorer.cpp +++ b/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(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(Sender)); + MenuPopup(FCustomCommandMenu, Rect, dynamic_cast(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((reinterpret_cast(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(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(TabSheet->Tag); +} +//--------------------------------------------------------------------------- void __fastcall TCustomScpExplorerForm::UpdateSessionTab(TTabSheet * TabSheet) { if (ALWAYS_TRUE(TabSheet != NULL)) { TManagedTerminal * ManagedTerminal = - dynamic_cast(reinterpret_cast(TabSheet->Tag)); + dynamic_cast(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(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(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(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(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(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(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 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); + // 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); - // 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(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(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(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(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(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(SessionsPageControl->Pages[Index]->Tag); + TTerminal * TargetTerminal = GetSessionTabTerminal(SessionsPageControl->Pages[Index]); if (TargetTerminal != NULL) { assert(!IsFileControl(DropSourceControl, osRemote)); diff --git a/source/forms/CustomScpExplorer.dfm b/source/forms/CustomScpExplorer.dfm index 46e3c8235..c4b3fc09c 100644 --- a/source/forms/CustomScpExplorer.dfm +++ b/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 diff --git a/source/forms/CustomScpExplorer.h b/source/forms/CustomScpExplorer.h index c6aebba9c..016d0e11a 100644 --- a/source/forms/CustomScpExplorer.h +++ b/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); diff --git a/source/forms/EditMask.cpp b/source/forms/EditMask.cpp index 755354cdf..040beda7f 100644 --- a/source/forms/EditMask.cpp +++ b/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; } } diff --git a/source/forms/Editor.cpp b/source/forms/Editor.cpp index f6c33b290..4b06b8b50 100644 --- a/source/forms/Editor.cpp +++ b/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) diff --git a/source/forms/Editor.dfm b/source/forms/Editor.dfm index da44d87d7..8f3bc5dfa 100644 --- a/source/forms/Editor.dfm +++ b/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 diff --git a/source/forms/EditorPreferences.cpp b/source/forms/EditorPreferences.cpp index 22b6d66c6..b331040c7 100644 --- a/source/forms/EditorPreferences.cpp +++ b/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); } diff --git a/source/forms/EditorPreferences.dfm b/source/forms/EditorPreferences.dfm index a8550d4c9..be82e65fd 100644 --- a/source/forms/EditorPreferences.dfm +++ b/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 diff --git a/source/forms/FileFind.cpp b/source/forms/FileFind.cpp index d2ad389f4..c4a050c13 100644 --- a/source/forms/FileFind.cpp +++ b/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(FileView->ItemFocused->Data)->FullFileName; diff --git a/source/forms/FileFind.dfm b/source/forms/FileFind.dfm index 7ed1c6bc2..c106cca92 100644 --- a/source/forms/FileFind.dfm +++ b/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 diff --git a/source/forms/FullSynchronize.cpp b/source/forms/FullSynchronize.cpp index 55f46953f..82c073817 100644 --- a/source/forms/FullSynchronize.cpp +++ b/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); } //--------------------------------------------------------------------------- diff --git a/source/forms/FullSynchronize.dfm b/source/forms/FullSynchronize.dfm index 288675e8d..bb14270cb 100644 --- a/source/forms/FullSynchronize.dfm +++ b/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 ×tamps' TabOrder = 2 diff --git a/source/forms/FullSynchronize.h b/source/forms/FullSynchronize.h index d83454cac..73fe3554a 100644 --- a/source/forms/FullSynchronize.h +++ b/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); diff --git a/source/forms/ImportSessions.cpp b/source/forms/ImportSessions.cpp index 6244c3610..bf15f3059 100644 --- a/source/forms/ImportSessions.cpp +++ b/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) { diff --git a/source/forms/ImportSessions.dfm b/source/forms/ImportSessions.dfm index b921ea915..301474571 100644 --- a/source/forms/ImportSessions.dfm +++ b/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' diff --git a/source/forms/InputDlg.cpp b/source/forms/InputDlg.cpp index 1bc61867a..717a21426 100644 --- a/source/forms/InputDlg.cpp +++ b/source/forms/InputDlg.cpp @@ -7,6 +7,7 @@ #include #include #include +#include //--------------------------------------------------------------------------- #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) { diff --git a/source/forms/LocationProfiles.cpp b/source/forms/LocationProfiles.cpp index 34629b376..d9f6b03e8 100644 --- a/source/forms/LocationProfiles.cpp +++ b/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); diff --git a/source/forms/LocationProfiles.h b/source/forms/LocationProfiles.h index 00be594e0..dd07f7f78 100644 --- a/source/forms/LocationProfiles.h +++ b/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(); diff --git a/source/forms/Log.cpp b/source/forms/Log.cpp index d9b5dd501..370481bab 100644 --- a/source/forms/Log.cpp +++ b/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"); } //--------------------------------------------------------------------------- diff --git a/source/forms/Log.dfm b/source/forms/Log.dfm index d9bfeae3e..6cbaf8a4d 100644 --- a/source/forms/Log.dfm +++ b/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 diff --git a/source/forms/Login.cpp b/source/forms/Login.cpp index e440e27c4..ad7892c72 100644 --- a/source/forms/Login.cpp +++ b/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) { - FSessionData = new TSessionData(L""); - FSessionData->Assign(SessionData); + // advanced + InvalidateSessionData(); + // clone advanced settings only when really needed, + // see also note in SessionAdvancedActionExecute + if (Editable) + { + FSessionData = new TSessionData(L""); + FSessionData->Assign(SessionData); + } + } + else + { + // 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); } } //--------------------------------------------------------------------------- diff --git a/source/forms/Login.dfm b/source/forms/Login.dfm index 24060771a..52aedbe12 100644 --- a/source/forms/Login.dfm +++ b/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' diff --git a/source/forms/Login.h b/source/forms/Login.h index 579fc23d5..827217a5d 100644 --- a/source/forms/Login.h +++ b/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(); diff --git a/source/forms/MessageDlg.cpp b/source/forms/MessageDlg.cpp index 004d60790..4dbb58d18 100644 --- a/source/forms/MessageDlg.cpp +++ b/source/forms/MessageDlg.cpp @@ -14,16 +14,57 @@ #include #include #include +#include //--------------------------------------------------------------------------- #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(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(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(); + 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 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 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); } diff --git a/source/forms/NonVisual.cpp b/source/forms/NonVisual.cpp index c63f672e6..04a8d52ba 100644 --- a/source/forms/NonVisual.cpp +++ b/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) diff --git a/source/forms/OpenDirectory.cpp b/source/forms/OpenDirectory.cpp index b49f8cd1d..4cfc237a1 100644 --- a/source/forms/OpenDirectory.cpp +++ b/source/forms/OpenDirectory.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #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); } } //--------------------------------------------------------------------------- diff --git a/source/forms/Preferences.cpp b/source/forms/Preferences.cpp index 1d87d70f1..176246492 100644 --- a/source/forms/Preferences.cpp +++ b/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(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(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)); diff --git a/source/forms/Preferences.cpp.LOCAL b/source/forms/Preferences.cpp.LOCAL deleted file mode 100644 index 30cff7112..000000000 --- a/source/forms/Preferences.cpp.LOCAL +++ /dev/null @@ -1,2083 +0,0 @@ -//--------------------------------------------------------------------- -#include -#pragma hdrstop - -#include -#include -#include - -#include "Preferences.h" - -#include -#include -#include - -#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 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(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(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(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(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(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(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(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(Sender)->ItemIndex; - FListViewDragDest = -1; - ScrollOnDragOver(Sender)->StartDrag(); -} -//--------------------------------------------------------------------------- -bool __fastcall TPreferencesDialog::AllowListViewDrag(TObject * Sender, int X, int Y) -{ - TListItem * Item = dynamic_cast(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(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(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 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 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(); -} -//--------------------------------------------------------------------------- - diff --git a/source/forms/Preferences.dfm b/source/forms/Preferences.dfm index 93dae6708..dc5174e07 100644 --- a/source/forms/Preferences.dfm +++ b/source/forms/Preferences.dfm @@ -7,7 +7,7 @@ object PreferencesDialog: TPreferencesDialog BorderStyle = bsDialog Caption = 'Preferences' ClientHeight = 439 - ClientWidth = 513 + ClientWidth = 545 Color = clBtnFace ParentFont = True OldCreateOrder = True @@ -15,12 +15,12 @@ object PreferencesDialog: TPreferencesDialog OnCloseQuery = FormCloseQuery OnShow = FormShow DesignSize = ( - 513 + 545 439) PixelsPerInch = 96 TextHeight = 13 object OKButton: TButton - Left = 250 + Left = 282 Top = 408 Width = 75 Height = 25 @@ -31,7 +31,7 @@ object PreferencesDialog: TPreferencesDialog TabOrder = 1 end object CloseButton: TButton - Left = 338 + Left = 370 Top = 408 Width = 75 Height = 25 @@ -44,7 +44,7 @@ object PreferencesDialog: TPreferencesDialog object MainPanel: TPanel Left = 0 Top = 0 - Width = 513 + Width = 545 Height = 402 Align = alTop Anchors = [akLeft, akTop, akRight, akBottom] @@ -53,7 +53,7 @@ object PreferencesDialog: TPreferencesDialog object PageControl: TPageControl Left = 132 Top = 0 - Width = 381 + Width = 413 Height = 402 ActivePage = PreferencesSheet Align = alClient @@ -70,23 +70,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 2 TabVisible = False DesignSize = ( - 373 + 405 392) object CommonPreferencesGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 256 Anchors = [akLeft, akTop, akRight] Caption = 'Confirmations' TabOrder = 0 DesignSize = ( - 357 + 389 256) object ConfirmOverwritingCheck: TCheckBox Left = 16 Top = 44 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Overwriting of files' @@ -96,7 +96,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmDeletingCheck: TCheckBox Left = 16 Top = 67 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Deleting of files (recommended)' @@ -106,7 +106,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmClosingSessionCheck: TCheckBox Left = 16 Top = 136 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Exiting appli&cation' @@ -116,7 +116,7 @@ object PreferencesDialog: TPreferencesDialog object DDTransferConfirmationCheck: TCheckBox Left = 16 Top = 182 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'D&rag && drop operations' @@ -126,7 +126,7 @@ object PreferencesDialog: TPreferencesDialog object ContinueOnErrorCheck: TCheckBox Left = 16 Top = 228 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Continue on &error (advanced users)' @@ -136,7 +136,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmExitOnCompletionCheck: TCheckBox Left = 16 Top = 159 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Exiting application on o&peration completion' @@ -146,7 +146,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmResumeCheck: TCheckBox Left = 16 Top = 113 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Trans&fer resuming' @@ -156,7 +156,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmCommandSessionCheck: TCheckBox Left = 16 Top = 205 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Opening separate &shell session' @@ -166,7 +166,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmRecyclingCheck: TCheckBox Left = 16 Top = 90 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Moving files to Recycle bin' @@ -176,7 +176,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmTransferringCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Transferring of files' @@ -187,25 +187,26 @@ object PreferencesDialog: TPreferencesDialog object NotificationsGroup: TGroupBox Left = 8 Top = 271 - Width = 357 + Width = 389 Height = 73 Anchors = [akLeft, akTop, akRight] Caption = 'Notifications' TabOrder = 1 DesignSize = ( - 357 + 389 73) object BeepOnFinishAfterText: TLabel - Left = 344 + Left = 376 Top = 22 Width = 5 Height = 13 + Anchors = [akTop, akRight] Caption = 's' end object BeepOnFinishCheck: TCheckBox Left = 16 Top = 21 - Width = 260 + Width = 292 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Beep when work finishes, if it lasted more than' @@ -213,13 +214,14 @@ object PreferencesDialog: TPreferencesDialog OnClick = ControlChange end object BeepOnFinishAfterEdit: TUpDownEdit - Left = 282 + Left = 314 Top = 19 Width = 57 Height = 21 Alignment = taRightJustify Increment = 15.000000000000000000 MaxValue = 999.000000000000000000 + Anchors = [akTop, akRight] MaxLength = 3 TabOrder = 1 OnChange = ControlChange @@ -227,7 +229,7 @@ object PreferencesDialog: TPreferencesDialog object BalloonNotificationsCheck: TCheckBox Left = 16 Top = 46 - Width = 309 + Width = 364 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Show balloon ¬ifications in taskbar status area (system tray)' @@ -244,31 +246,33 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 4 TabVisible = False DesignSize = ( - 373 + 405 392) object LoggingGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 190 Anchors = [akLeft, akTop, akRight] Caption = 'Session log' TabOrder = 0 DesignSize = ( - 357 + 389 190) object LogWindowLinesText: TLabel - Left = 256 + Left = 327 Top = 163 Width = 21 Height = 13 + Anchors = [akTop, akRight] Caption = 'lines' end object LogToFileCheck: TCheckBox Left = 16 Top = 47 - Width = 217 + Width = 359 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Log to &file:' TabOrder = 2 OnClick = ControlChange @@ -276,7 +280,7 @@ object PreferencesDialog: TPreferencesDialog object LogFileNameEdit3: TFilenameEdit Left = 40 Top = 69 - Width = 303 + Width = 335 Height = 21 AcceptFiles = True OnBeforeDialog = PathEditBeforeDialog @@ -295,7 +299,7 @@ object PreferencesDialog: TPreferencesDialog object LogShowWindowCheck: TCheckBox Left = 16 Top = 120 - Width = 217 + Width = 327 Height = 17 Caption = 'Show log &window:' TabOrder = 6 @@ -304,7 +308,7 @@ object PreferencesDialog: TPreferencesDialog object LogWindowCompleteButton: TRadioButton Left = 40 Top = 140 - Width = 233 + Width = 303 Height = 17 Caption = 'Display &complete session' TabOrder = 7 @@ -313,29 +317,31 @@ object PreferencesDialog: TPreferencesDialog object LogWindowLinesButton: TRadioButton Left = 40 Top = 163 - Width = 136 + Width = 186 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Display only &last ' TabOrder = 8 OnClick = ControlChange end object LogWindowLinesEdit: TUpDownEdit - Left = 176 + Left = 232 Top = 159 - Width = 73 + Width = 89 Height = 21 Alignment = taRightJustify Increment = 50.000000000000000000 MaxValue = 10000.000000000000000000 MinValue = 50.000000000000000000 Value = 50.000000000000000000 + Anchors = [akTop, akRight] TabOrder = 9 OnChange = ControlChange end object LogFilePanel: TPanel Left = 40 Top = 93 - Width = 233 + Width = 265 Height = 25 Anchors = [akLeft, akTop, akRight] BevelOuter = bvNone @@ -343,7 +349,7 @@ object PreferencesDialog: TPreferencesDialog object LogFileAppendButton: TRadioButton Left = 0 Top = 4 - Width = 97 + Width = 106 Height = 17 Caption = 'Appe&nd' TabOrder = 0 @@ -352,7 +358,7 @@ object PreferencesDialog: TPreferencesDialog object LogFileOverwriteButton: TRadioButton Left = 112 Top = 4 - Width = 97 + Width = 106 Height = 17 Caption = '&Overwrite' TabOrder = 1 @@ -360,12 +366,12 @@ object PreferencesDialog: TPreferencesDialog end end object LogProtocolCombo: TComboBox - Left = 224 + Left = 256 Top = 21 Width = 119 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 1 OnChange = ControlChange Items.Strings = ( @@ -374,7 +380,7 @@ object PreferencesDialog: TPreferencesDialog 'Debug 2') end object LogFileNameHintText: TStaticText - Left = 261 + Left = 293 Top = 91 Width = 82 Height = 16 @@ -388,8 +394,9 @@ object PreferencesDialog: TPreferencesDialog object EnableLoggingCheck: TCheckBox Left = 16 Top = 23 - Width = 202 + Width = 234 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Enable &session logging on level:' TabOrder = 0 OnClick = ControlChange @@ -398,18 +405,18 @@ object PreferencesDialog: TPreferencesDialog object ActionsLoggingGroup: TGroupBox Left = 8 Top = 203 - Width = 357 + Width = 389 Height = 86 Anchors = [akLeft, akTop, akRight] Caption = 'XML log' TabOrder = 1 DesignSize = ( - 357 + 389 86) object ActionsLogFileNameEdit: TFilenameEdit Left = 40 Top = 43 - Width = 302 + Width = 335 Height = 21 AcceptFiles = True OnBeforeDialog = PathEditBeforeDialog @@ -426,7 +433,7 @@ object PreferencesDialog: TPreferencesDialog OnChange = ControlChange end object ActionsLogFileNameHintText: TStaticText - Left = 261 + Left = 293 Top = 65 Width = 82 Height = 16 @@ -440,8 +447,9 @@ object PreferencesDialog: TPreferencesDialog object EnableActionsLoggingCheck: TCheckBox Left = 16 Top = 21 - Width = 241 + Width = 359 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Enable &XML logging to file:' TabOrder = 0 OnClick = ControlChange @@ -456,7 +464,7 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 5 TabVisible = False DesignSize = ( - 373 + 405 392) object InterfaceChangeLabel: TLabel Left = 8 @@ -468,12 +476,13 @@ object PreferencesDialog: TPreferencesDialog object ThemeGroup: TGroupBox Left = 8 Top = 216 - Width = 357 + Width = 389 Height = 52 + Anchors = [akLeft, akTop, akRight] Caption = 'Theme' TabOrder = 0 DesignSize = ( - 357 + 389 52) object Label7: TLabel Left = 16 @@ -484,9 +493,9 @@ object PreferencesDialog: TPreferencesDialog FocusControl = ThemeCombo end object ThemeCombo: TComboBox - Left = 120 + Left = 132 Top = 18 - Width = 109 + Width = 141 Height = 21 Style = csDropDownList Anchors = [akLeft, akTop, akRight] @@ -500,18 +509,18 @@ object PreferencesDialog: TPreferencesDialog object InterfaceGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 202 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'User Interface' TabOrder = 1 DesignSize = ( - 357 + 389 202) object CommanderDescriptionLabel2: TLabel Left = 132 Top = 20 - Width = 218 + Width = 250 Height = 115 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -526,7 +535,7 @@ object PreferencesDialog: TPreferencesDialog object ExplorerDescriptionLabel: TLabel Left = 132 Top = 134 - Width = 220 + Width = 252 Height = 62 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -799,23 +808,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 3 TabVisible = False DesignSize = ( - 373 + 405 392) object PanelsCommonGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 195 Anchors = [akLeft, akTop, akRight] Caption = 'Common' TabOrder = 0 DesignSize = ( - 357 + 389 195) object ShowHiddenFilesCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Show hidden files (Ctrl+Alt+H)' @@ -825,7 +834,7 @@ object PreferencesDialog: TPreferencesDialog object DefaultDirIsHomeCheck: TCheckBox Left = 16 Top = 69 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Default directory is &home directory' @@ -835,7 +844,7 @@ object PreferencesDialog: TPreferencesDialog object DeleteToRecycleBinCheck: TCheckBox Left = 16 Top = 45 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Delete local files to recycle bin' @@ -845,7 +854,7 @@ object PreferencesDialog: TPreferencesDialog object PreservePanelStateCheck: TCheckBox Left = 16 Top = 93 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Remember panels'#39' state when switching sessions' @@ -855,7 +864,7 @@ object PreferencesDialog: TPreferencesDialog object RenameWholeNameCheck: TCheckBox Left = 16 Top = 117 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Select &whole name when renaming file' @@ -865,7 +874,7 @@ object PreferencesDialog: TPreferencesDialog object FormatSizeBytesCheck: TCheckBox Left = 16 Top = 141 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Show file sizes in short &format' @@ -875,7 +884,7 @@ object PreferencesDialog: TPreferencesDialog object FullRowSelectCheck: TCheckBox Left = 16 Top = 165 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Full row select' @@ -886,26 +895,27 @@ object PreferencesDialog: TPreferencesDialog object DoubleClickGroup: TGroupBox Left = 8 Top = 208 - Width = 357 + Width = 389 Height = 74 Anchors = [akLeft, akTop, akRight] Caption = 'Double-click' TabOrder = 1 DesignSize = ( - 357 + 389 74) object DoubleClickActionLabel: TLabel Left = 16 Top = 21 Width = 179 Height = 13 + Anchors = [akLeft, akTop, akRight] Caption = '&Operation to perform on double-click:' FocusControl = DoubleClickActionCombo end object CopyOnDoubleClickConfirmationCheck: TCheckBox Left = 32 Top = 45 - Width = 308 + Width = 340 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Confirm copy on double-click operation' @@ -913,12 +923,12 @@ object PreferencesDialog: TPreferencesDialog OnClick = ControlChange end object DoubleClickActionCombo: TComboBox - Left = 232 + Left = 264 Top = 17 Width = 108 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 0 OnChange = ControlChange Items.Strings = ( @@ -936,12 +946,12 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 3 TabVisible = False DesignSize = ( - 373 + 405 392) object Label3: TLabel Left = 8 Top = 8 - Width = 361 + Width = 393 Height = 29 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -951,13 +961,13 @@ object PreferencesDialog: TPreferencesDialog object PanelsGroup: TGroupBox Left = 8 Top = 38 - Width = 357 + Width = 389 Height = 99 Anchors = [akLeft, akTop, akRight] Caption = 'Panels' TabOrder = 0 DesignSize = ( - 357 + 389 99) object Label8: TLabel Left = 16 @@ -970,7 +980,7 @@ object PreferencesDialog: TPreferencesDialog object SwappedPanelsCheck: TCheckBox Left = 16 Top = 45 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'S&wap panels (local on right, remote on left)' @@ -980,7 +990,7 @@ object PreferencesDialog: TPreferencesDialog object NortonLikeModeCombo: TComboBox Left = 208 Top = 17 - Width = 132 + Width = 164 Height = 21 Style = csDropDownList Anchors = [akLeft, akTop, akRight] @@ -994,7 +1004,7 @@ object PreferencesDialog: TPreferencesDialog object TreeOnLeftCheck: TCheckBox Left = 16 Top = 69 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Show &directory tree left of file list' @@ -1005,13 +1015,13 @@ object PreferencesDialog: TPreferencesDialog object CommanderMiscGroup: TGroupBox Left = 8 Top = 146 - Width = 357 + Width = 389 Height = 77 Anchors = [akLeft, akTop, akRight] Caption = 'Miscellaneous' TabOrder = 1 DesignSize = ( - 357 + 389 77) object Label10: TLabel Left = 16 @@ -1024,7 +1034,7 @@ object PreferencesDialog: TPreferencesDialog object UseLocationProfilesCheck: TCheckBox Left = 16 Top = 45 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Use Location Profiles instead of Directory Bookmarks' @@ -1034,7 +1044,7 @@ object PreferencesDialog: TPreferencesDialog object ExplorerKeyboardShortcutsCombo: TComboBox Left = 208 Top = 17 - Width = 132 + Width = 164 Height = 21 Style = csDropDownList Anchors = [akLeft, akTop, akRight] @@ -1048,18 +1058,18 @@ object PreferencesDialog: TPreferencesDialog object CompareCriterionsGroup: TGroupBox Left = 8 Top = 233 - Width = 357 + Width = 389 Height = 74 Anchors = [akLeft, akTop, akRight] Caption = 'Compare directory criterions' TabOrder = 2 DesignSize = ( - 357 + 389 74) object CompareByTimeCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Compare by &time' @@ -1069,7 +1079,7 @@ object PreferencesDialog: TPreferencesDialog object CompareBySizeCheck: TCheckBox Left = 16 Top = 45 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Compare by &size' @@ -1086,12 +1096,12 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 5 TabVisible = False DesignSize = ( - 373 + 405 392) object Label4: TLabel Left = 8 Top = 8 - Width = 361 + Width = 393 Height = 29 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -1101,18 +1111,18 @@ object PreferencesDialog: TPreferencesDialog object GroupBox2: TGroupBox Left = 8 Top = 38 - Width = 357 + Width = 389 Height = 54 Anchors = [akLeft, akTop, akRight] Caption = 'View' TabOrder = 0 DesignSize = ( - 357 + 389 54) object ShowFullAddressCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Show full path on address bar' @@ -1129,25 +1139,25 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 7 TabVisible = False DesignSize = ( - 373 + 405 392) object InternalEditorGroup: TGroupBox Left = 8 Top = 244 - Width = 357 + Width = 389 Height = 146 Anchors = [akLeft, akRight, akBottom] Caption = 'Internal editor options' TabOrder = 1 DesignSize = ( - 357 + 389 146) object EditorFontLabel: TLabel - Left = 148 + Left = 180 Top = 49 Width = 199 Height = 88 - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] AutoSize = False Caption = 'EditorFontLabel' Color = clBtnFace @@ -1172,10 +1182,11 @@ object PreferencesDialog: TPreferencesDialog FocusControl = EditorEncodingCombo end object EditorFontButton: TButton - Left = 148 + Left = 180 Top = 18 Width = 105 Height = 25 + Anchors = [akTop, akRight] Caption = '&Select font...' TabOrder = 3 OnClick = EditorFontButtonClick @@ -1183,7 +1194,7 @@ object PreferencesDialog: TPreferencesDialog object EditorWordWrapCheck: TCheckBox Left = 16 Top = 20 - Width = 126 + Width = 158 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Wrap long lines' @@ -1193,12 +1204,13 @@ object PreferencesDialog: TPreferencesDialog object EditorTabSizeEdit: TUpDownEdit Left = 16 Top = 64 - Width = 89 + Width = 145 Height = 21 Alignment = taRightJustify MaxValue = 99.000000000000000000 MinValue = 1.000000000000000000 Value = 1.000000000000000000 + Anchors = [akLeft, akTop, akRight] MaxLength = 2 TabOrder = 1 OnChange = ControlChange @@ -1206,9 +1218,10 @@ object PreferencesDialog: TPreferencesDialog object EditorEncodingCombo: TComboBox Left = 16 Top = 112 - Width = 113 + Width = 145 Height = 21 Style = csDropDownList + Anchors = [akLeft, akTop, akRight] MaxLength = 2 TabOrder = 2 OnChange = ControlChange @@ -1217,18 +1230,18 @@ object PreferencesDialog: TPreferencesDialog object EditorPreferenceGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 231 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'Editor preference' TabOrder = 0 DesignSize = ( - 357 + 389 231) object EditorListView3: TListView Left = 16 Top = 24 - Width = 324 + Width = 356 Height = 133 Anchors = [akLeft, akTop, akRight, akBottom] Columns = < @@ -1285,7 +1298,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = AddEditEditorButtonClick end object UpEditorButton: TButton - Left = 258 + Left = 290 Top = 164 Width = 83 Height = 25 @@ -1295,7 +1308,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = UpDownEditorButtonClick end object DownEditorButton: TButton - Left = 258 + Left = 290 Top = 195 Width = 83 Height = 25 @@ -1324,23 +1337,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 8 TabVisible = False DesignSize = ( - 373 + 405 392) object ShellIconsGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 206 Anchors = [akLeft, akTop, akRight] Caption = 'Windows Shell' TabOrder = 0 DesignSize = ( - 357 + 389 206) object DesktopIconButton: TButton Left = 16 Top = 24 - Width = 325 + Width = 357 Height = 25 Anchors = [akLeft, akTop, akRight] Caption = 'Create a &desktop icon' @@ -1350,7 +1363,7 @@ object PreferencesDialog: TPreferencesDialog object QuickLaunchIconButton: TButton Left = 16 Top = 56 - Width = 325 + Width = 357 Height = 25 Anchors = [akLeft, akTop, akRight] Caption = 'Create a &Quick Launch icon' @@ -1360,7 +1373,7 @@ object PreferencesDialog: TPreferencesDialog object SendToHookButton: TButton Left = 16 Top = 88 - Width = 325 + Width = 357 Height = 25 Anchors = [akLeft, akTop, akRight] Caption = 'Add upload shortcut to Explorer'#39's '#39'&Send to'#39' context menu' @@ -1370,7 +1383,7 @@ object PreferencesDialog: TPreferencesDialog object RegisterAsUrlHandlerButton: TButton Left = 16 Top = 135 - Width = 325 + Width = 357 Height = 25 Anchors = [akLeft, akTop, akRight] Caption = 'Register to &handle sftp:// and scp:// addresses' @@ -1380,7 +1393,7 @@ object PreferencesDialog: TPreferencesDialog object AddSearchPathButton: TButton Left = 16 Top = 167 - Width = 325 + Width = 357 Height = 25 Anchors = [akLeft, akTop, akRight] Caption = 'Add WinSCP to &search path' @@ -1388,7 +1401,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = AddSearchPathButtonClick end object ShellIconsText2: TStaticText - Left = 11 + Left = 43 Top = 116 Width = 330 Height = 17 @@ -1412,23 +1425,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 9 TabVisible = False DesignSize = ( - 373 + 405 392) object CustomCommandsGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 374 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'Custom commands' TabOrder = 0 DesignSize = ( - 357 + 389 374) object CustomCommandsView: TListView Left = 16 Top = 24 - Width = 324 + Width = 356 Height = 266 Anchors = [akLeft, akTop, akRight, akBottom] Columns = < @@ -1490,7 +1503,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = RemoveCommandButtonClick end object UpCommandButton: TButton - Left = 258 + Left = 290 Top = 301 Width = 83 Height = 25 @@ -1500,7 +1513,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = UpDownCommandButtonClick end object DownCommandButton: TButton - Left = 258 + Left = 290 Top = 333 Width = 83 Height = 25 @@ -1529,23 +1542,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 10 TabVisible = False DesignSize = ( - 373 + 405 392) object DragDropDownloadsGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 252 Anchors = [akLeft, akTop, akRight] Caption = 'Drag && Drop downloads' TabOrder = 0 DesignSize = ( - 357 + 389 252) object DDExtEnabledLabel: TLabel Left = 35 Top = 68 - Width = 313 + Width = 345 Height = 53 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -1559,7 +1572,7 @@ object PreferencesDialog: TPreferencesDialog object DDExtDisabledLabel: TLabel Left = 35 Top = 144 - Width = 314 + Width = 346 Height = 54 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -1573,7 +1586,7 @@ object PreferencesDialog: TPreferencesDialog object DDExtEnabledButton: TRadioButton Left = 16 Top = 48 - Width = 332 + Width = 364 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Use &shell extension' @@ -1583,7 +1596,7 @@ object PreferencesDialog: TPreferencesDialog object DDExtDisabledButton: TRadioButton Left = 16 Top = 124 - Width = 324 + Width = 356 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Use &temporary folder' @@ -1624,7 +1637,7 @@ object PreferencesDialog: TPreferencesDialog object DDAllowMoveInitCheck: TCheckBox Left = 16 Top = 24 - Width = 332 + Width = 364 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Allow &moving from remote directory to other applications' @@ -1641,16 +1654,19 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 11 TabVisible = False DesignSize = ( - 373 + 405 392) object QueueGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 200 Anchors = [akLeft, akTop, akRight] Caption = 'Background transfers' TabOrder = 0 + DesignSize = ( + 389 + 200) object Label5: TLabel Left = 16 Top = 25 @@ -1668,7 +1684,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = ControlChange end object QueueTransferLimitEdit: TUpDownEdit - Left = 272 + Left = 304 Top = 22 Width = 73 Height = 21 @@ -1676,55 +1692,62 @@ object PreferencesDialog: TPreferencesDialog MaxValue = 9.000000000000000000 MinValue = 1.000000000000000000 Value = 1.000000000000000000 + Anchors = [akTop, akRight] MaxLength = 1 TabOrder = 0 end object QueueAutoPopupCheck: TCheckBox Left = 16 Top = 146 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Automatically popup prompts of background transfers when idle' TabOrder = 5 end object QueueCheck: TCheckBox Left = 16 Top = 74 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Transfer on &background by default' TabOrder = 2 end object QueueNoConfirmationCheck: TCheckBox Left = 16 Top = 122 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&No confirmations for background transfers' TabOrder = 4 end object QueueIndividuallyCheck: TCheckBox Left = 16 Top = 98 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Transfer each file individually on background by default' TabOrder = 3 end object EnableQueueByDefaultCheck: TCheckBox Left = 16 Top = 50 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Enable queue processing by default' TabOrder = 1 end object QueueKeepDoneItemsForCombo: TComboBox - Left = 248 + Left = 280 Top = 169 Width = 97 Height = 21 Style = csDropDownList + Anchors = [akTop, akRight] MaxLength = 1 TabOrder = 6 OnChange = ControlChange @@ -1740,32 +1763,38 @@ object PreferencesDialog: TPreferencesDialog object QueueViewGroup: TGroupBox Left = 8 Top = 214 - Width = 357 + Width = 389 Height = 99 Anchors = [akLeft, akTop, akRight] Caption = 'Queue list' TabOrder = 1 + DesignSize = ( + 389 + 99) object QueueViewShowButton: TRadioButton Left = 16 Top = 21 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Show' TabOrder = 0 end object QueueViewHideWhenEmptyButton: TRadioButton Left = 16 Top = 45 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Hide &when empty' TabOrder = 1 end object QueueViewHideButton: TRadioButton Left = 16 Top = 69 - Width = 337 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Hide' TabOrder = 2 end @@ -1779,21 +1808,25 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 12 TabVisible = False DesignSize = ( - 373 + 405 392) object StorageGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 72 Anchors = [akLeft, akTop, akRight] Caption = 'Configuration storage' TabOrder = 0 + DesignSize = ( + 389 + 72) object RegistryStorageButton: TRadioButton Left = 16 Top = 21 - Width = 289 + Width = 360 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Windows re&gistry' TabOrder = 0 OnClick = ControlChange @@ -1801,8 +1834,9 @@ object PreferencesDialog: TPreferencesDialog object IniFileStorageButton2: TRadioButton Left = 16 Top = 45 - Width = 289 + Width = 360 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&INI file (winscp.ini)' TabOrder = 1 OnClick = ControlChange @@ -1811,18 +1845,18 @@ object PreferencesDialog: TPreferencesDialog object TemporaryDirectoryGrouo: TGroupBox Left = 8 Top = 88 - Width = 357 + Width = 389 Height = 198 Anchors = [akLeft, akTop, akRight] Caption = 'Temporary directory' TabOrder = 1 DesignSize = ( - 357 + 389 198) object Label6: TLabel Left = 16 Top = 22 - Width = 324 + Width = 360 Height = 23 Anchors = [akLeft, akTop, akRight] AutoSize = False @@ -1832,8 +1866,9 @@ object PreferencesDialog: TPreferencesDialog object DDSystemTemporaryDirectoryButton: TRadioButton Left = 16 Top = 45 - Width = 297 + Width = 360 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Use temporary directory of system' TabOrder = 0 OnClick = ControlChange @@ -1841,16 +1876,16 @@ object PreferencesDialog: TPreferencesDialog object DDCustomTemporaryDirectoryButton: TRadioButton Left = 16 Top = 69 - Width = 129 + Width = 148 Height = 17 Caption = 'Use this &directory:' TabOrder = 1 OnClick = ControlChange end object DDTemporaryDirectoryEdit: TDirectoryEdit - Left = 152 + Left = 168 Top = 65 - Width = 192 + Width = 208 Height = 21 AcceptFiles = True OnBeforeDialog = PathEditBeforeDialog @@ -1865,7 +1900,7 @@ object PreferencesDialog: TPreferencesDialog object TemporaryDirectoryCleanupCheck: TCheckBox Left = 16 Top = 144 - Width = 325 + Width = 360 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Cleanup obsolete temporary directories on startup' @@ -1875,7 +1910,7 @@ object PreferencesDialog: TPreferencesDialog object ConfirmTemporaryDirectoryCleanupCheck: TCheckBox Left = 32 Top = 169 - Width = 309 + Width = 344 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Ask before cleanup' @@ -1885,7 +1920,7 @@ object PreferencesDialog: TPreferencesDialog object TemporaryDirectoryAppendSessionCheck: TCheckBox Left = 16 Top = 94 - Width = 325 + Width = 360 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Append &session name to temporary path' @@ -1895,7 +1930,7 @@ object PreferencesDialog: TPreferencesDialog object TemporaryDirectoryAppendPathCheck: TCheckBox Left = 16 Top = 119 - Width = 325 + Width = 360 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Append remote &path to temporary path' @@ -1906,13 +1941,13 @@ object PreferencesDialog: TPreferencesDialog object OtherStorageGroup: TGroupBox Left = 8 Top = 293 - Width = 357 + Width = 389 Height = 53 Anchors = [akLeft, akTop, akRight] Caption = 'Other' TabOrder = 2 DesignSize = ( - 357 + 389 53) object RandomSeedFileLabel: TLabel Left = 16 @@ -1923,9 +1958,9 @@ object PreferencesDialog: TPreferencesDialog FocusControl = RandomSeedFileEdit end object RandomSeedFileEdit: TFilenameEdit - Left = 128 + Left = 144 Top = 19 - Width = 216 + Width = 232 Height = 21 AcceptFiles = True OnBeforeDialog = PathEditBeforeDialog @@ -1951,12 +1986,12 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 13 TabVisible = False DesignSize = ( - 373 + 405 392) object ResumeBox: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 123 Anchors = [akLeft, akTop, akRight] Caption = 'Enable transfer resume/transfer to temporary filename for' @@ -2011,7 +2046,7 @@ object PreferencesDialog: TPreferencesDialog object SessionReopenGroup: TGroupBox Left = 8 Top = 139 - Width = 357 + Width = 389 Height = 203 Anchors = [akLeft, akTop, akRight] Caption = 'Automatic reconnect' @@ -2025,7 +2060,7 @@ object PreferencesDialog: TPreferencesDialog FocusControl = SessionReopenAutoEdit end object SessionReopenAutoSecLabel: TLabel - Left = 254 + Left = 271 Top = 48 Width = 39 Height = 13 @@ -2041,7 +2076,7 @@ object PreferencesDialog: TPreferencesDialog FocusControl = SessionReopenTimeoutEdit end object SessionReopenTimeoutSecLabel: TLabel - Left = 254 + Left = 271 Top = 176 Width = 39 Height = 13 @@ -2057,7 +2092,7 @@ object PreferencesDialog: TPreferencesDialog FocusControl = SessionReopenAutoStallEdit end object SessionReopenAutoStallSecLabel: TLabel - Left = 254 + Left = 271 Top = 149 Width = 39 Height = 13 @@ -2073,7 +2108,7 @@ object PreferencesDialog: TPreferencesDialog FocusControl = SessionReopenAutoIdleEdit end object SessionReopenAutoIdleSecLabel: TLabel - Left = 254 + Left = 271 Top = 99 Width = 39 Height = 13 @@ -2092,7 +2127,7 @@ object PreferencesDialog: TPreferencesDialog object SessionReopenAutoEdit: TUpDownEdit Left = 168 Top = 43 - Width = 81 + Width = 97 Height = 21 Alignment = taRightJustify Increment = 5.000000000000000000 @@ -2114,7 +2149,7 @@ object PreferencesDialog: TPreferencesDialog object SessionReopenTimeoutEdit: TUpDownEdit Left = 168 Top = 171 - Width = 81 + Width = 97 Height = 21 Alignment = taRightJustify Increment = 30.000000000000000000 @@ -2136,7 +2171,7 @@ object PreferencesDialog: TPreferencesDialog object SessionReopenAutoStallEdit: TUpDownEdit Left = 168 Top = 144 - Width = 81 + Width = 97 Height = 21 Alignment = taRightJustify Increment = 5.000000000000000000 @@ -2149,7 +2184,7 @@ object PreferencesDialog: TPreferencesDialog object SessionReopenAutoIdleEdit: TUpDownEdit Left = 168 Top = 94 - Width = 81 + Width = 97 Height = 21 Alignment = taRightJustify Increment = 5.000000000000000000 @@ -2169,18 +2204,18 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 14 TabVisible = False DesignSize = ( - 373 + 405 392) object UpdatesGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 51 Anchors = [akLeft, akTop, akRight] Caption = 'Automatic check for application updates' TabOrder = 0 DesignSize = ( - 357 + 389 51) object Label12: TLabel Left = 16 @@ -2191,12 +2226,12 @@ object PreferencesDialog: TPreferencesDialog FocusControl = UpdatesPeriodCombo end object UpdatesPeriodCombo: TComboBox - Left = 256 + Left = 278 Top = 18 - Width = 88 + Width = 98 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 0 Items.Strings = ( 'Never' @@ -2208,13 +2243,13 @@ object PreferencesDialog: TPreferencesDialog object UpdatesProxyGroup: TGroupBox Left = 8 Top = 152 - Width = 357 + Width = 389 Height = 142 Anchors = [akLeft, akTop, akRight] Caption = 'Connection' TabOrder = 2 DesignSize = ( - 357 + 389 142) object UpdatesProxyHostLabel: TLabel Left = 34 @@ -2225,7 +2260,7 @@ object PreferencesDialog: TPreferencesDialog FocusControl = UpdatesProxyHostEdit end object UpdatesProxyPortLabel: TLabel - Left = 252 + Left = 280 Top = 91 Width = 63 Height = 13 @@ -2234,9 +2269,9 @@ object PreferencesDialog: TPreferencesDialog FocusControl = UpdatesProxyPortEdit end object UpdatesProxyPortEdit: TUpDownEdit - Left = 252 + Left = 278 Top = 108 - Width = 94 + Width = 98 Height = 21 Alignment = taRightJustify MaxValue = 65535.000000000000000000 @@ -2248,7 +2283,7 @@ object PreferencesDialog: TPreferencesDialog object UpdatesProxyHostEdit: TEdit Left = 34 Top = 108 - Width = 205 + Width = 238 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 50 @@ -2258,8 +2293,9 @@ object PreferencesDialog: TPreferencesDialog object UpdatesProxyCheck: TRadioButton Left = 16 Top = 69 - Width = 333 + Width = 365 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Use proxy server' TabOrder = 2 OnClick = ControlChange @@ -2267,8 +2303,9 @@ object PreferencesDialog: TPreferencesDialog object UpdatesDirectCheck: TRadioButton Left = 16 Top = 21 - Width = 333 + Width = 365 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'No &proxy' TabOrder = 0 OnClick = ControlChange @@ -2276,8 +2313,9 @@ object PreferencesDialog: TPreferencesDialog object UpdatesAutoCheck: TRadioButton Left = 16 Top = 45 - Width = 333 + Width = 365 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Automatically detect proxy settings' TabOrder = 1 OnClick = ControlChange @@ -2286,13 +2324,13 @@ object PreferencesDialog: TPreferencesDialog object UpdatesOptionsGroup: TGroupBox Left = 8 Top = 65 - Width = 357 + Width = 389 Height = 81 Anchors = [akLeft, akTop, akRight] Caption = 'Options' TabOrder = 1 DesignSize = ( - 357 + 389 81) object UpdatesBetaVersionsLabel: TLabel Left = 16 @@ -2303,28 +2341,30 @@ object PreferencesDialog: TPreferencesDialog FocusControl = UpdatesBetaVersionsCombo end object UpdatesBetaVersionsCombo: TComboBox - Left = 256 + Left = 278 Top = 18 - Width = 88 + Width = 98 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 0 end object CollectUsageCheck: TCheckBox Left = 16 Top = 49 - Width = 234 + Width = 262 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Allow &anonymous usage statistics' TabOrder = 1 OnClick = ControlChange end object UsageViewButton: TButton - Left = 255 + Left = 278 Top = 45 - Width = 90 + Width = 98 Height = 25 + Anchors = [akTop, akRight] Caption = 'View &statistics' TabOrder = 2 OnClick = UsageViewButtonClick @@ -2339,23 +2379,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 15 TabVisible = False DesignSize = ( - 373 + 405 392) object CopyParamListGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 374 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'Transfer settings presets' TabOrder = 0 DesignSize = ( - 357 + 389 374) object CopyParamLabel: TLabel Left = 18 Top = 222 - Width = 322 + Width = 354 Height = 53 Anchors = [akLeft, akRight, akBottom] AutoSize = False @@ -2366,7 +2406,7 @@ object PreferencesDialog: TPreferencesDialog object CopyParamListView: TListView Left = 16 Top = 24 - Width = 324 + Width = 356 Height = 192 Anchors = [akLeft, akTop, akRight, akBottom] Columns = < @@ -2420,7 +2460,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = RemoveCopyParamButtonClick end object UpCopyParamButton: TButton - Left = 257 + Left = 289 Top = 281 Width = 83 Height = 25 @@ -2430,7 +2470,7 @@ object PreferencesDialog: TPreferencesDialog OnClick = UpDownCopyParamButtonClick end object DownCopyParamButton: TButton - Left = 257 + Left = 289 Top = 313 Width = 83 Height = 25 @@ -2462,9 +2502,9 @@ object PreferencesDialog: TPreferencesDialog object CopyParamAutoSelectNoticeCheck: TCheckBox Left = 18 Top = 344 - Width = 322 + Width = 354 Height = 17 - Anchors = [akLeft, akBottom] + Anchors = [akLeft, akRight, akBottom] Caption = '&Announce when transfer settings preset is autoselected' TabOrder = 7 OnClick = ControlChange @@ -2479,37 +2519,43 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 16 TabVisible = False DesignSize = ( - 373 + 405 392) object PathInCaptionGroup: TGroupBox Left = 8 Top = 114 - Width = 357 + Width = 389 Height = 94 Anchors = [akLeft, akTop, akRight] Caption = 'Path in window title' TabOrder = 1 + DesignSize = ( + 389 + 94) object PathInCaptionFullButton: TRadioButton Left = 16 Top = 21 - Width = 337 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Show &full path' TabOrder = 0 end object PathInCaptionShortButton: TRadioButton Left = 16 Top = 44 - Width = 337 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Sho&w short path' TabOrder = 1 end object PathInCaptionNoneButton: TRadioButton Left = 16 Top = 67 - Width = 337 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Do ¬ show' TabOrder = 2 end @@ -2517,18 +2563,18 @@ object PreferencesDialog: TPreferencesDialog object WindowMiscellaneousGroup: TGroupBox Left = 8 Top = 214 - Width = 357 + Width = 389 Height = 53 Anchors = [akLeft, akTop, akRight] Caption = 'Miscellaneous' TabOrder = 2 DesignSize = ( - 357 + 389 53) object MinimizeToTrayCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 361 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Minimize main window to taskbar status area (system tray)' @@ -2539,18 +2585,20 @@ object PreferencesDialog: TPreferencesDialog object WorkspacesGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 100 + Anchors = [akLeft, akTop, akRight] Caption = 'Workspaces' TabOrder = 0 DesignSize = ( - 357 + 389 100) object AutoSaveWorkspaceCheck: TCheckBox Left = 16 Top = 21 - Width = 329 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Automatically save workspace on exit:' TabOrder = 0 OnClick = ControlChange @@ -2558,15 +2606,16 @@ object PreferencesDialog: TPreferencesDialog object AutoWorkspaceCombo: TComboBox Left = 45 Top = 44 - Width = 300 + Width = 332 Height = 21 + Anchors = [akLeft, akTop, akRight] TabOrder = 1 OnClick = ControlChange end object AutoSaveWorkspacePasswordsCheck: TCheckBox Left = 45 Top = 70 - Width = 300 + Width = 332 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Save &passwords (not recommended) X' @@ -2583,23 +2632,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 18 TabVisible = False DesignSize = ( - 373 + 405 392) object MasterPasswordGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 92 Anchors = [akLeft, akTop, akRight] Caption = 'Master password' TabOrder = 0 DesignSize = ( - 357 + 389 92) object SetMasterPasswordButton: TButton Left = 16 Top = 51 - Width = 325 + Width = 357 Height = 25 Anchors = [akLeft, akTop, akRight] Caption = '&Change master password...' @@ -2607,9 +2656,9 @@ object PreferencesDialog: TPreferencesDialog OnClick = SetMasterPasswordButtonClick end object UseMasterPasswordCheck: TCheckBox - Left = 17 - Top = 24 - Width = 331 + Left = 16 + Top = 21 + Width = 356 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Use master password' @@ -2620,16 +2669,20 @@ object PreferencesDialog: TPreferencesDialog object PasswordGroupBox: TGroupBox Left = 8 Top = 106 - Width = 357 - Height = 56 + Width = 389 + Height = 52 Anchors = [akLeft, akTop, akRight] Caption = 'Session password' TabOrder = 1 + DesignSize = ( + 389 + 52) object SessionRememberPasswordCheck: TCheckBox - Left = 17 - Top = 24 - Width = 333 + Left = 16 + Top = 21 + Width = 356 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Remember &password for duration of session' TabOrder = 0 end @@ -2643,18 +2696,18 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 17 TabVisible = False DesignSize = ( - 373 + 405 392) object ExternalAppsGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 208 Anchors = [akLeft, akTop, akRight] Caption = 'External applications' TabOrder = 0 DesignSize = ( - 357 + 389 208) object PuttyPathLabel: TLabel Left = 16 @@ -2675,7 +2728,7 @@ object PreferencesDialog: TPreferencesDialog object PuttyPathEdit: THistoryComboBox Left = 16 Top = 38 - Width = 249 + Width = 281 Height = 21 Anchors = [akLeft, akTop, akRight] TabOrder = 0 @@ -2684,21 +2737,23 @@ object PreferencesDialog: TPreferencesDialog object PuttyPasswordCheck2: TCheckBox Left = 24 Top = 83 - Width = 321 + Width = 353 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Remember session password and pass it to PuTTY (SSH)' TabOrder = 3 end object AutoOpenInPuttyCheck: TCheckBox Left = 24 Top = 133 - Width = 321 + Width = 353 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Automatically &open new sessions in PuTTY' TabOrder = 5 end object PuttyPathBrowseButton: TButton - Left = 271 + Left = 303 Top = 36 Width = 75 Height = 25 @@ -2710,13 +2765,14 @@ object PreferencesDialog: TPreferencesDialog object TelnetForFtpInPuttyCheck: TCheckBox Left = 24 Top = 108 - Width = 321 + Width = 353 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Open &Telnet sessions in PuTTY for FTP sessions' TabOrder = 4 end object PuttyPathHintText: TStaticText - Left = 186 + Left = 218 Top = 61 Width = 79 Height = 16 @@ -2730,7 +2786,7 @@ object PreferencesDialog: TPreferencesDialog object PuttyRegistryStorageKeyEdit: THistoryComboBox Left = 16 Top = 174 - Width = 330 + Width = 362 Height = 21 Style = csDropDownList Anchors = [akLeft, akTop, akRight] @@ -2747,21 +2803,25 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 20 TabVisible = False DesignSize = ( - 373 + 405 392) object ExternalIpAddressGroupBox: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 98 Anchors = [akLeft, akTop, akRight] Caption = 'External IP address' TabOrder = 0 + DesignSize = ( + 389 + 98) object RetrieveExternalIpAddressButton: TRadioButton Left = 16 Top = 21 - Width = 329 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Retrieve external IP address from &operating system' TabOrder = 0 OnClick = ControlChange @@ -2769,8 +2829,9 @@ object PreferencesDialog: TPreferencesDialog object CustomExternalIpAddressButton: TRadioButton Left = 16 Top = 45 - Width = 233 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Use &following external IP address:' TabOrder = 1 OnClick = ControlChange @@ -2778,7 +2839,7 @@ object PreferencesDialog: TPreferencesDialog object CustomExternalIpAddressEdit: TEdit Left = 45 Top = 67 - Width = 108 + Width = 136 Height = 21 TabOrder = 2 OnClick = ControlChange @@ -2787,16 +2848,20 @@ object PreferencesDialog: TPreferencesDialog object ConnectionsGroup: TGroupBox Left = 8 Top = 112 - Width = 357 + Width = 389 Height = 53 Anchors = [akLeft, akTop, akRight] Caption = 'Connections' TabOrder = 1 + DesignSize = ( + 389 + 53) object TryFtpWhenSshFailsCheck: TCheckBox Left = 16 Top = 21 - Width = 329 + Width = 361 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'When SFTP connection is &rejected, knock FTP port' TabOrder = 0 OnClick = ControlChange @@ -2811,18 +2876,18 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 20 TabVisible = False DesignSize = ( - 373 + 405 392) object PanelsRemoteDirectoryGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 99 Anchors = [akLeft, akTop, akRight] Caption = 'Remote panel' TabOrder = 0 DesignSize = ( - 357 + 389 99) object RefreshRemoteDirectoryUnitLabel: TLabel Left = 336 @@ -2834,7 +2899,7 @@ object PreferencesDialog: TPreferencesDialog object ShowInaccesibleDirectoriesCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Show in&accessible directories' @@ -2844,7 +2909,7 @@ object PreferencesDialog: TPreferencesDialog object AutoReadDirectoryAfterOpCheck: TCheckBox Left = 16 Top = 45 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Auto&matically refresh directory after operation (Ctrl+Alt+R)' @@ -2854,7 +2919,7 @@ object PreferencesDialog: TPreferencesDialog object RefreshRemotePanelCheck: TCheckBox Left = 16 Top = 69 - Width = 234 + Width = 266 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Refresh remote panel &every' @@ -2881,23 +2946,23 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 20 TabVisible = False DesignSize = ( - 373 + 405 392) object LocalPanelGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 75 Anchors = [akLeft, akTop, akRight] Caption = 'Local panel' TabOrder = 0 DesignSize = ( - 357 + 389 75) object PreserveLocalDirectoryCheck: TCheckBox Left = 16 Top = 21 - Width = 325 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Do not &change state when switching sessions' @@ -2906,8 +2971,8 @@ object PreferencesDialog: TPreferencesDialog end object SystemContextMenuCheck: TCheckBox Left = 16 - Top = 45 - Width = 325 + Top = 44 + Width = 357 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Use system file context menu' @@ -2922,30 +2987,31 @@ object PreferencesDialog: TPreferencesDialog ImageIndex = 21 TabVisible = False DesignSize = ( - 373 + 405 392) object LanguagesGroup: TGroupBox Left = 8 Top = 8 - Width = 357 + Width = 389 Height = 374 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'Languages' TabOrder = 0 DesignSize = ( - 357 + 389 374) object LanguageChangeLabel: TLabel Left = 16 Top = 344 Width = 177 Height = 13 + Anchors = [akLeft, akBottom] Caption = 'Changes will apply on the next start.' end object LanguagesView: TListView Left = 16 Top = 24 - Width = 324 + Width = 356 Height = 309 Anchors = [akLeft, akTop, akRight, akBottom] Columns = < @@ -2963,10 +3029,11 @@ object PreferencesDialog: TPreferencesDialog OnSelectItem = ListViewSelectItem end object LanguagesGetMoreButton: TButton - Left = 265 + Left = 297 Top = 339 Width = 75 Height = 25 + Anchors = [akRight, akBottom] Caption = 'Get &more...' TabOrder = 1 OnClick = LanguagesGetMoreButtonClick @@ -3044,7 +3111,7 @@ object PreferencesDialog: TPreferencesDialog end end object HelpButton: TButton - Left = 426 + Left = 458 Top = 408 Width = 75 Height = 25 diff --git a/source/forms/Properties.cpp b/source/forms/Properties.cpp index 7d2f04ded..5f75c5c32 100644 --- a/source/forms/Properties.cpp +++ b/source/forms/Properties.cpp @@ -101,7 +101,7 @@ bool __fastcall TPropertiesDialog::Execute(TRemoteProperties & Properties) UpdateControls(); - bool Result = (ShowModal() == mrOk); + bool Result = (ShowModal() == DefaultResult(this)); if (Result) { @@ -531,7 +531,7 @@ void __fastcall TPropertiesDialog::UpdateControls() void __fastcall TPropertiesDialog::FormCloseQuery(TObject * /*Sender*/, bool & /*CanClose*/) { - if (ModalResult == mrOk) + if (ModalResult == DefaultResult(this)) { ExitActiveControl(this); } diff --git a/source/forms/RemoteTransfer.cpp b/source/forms/RemoteTransfer.cpp index 11fa70821..27a85667f 100644 --- a/source/forms/RemoteTransfer.cpp +++ b/source/forms/RemoteTransfer.cpp @@ -71,7 +71,7 @@ bool __fastcall TRemoteTransferDialog::Execute(void *& Session, UnicodeString & DirectoryEdit->Text = UnixIncludeTrailingBackslash(Target) + FileMask; FDirectCopy = DirectCopy; NotDirectCopyCheck->Checked = !DirectCopy; - bool Result = (ShowModal() == mrOk); + bool Result = (ShowModal() == DefaultResult(this)); if (Result) { Session = SessionCombo->Items->Objects[SessionCombo->ItemIndex]; @@ -128,7 +128,7 @@ void __fastcall TRemoteTransferDialog::SessionComboChange(TObject * /*Sender*/) void __fastcall TRemoteTransferDialog::FormCloseQuery(TObject * /*Sender*/, bool & /*CanClose*/) { - if (ModalResult != mrCancel) + if (ModalResult == DefaultResult(this)) { if ((SessionCombo->ItemIndex == FCurrentSession) && (FAllowDirectCopy == drcConfirmCommandSession) && diff --git a/source/forms/ScpCommander.cpp b/source/forms/ScpCommander.cpp index 9daa3b6e8..435cf27ee 100644 --- a/source/forms/ScpCommander.cpp +++ b/source/forms/ScpCommander.cpp @@ -122,7 +122,12 @@ __fastcall TScpCommanderForm::TScpCommanderForm(TComponent* Owner) UpdateToolbar2ItemCaption(Toolbar2Toolbar->Items->Items[i]); } - LocalDirView->Font = Screen->IconFont; + UseDesktopFont(LocalDirView); + UseDesktopFont(LocalDriveView); + UseDesktopFont(LocalPathLabel); + UseDesktopFont(RemotePathLabel); + UseDesktopFont(LocalStatusBar); + UseDesktopFont(StatusBar); NonVisualDataModule->QueueSpeedComboBoxItem(QueueSpeedComboBoxItem); } @@ -165,9 +170,9 @@ void __fastcall TScpCommanderForm::RestoreParams() PANEL ## StatusBar->Visible = WinConfiguration->ScpCommander.PANEL ## Panel.StatusBar; \ PANEL ## DriveView->Visible = WinConfiguration->ScpCommander.PANEL ## Panel.DriveView; \ if (PANEL ## DriveView->Align == alTop) \ - PANEL ## DriveView->Height = WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewHeight; \ + PANEL ## DriveView->Height = LoadDimension(WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewHeight, WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewHeightPixelsPerInch); \ else \ - PANEL ## DriveView->Width = WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewWidth + PANEL ## DriveView->Width = LoadDimension(WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewWidth, WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewWidthPixelsPerInch) RESTORE_PANEL_PARAMS(Local); RESTORE_PANEL_PARAMS(Remote); #undef RESTORE_PANEL_PARAMS @@ -201,9 +206,15 @@ void __fastcall TScpCommanderForm::StoreParams() WinConfiguration->ScpCommander.PANEL ## Panel.StatusBar = PANEL ## StatusBar->Visible; \ WinConfiguration->ScpCommander.PANEL ## Panel.DriveView = PANEL ## DriveView->Visible; \ if (PANEL ## DriveView->Align == alTop) \ + { \ WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewHeight = PANEL ## DriveView->Height; \ + WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewHeightPixelsPerInch = Screen->PixelsPerInch; \ + } \ else \ - WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewWidth = PANEL ## DriveView->Width + { \ + WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewWidth = PANEL ## DriveView->Width; \ + WinConfiguration->ScpCommander.PANEL ## Panel.DriveViewWidthPixelsPerInch = Screen->PixelsPerInch; \ + } STORE_PANEL_PARAMS(Local); STORE_PANEL_PARAMS(Remote); #undef RESTORE_PANEL_PARAMS @@ -1065,70 +1076,31 @@ void __fastcall TScpCommanderForm::SynchronizeBrowsing(TCustomDirView * ADirView if (!FSynchronisingBrowse && NonVisualDataModule->SynchronizeBrowsingAction->Checked && !PrevPath.IsEmpty() && PrevPath != ADirView->Path) { - bool PrevAllowTransferPresetAutoSelect = FAllowTransferPresetAutoSelect; + TValueRestorer AllowTransferPresetAutoSelectRestorer(FAllowTransferPresetAutoSelect); FAllowTransferPresetAutoSelect = false; + TValueRestorer SynchronisingBrowseRestorer(FSynchronisingBrowse); FSynchronisingBrowse = true; + try { + UnicodeString NewPath; + + bool Error = false; + std::auto_ptr ErrorMoreMessages; + UnicodeString ErrorHelpKeyword; + try { - UnicodeString NewPath; - try - { - SynchronizeBrowsing(ADirView, PrevPath, NewPath, false); - } - // EAbort means that we do not know how to synchronize browsing - // there's no fallback scenario for that - catch(EAbort &) - { - throw; - } - catch(Exception & E) - { - // what does this say? - if (Application->Terminated) - { - throw; - } - else - { - TStrings * MoreMessages = ExceptionToMoreMessages(&E); - try - { - UnicodeString HelpKeyword = - MergeHelpKeyword(HELP_SYNC_DIR_BROWSE_ERROR, GetExceptionHelpKeyword(&E)); - if (MoreMessageDialog(FMTLOAD(SYNC_DIR_BROWSE_CREATE, (NewPath)), - MoreMessages, qtConfirmation, qaYes | qaNo, - HelpKeyword) == qaYes) - { - try - { - SynchronizeBrowsing(ADirView, PrevPath, NewPath, true); - } - catch(Exception & E) - { - if (!Application->Terminated) - { - Terminal->ShowExtendedException(&E); - } - throw; - } - } - else - { - NonVisualDataModule->SynchronizeBrowsingAction->Checked = false; - } - } - __finally - { - delete MoreMessages; - } - } - } + SynchronizeBrowsing(ADirView, PrevPath, NewPath, false); + } + // EAbort means that we do not know how to synchronize browsing + // there's no fallback scenario for that + catch(EAbort &) + { + throw; } catch(Exception & E) { - NonVisualDataModule->SynchronizeBrowsingAction->Checked = false; // what does this say? if (Application->Terminated) { @@ -1136,16 +1108,57 @@ void __fastcall TScpCommanderForm::SynchronizeBrowsing(TCustomDirView * ADirView } else { - MessageDialog(LoadStr(SYNC_DIR_BROWSE_ERROR), qtInformation, qaOK, - HELP_SYNC_DIR_BROWSE_ERROR); + Error = true; + ErrorMoreMessages.reset(ExceptionToMoreMessages(&E)); + ErrorHelpKeyword = + MergeHelpKeyword(HELP_SYNC_DIR_BROWSE_ERROR, GetExceptionHelpKeyword(&E)); } } + + // this was moved here out of the above catch clause, + // to avoid deep nesting, what seems to cause some stray access violations + if (Error) + { + if (MoreMessageDialog(FMTLOAD(SYNC_DIR_BROWSE_CREATE, (NewPath)), + ErrorMoreMessages.get(), qtConfirmation, qaYes | qaNo, + ErrorHelpKeyword) == qaYes) + { + try + { + SynchronizeBrowsing(ADirView, PrevPath, NewPath, true); + } + catch(Exception & E) + { + if (!Application->Terminated) + { + Terminal->ShowExtendedException(&E); + } + throw; + } + } + else + { + NonVisualDataModule->SynchronizeBrowsingAction->Checked = false; + } + } + } - __finally + catch(Exception & E) { - FSynchronisingBrowse = false; - FAllowTransferPresetAutoSelect = PrevAllowTransferPresetAutoSelect; + NonVisualDataModule->SynchronizeBrowsingAction->Checked = false; + // what does this say? + if (Application->Terminated) + { + throw; + } + else + { + MessageDialog(LoadStr(SYNC_DIR_BROWSE_ERROR), qtInformation, qaOK, + HELP_SYNC_DIR_BROWSE_ERROR); + } } + + // note the value restorers at the beginning of this block } } //--------------------------------------------------------------------------- @@ -1208,9 +1221,9 @@ void __fastcall TScpCommanderForm::AddEditLink(TOperationSide Side, bool Add) FileName = FileName + L".lnk"; } - if (Edit && !DeleteFile(FileName)) + if (Edit) { - throw Exception(FMTLOAD(DELETE_LOCAL_FILE_ERROR, (FileName))); + DeleteFileChecked(FileName); } if (!CreateFileShortCut(PointTo, FileName, L"")) { @@ -2015,8 +2028,8 @@ void __fastcall TScpCommanderForm::LocalDirViewContextPopup(TObject * /*Sender*/ //--------------------------------------------------------------------------- void __fastcall TScpCommanderForm::DisplaySystemContextMenu() { + TValueRestorer Restorer(FForceSystemContextMenu); FForceSystemContextMenu = true; - TBoolRestorer Restorer(FForceSystemContextMenu); if ((FLastContextPopupScreenPoint.x >= 0) && (FLastContextPopupScreenPoint.Y >= 0)) { LocalDirView->DisplayContextMenu(FLastContextPopupScreenPoint); diff --git a/source/forms/ScpCommander.dfm b/source/forms/ScpCommander.dfm index 095069e0c..34cbed728 100644 --- a/source/forms/ScpCommander.dfm +++ b/source/forms/ScpCommander.dfm @@ -14,6 +14,7 @@ inherited ScpCommanderForm: TScpCommanderForm Top = 177 Width = 5 Height = 298 + Cursor = crSizeWE Hint = '|Drag to change ratio of file panels. Double click to make width' + ' of file panels equal.' @@ -996,7 +997,7 @@ inherited ScpCommanderForm: TScpCommanderForm Top = 143 Width = 429 Height = 3 - Cursor = crVSplit + Cursor = crSizeNS Hint = 'Drag to resize directory tree. Double click to make height of di' + 'rectory trees equal.' @@ -1205,7 +1206,7 @@ inherited ScpCommanderForm: TScpCommanderForm end inherited QueueView3: TListView Width = 829 - Height = 75 + Height = 71 TabStop = False end inherited QueueDock: TTBXDock @@ -1248,7 +1249,7 @@ inherited ScpCommanderForm: TScpCommanderForm Top = 143 Width = 395 Height = 3 - Cursor = crVSplit + Cursor = crSizeNS Hint = 'Drag to resize directory tree. Double click to make height of di' + 'rectory trees equal.' diff --git a/source/forms/ScpExplorer.cpp b/source/forms/ScpExplorer.cpp index 8510d247b..1ab978396 100644 --- a/source/forms/ScpExplorer.cpp +++ b/source/forms/ScpExplorer.cpp @@ -87,14 +87,23 @@ void __fastcall TScpExplorerForm::RestoreParams() TCustomScpExplorerForm::RestoreParams(); + bool HadHandleAllocated = RemoteDirView->HandleAllocated(); RemoteDirView->UnixColProperties->ParamsStr = WinConfiguration->ScpExplorer.DirViewParams; RemoteDirView->UnixColProperties->ExtVisible = false; // just to make sure RemoteDirView->ViewStyle = (TViewStyle)WinConfiguration->ScpExplorer.ViewStyle; + if (HadHandleAllocated) + { + // This is here to make our persistence checks in VerifyControl pass, + // but we do not want the view linger in the middle of delayed recreation anyway + RemoteDirView->HandleNeeded(); + } + LoadToolbarsLayoutStr(WinConfiguration->ScpExplorer.ToolbarsLayout); SessionsPageControl->Visible = WinConfiguration->ScpExplorer.SessionsTabs; RemoteStatusBar->Visible = WinConfiguration->ScpExplorer.StatusBar; RemoteDriveView->Visible = WinConfiguration->ScpExplorer.DriveView; - RemoteDriveView->Width = WinConfiguration->ScpExplorer.DriveViewWidth; + RemoteDriveView->Width = + LoadDimension(WinConfiguration->ScpExplorer.DriveViewWidth, WinConfiguration->ScpExplorer.DriveViewWidthPixelsPerInch); } //--------------------------------------------------------------------------- void __fastcall TScpExplorerForm::StoreParams() @@ -113,6 +122,7 @@ void __fastcall TScpExplorerForm::StoreParams() WinConfiguration->ScpExplorer.ViewStyle = RemoteDirView->ViewStyle; WinConfiguration->ScpExplorer.DriveView = RemoteDriveView->Visible; WinConfiguration->ScpExplorer.DriveViewWidth = RemoteDriveView->Width; + WinConfiguration->ScpExplorer.DriveViewWidthPixelsPerInch = Screen->PixelsPerInch; TCustomScpExplorerForm::StoreParams(); } __finally @@ -235,7 +245,7 @@ void __fastcall TScpExplorerForm::RemoteDirViewUpdateStatusBar( TObject * /*Sender*/, const TStatusFileInfo & FileInfo) { FStatusBarFileText = FileStatusBarText(FileInfo); - if (!CancelNote()) + if (!CancelNote(false)) { // if there's no note to cancel, we need to update status bar explicitly UpdateStatusBar(); diff --git a/source/forms/SelectMask.cpp b/source/forms/SelectMask.cpp index e46fd8788..9ed473a20 100644 --- a/source/forms/SelectMask.cpp +++ b/source/forms/SelectMask.cpp @@ -107,7 +107,7 @@ void __fastcall TSelectMaskDialog::Init(TMode Mode) void __fastcall TSelectMaskDialog::FormCloseQuery(TObject * /*Sender*/, bool & /*CanClose*/) { - if (ModalResult != mrCancel) + if (ModalResult == DefaultResult(this)) { if (MaskEdit->Focused()) { @@ -120,7 +120,7 @@ bool __fastcall TSelectMaskDialog::Execute() { MaskEdit->Items = WinConfiguration->History[L"Mask"]; ActiveControl = MaskEdit; - bool Result = (ShowModal() == mrOk); + bool Result = (ShowModal() == DefaultResult(this)); if (Result) { MaskEdit->SaveToHistory(); diff --git a/source/forms/SiteAdvanced.cpp b/source/forms/SiteAdvanced.cpp index 783188456..f83dd6b3d 100644 --- a/source/forms/SiteAdvanced.cpp +++ b/source/forms/SiteAdvanced.cpp @@ -106,8 +106,8 @@ void __fastcall TSiteAdvancedDialog::InitControls() LocalDirectoryLabel->Visible = false; LocalDirectoryEdit->Visible = false; LocalDirectoryDescLabel->Visible = false; - DirectoriesGroup->Height = RemoteDirectoryEdit->Top + RemoteDirectoryEdit->Height + 12; - DirectoryOptionsGroup->Top = DirectoriesGroup->Top + DirectoriesGroup->Height + 8; + DirectoriesGroup->Height = RemoteDirectoryEdit->Top + RemoteDirectoryEdit->Height + ScaleByTextHeight(this, 12); + DirectoryOptionsGroup->Top = DirectoriesGroup->Top + DirectoriesGroup->Height + ScaleByTextHeight(this, 8); } ColorButton->Visible = (FOptions & loColor); @@ -194,6 +194,7 @@ void __fastcall TSiteAdvancedDialog::LoadSession() } // hide selection, which is wrongly shown initially even when the box has not focus SftpServerEdit->SelLength = 0; + AllowScpFallbackCheck->Checked = (FSessionData->FSProtocol == fsSFTP); SFTPMaxVersionCombo->ItemIndex = FSessionData->SFTPMaxVersion; @@ -389,6 +390,7 @@ void __fastcall TSiteAdvancedDialog::LoadSession() // connection/tls/ssl page MinTlsVersionCombo->ItemIndex = TlsVersionToIndex(FSessionData->MinTlsVersion); MaxTlsVersionCombo->ItemIndex = TlsVersionToIndex(FSessionData->MaxTlsVersion); + SslSessionReuseCheck->Checked = FSessionData->SslSessionReuse; // color SetSessionColor((TColor)FSessionData->Color); @@ -563,6 +565,19 @@ void __fastcall TSiteAdvancedDialog::SaveSession() ((SftpServerEdit->Text == SftpServerEdit->Items->Strings[0]) ? UnicodeString() : SftpServerEdit->Text); FSessionData->SFTPMaxVersion = SFTPMaxVersionCombo->ItemIndex; + if (AllowScpFallbackCheck->Checked != (FSessionData->FSProtocol == fsSFTP)) + { + if (AllowScpFallbackCheck->Checked) + { + assert(FSessionData->FSProtocol == fsSFTPonly); + FSessionData->FSProtocol = fsSFTP; + } + else + { + assert(FSessionData->FSProtocol == fsSFTP); + FSessionData->FSProtocol = fsSFTPonly; + } + } #define SAVE_SFTP_BUG_COMBO(BUG) FSessionData->SFTPBug[sb ## BUG] = ComboAutoSwitchSave(SFTPBug ## BUG ## Combo); SAVE_SFTP_BUG_COMBO(Symlink); @@ -621,6 +636,7 @@ void __fastcall TSiteAdvancedDialog::SaveSession() // connection/tls/ssl page FSessionData->MinTlsVersion = IndexToTlsVersion(MinTlsVersionCombo->ItemIndex); FSessionData->MaxTlsVersion = IndexToTlsVersion(MaxTlsVersionCombo->ItemIndex); + FSessionData->SslSessionReuse = SslSessionReuseCheck->Checked; // color FSessionData->Color = FColor; @@ -879,6 +895,7 @@ void __fastcall TSiteAdvancedDialog::UpdateControls() ((FtpProxyLogonType > 0) && (FtpProxyLogonType != 3) && (FtpProxyLogonType != 5))); EnableControl(ProxyPasswordLabel, ProxyPasswordEdit->Enabled); bool ProxySettings = (ProxyMethod != ::pmNone) && SshProtocol; + ProxySettingsGroup->Visible = SshProtocol; EnableControl(ProxySettingsGroup, ProxySettings); EnableControl(ProxyTelnetCommandEdit, ProxySettings && (ProxyMethod == pmTelnet)); @@ -934,11 +951,12 @@ void __fastcall TSiteAdvancedDialog::UpdateControls() // environment/scp/shell ScpSheet->Enabled = SshProtocol; - // disable also for SFTP with SCP fallback, as if someone wants to configure + ScpSheet->Caption = LoadStr(ScpProtocol ? LOGIN_SCP_SHELL_PAGE : LOGIN_SHELL_PAGE); + // hide also for SFTP with SCP fallback, as if someone wants to configure // these he/she probably intends to use SCP and should explicitly select it. // (note that these are not used for secondary shell session) - EnableControl(ScpLsOptionsGroup, ScpProtocol); - EnableControl(OtherShellOptionsGroup, ScpProtocol); + ScpLsOptionsGroup->Visible = ScpProtocol; + OtherShellOptionsGroup->Visible = ScpProtocol; // environment/ftp FtpSheet->Enabled = FtpProtocol; @@ -1005,7 +1023,7 @@ bool __fastcall TSiteAdvancedDialog::Execute(TSessionData * SessionData) FSessionData = SessionData; LoadSession(); - bool Result = (ShowModal() == mrOk); + bool Result = (ShowModal() == DefaultResult(this)); if (Result) { @@ -1232,7 +1250,7 @@ void __fastcall TSiteAdvancedDialog::PrivateKeyEditAfterDialog(TObject * Sender, void __fastcall TSiteAdvancedDialog::FormCloseQuery(TObject * /*Sender*/, bool & /*CanClose*/) { - if (ModalResult != mrCancel) + if (ModalResult == DefaultResult(this)) { VerifyKeyIncludingVersion(PrivateKeyEdit->Text, GetSshProt()); // for tunnel key do not check SSH version as it is not configurable diff --git a/source/forms/SiteAdvanced.dfm b/source/forms/SiteAdvanced.dfm index 433a3b7c2..13bed4e6c 100644 --- a/source/forms/SiteAdvanced.dfm +++ b/source/forms/SiteAdvanced.dfm @@ -7,7 +7,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog BorderStyle = bsDialog Caption = 'Advanced Site Settings' ClientHeight = 432 - ClientWidth = 513 + ClientWidth = 561 Color = clBtnFace ParentFont = True OldCreateOrder = True @@ -15,14 +15,14 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnCloseQuery = FormCloseQuery OnShow = FormShow DesignSize = ( - 513 + 561 432) PixelsPerInch = 96 TextHeight = 13 object MainPanel: TPanel Left = 0 Top = 0 - Width = 513 + Width = 561 Height = 392 Align = alTop Anchors = [akLeft, akTop, akRight, akBottom] @@ -32,7 +32,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog Tag = 1 Left = 152 Top = 0 - Width = 361 + Width = 409 Height = 392 HelpType = htKeyword ActivePage = EnvironmentSheet @@ -50,18 +50,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 6 TabVisible = False DesignSize = ( - 353 + 401 382) object EnvironmentGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 96 Anchors = [akLeft, akTop, akRight] Caption = 'Server environment' TabOrder = 0 DesignSize = ( - 345 + 393 96) object EOLTypeLabel: TLabel Left = 12 @@ -88,46 +88,48 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = TimeDifferenceEdit end object TimeDifferenceHoursLabel: TLabel - Left = 194 + Left = 210 Top = 68 Width = 27 Height = 13 + Anchors = [akTop, akRight] Caption = 'hours' FocusControl = TimeDifferenceEdit end object TimeDifferenceMinutesLabel: TLabel - Left = 296 + Left = 336 Top = 66 Width = 37 Height = 13 + Anchors = [akTop, akRight] Caption = 'minutes' FocusControl = TimeDifferenceMinutesEdit end object EOLTypeCombo: TComboBox - Left = 272 + Left = 320 Top = 15 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 0 Items.Strings = ( 'LF' 'CR/LF') end object UtfCombo: TComboBox - Left = 272 + Left = 320 Top = 39 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 1 end object TimeDifferenceEdit: TUpDownEdit Left = 135 Top = 63 - Width = 54 + Width = 69 Height = 21 Alignment = taRightJustify MaxValue = 25.000000000000000000 @@ -138,9 +140,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnChange = DataChange end object TimeDifferenceMinutesEdit: TUpDownEdit - Left = 237 + Left = 261 Top = 63 - Width = 54 + Width = 69 Height = 21 Alignment = taRightJustify Increment = 15.000000000000000000 @@ -155,18 +157,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object DSTModeGroup: TGroupBox Left = 0 Top = 110 - Width = 345 + Width = 393 Height = 93 Anchors = [akLeft, akTop, akRight] Caption = 'Daylight saving time' TabOrder = 1 DesignSize = ( - 345 + 393 93) object DSTModeUnixCheck: TRadioButton Left = 12 Top = 19 - Width = 317 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Adjust remote timestamp to local co&nventions' @@ -176,7 +178,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object DSTModeWinCheck: TRadioButton Left = 12 Top = 42 - Width = 317 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Adjust remote timestamp with &DST' @@ -186,7 +188,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object DSTModeKeepCheck: TRadioButton Left = 12 Top = 65 - Width = 317 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Preser&ve remote timestamp' @@ -203,18 +205,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 11 TabVisible = False DesignSize = ( - 353 + 401 382) object DirectoriesGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 183 Anchors = [akLeft, akTop, akRight] Caption = 'Directories' TabOrder = 0 DesignSize = ( - 345 + 393 183) object LocalDirectoryLabel: TLabel Left = 12 @@ -242,7 +244,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object LocalDirectoryEdit: TDirectoryEdit Left = 12 Top = 128 - Width = 323 + Width = 371 Height = 21 AcceptFiles = True DialogText = 'Select startup local directory.' @@ -255,7 +257,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object RemoteDirectoryEdit: TEdit Left = 12 Top = 83 - Width = 323 + Width = 371 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 1000 @@ -266,7 +268,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object UpdateDirectoriesCheck: TCheckBox Left = 12 Top = 42 - Width = 321 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Re&member last used directory' @@ -275,7 +277,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object SynchronizeBrowsingCheck: TCheckBox Left = 12 Top = 19 - Width = 321 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Syn&chronize browsing' @@ -285,18 +287,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object DirectoryOptionsGroup: TGroupBox Left = 0 Top = 198 - Width = 345 + Width = 393 Height = 93 Anchors = [akLeft, akTop, akRight] Caption = 'Directory reading options' TabOrder = 1 DesignSize = ( - 345 + 393 93) object CacheDirectoriesCheck: TCheckBox Left = 12 Top = 19 - Width = 321 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Cache &visited remote directories' @@ -306,7 +308,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object CacheDirectoryChangesCheck: TCheckBox Left = 12 Top = 42 - Width = 182 + Width = 230 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Cache &directory changes' @@ -316,18 +318,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ResolveSymlinksCheck: TCheckBox Left = 12 Top = 65 - Width = 321 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Resolve symbolic li&nks' TabOrder = 3 end object PreserveDirectoryChangesCheck: TCheckBox - Left = 203 + Left = 251 Top = 42 Width = 139 Height = 17 - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] Caption = '&Permanent cache' TabOrder = 2 end @@ -341,18 +343,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 15 TabVisible = False DesignSize = ( - 353 + 401 382) object RecycleBinGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 114 Anchors = [akLeft, akTop, akRight] Caption = 'Recycle bin' TabOrder = 0 DesignSize = ( - 345 + 393 114) object RecycleBinPathLabel: TLabel Left = 12 @@ -365,8 +367,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object DeleteToRecycleBinCheck: TCheckBox Left = 12 Top = 19 - Width = 317 + Width = 370 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Preserve deleted remote files to recycle bin' TabOrder = 0 OnClick = DataChange @@ -374,8 +377,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object OverwrittenToRecycleBinCheck: TCheckBox Left = 12 Top = 42 - Width = 317 + Width = 370 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Preserve &overwritten remote files to recycle bin (SFTP only)' TabOrder = 1 OnClick = DataChange @@ -383,7 +387,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object RecycleBinPathEdit: TEdit Left = 12 Top = 81 - Width = 322 + Width = 370 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 1000 @@ -401,18 +405,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 12 TabVisible = False DesignSize = ( - 353 + 401 382) object SFTPBugsGroupBox: TGroupBox Left = 0 Top = 108 - Width = 345 + Width = 393 Height = 70 Anchors = [akLeft, akTop, akRight] Caption = 'Detection of known bugs in SFTP servers' TabOrder = 1 DesignSize = ( - 345 + 393 70) object Label10: TLabel Left = 12 @@ -431,34 +435,34 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = SFTPBugSignedTSCombo end object SFTPBugSymlinkCombo: TComboBox - Left = 272 + Left = 320 Top = 15 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 0 end object SFTPBugSignedTSCombo: TComboBox - Left = 272 + Left = 320 Top = 39 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 1 end end object SFTPProtocolGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 96 Anchors = [akLeft, akTop, akRight] Caption = 'Protocol options' TabOrder = 0 DesignSize = ( - 345 + 393 96) object Label34: TLabel Left = 12 @@ -477,12 +481,12 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = SftpServerEdit end object SFTPMaxVersionCombo: TComboBox - Left = 272 + Left = 320 Top = 39 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 1 Items.Strings = ( '0' @@ -493,9 +497,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog '5') end object SftpServerEdit: TComboBox - Left = 184 + Left = 149 Top = 15 - Width = 149 + Width = 232 Height = 21 AutoComplete = False Anchors = [akLeft, akTop, akRight] @@ -510,8 +514,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AllowScpFallbackCheck: TCheckBox Left = 12 Top = 68 - Width = 121 + Width = 369 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Allow SCP &fallback' TabOrder = 2 OnClick = DataChange @@ -522,20 +527,23 @@ object SiteAdvancedDialog: TSiteAdvancedDialog Tag = 2 HelpType = htKeyword HelpKeyword = 'ui_login_scp' - Caption = 'SCP/Shell' + Caption = 'SCP/ShellX' ImageIndex = 3 TabVisible = False DesignSize = ( - 353 + 401 382) object OtherShellOptionsGroup: TGroupBox Left = 0 Top = 161 - Width = 345 + Width = 393 Height = 69 Anchors = [akLeft, akTop, akRight] Caption = 'Other options' TabOrder = 2 + DesignSize = ( + 393 + 69) object LookupUserGroupsCheck: TCheckBox Left = 12 Top = 19 @@ -556,19 +564,21 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnClick = DataChange end object UnsetNationalVarsCheck: TCheckBox - Left = 152 + Left = 168 Top = 19 - Width = 185 + Width = 213 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Clear &national variables' TabOrder = 1 OnClick = DataChange end object Scp1CompatibilityCheck: TCheckBox - Left = 152 + Left = 168 Top = 42 - Width = 185 + Width = 213 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Use scp&2 with scp1 compatibility' TabOrder = 3 OnClick = DataChange @@ -577,13 +587,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ShellGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 70 Anchors = [akLeft, akTop, akRight] Caption = 'Shell' TabOrder = 0 DesignSize = ( - 345 + 393 70) object Label19: TLabel Left = 12 @@ -602,9 +612,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = ReturnVarEdit end object ShellEdit: TComboBox - Left = 152 + Left = 168 Top = 15 - Width = 181 + Width = 213 Height = 21 AutoComplete = False Anchors = [akLeft, akTop, akRight] @@ -618,9 +628,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog 'sudo su -') end object ReturnVarEdit: TComboBox - Left = 152 + Left = 168 Top = 39 - Width = 181 + Width = 213 Height = 21 AutoComplete = False Anchors = [akLeft, akTop, akRight] @@ -636,13 +646,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ScpLsOptionsGroup: TGroupBox Left = 0 Top = 84 - Width = 345 + Width = 393 Height = 69 Anchors = [akLeft, akTop, akRight] Caption = 'Directory listing' TabOrder = 1 DesignSize = ( - 345 + 393 69) object Label9: TLabel Left = 12 @@ -662,18 +672,19 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnClick = DataChange end object SCPLsFullTimeAutoCheck: TCheckBox - Left = 152 + Left = 168 Top = 42 - Width = 185 + Width = 217 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Try to get &full timestamp' TabOrder = 2 OnClick = DataChange end object ListingCommandEdit: TComboBox - Left = 152 + Left = 168 Top = 15 - Width = 181 + Width = 213 Height = 21 AutoComplete = False Anchors = [akLeft, akTop, akRight] @@ -694,18 +705,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 16 TabVisible = False DesignSize = ( - 353 + 401 382) object FtpGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 200 Anchors = [akLeft, akTop, akRight] Caption = 'Protocol options' TabOrder = 0 DesignSize = ( - 345 + 393 200) object Label25: TLabel Left = 12 @@ -734,9 +745,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object FtpForcePasvIpLabel: TLabel Left = 12 Top = 172 - Width = 226 + Width = 230 Height = 13 - Caption = '&Force IP address for passive mode connections' + Caption = '&Force IP address for passive mode connections:' FocusControl = FtpForcePasvIpCombo end object FtpAccountLabel: TLabel @@ -750,47 +761,48 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object PostLoginCommandsMemo: TMemo Left = 12 Top = 59 - Width = 321 + Width = 369 Height = 53 Anchors = [akLeft, akTop, akRight] ScrollBars = ssVertical TabOrder = 1 end object FtpListAllCombo: TComboBox - Left = 272 + Left = 320 Top = 143 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 3 OnChange = DataChange end object FtpForcePasvIpCombo: TComboBox - Left = 272 + Left = 320 Top = 167 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 4 OnChange = DataChange end object FtpUseMlsdCombo: TComboBox - Left = 272 + Left = 320 Top = 119 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 2 OnChange = DataChange end object FtpAccountEdit: TEdit Left = 128 Top = 15 - Width = 205 + Width = 253 Height = 21 + Anchors = [akLeft, akTop, akRight] MaxLength = 100 TabOrder = 0 Text = 'FtpAccountEdit' @@ -806,18 +818,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 7 TabVisible = False DesignSize = ( - 353 + 401 382) object FtpPingGroup: TGroupBox Left = 0 Top = 132 - Width = 345 + Width = 393 Height = 117 Anchors = [akLeft, akTop, akRight] Caption = 'Keepalives' TabOrder = 4 DesignSize = ( - 345 + 393 117) object FtpPingIntervalLabel: TLabel Left = 12 @@ -843,7 +855,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object FtpPingOffButton: TRadioButton Left = 12 Top = 19 - Width = 317 + Width = 365 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Off' @@ -853,7 +865,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object FtpPingNullPacketButton: TRadioButton Left = 12 Top = 42 - Width = 317 + Width = 365 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Sending of &null SSH packets' @@ -864,7 +876,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object FtpPingDummyCommandButton: TRadioButton Left = 12 Top = 65 - Width = 317 + Width = 365 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Executing &dummy protocol commands' @@ -875,11 +887,14 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object TimeoutGroup: TGroupBox Left = 0 Top = 80 - Width = 345 + Width = 393 Height = 46 Anchors = [akLeft, akTop, akRight] Caption = 'Timeouts' TabOrder = 1 + DesignSize = ( + 393 + 46) object Label11: TLabel Left = 12 Top = 19 @@ -889,15 +904,16 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = TimeoutEdit end object Label12: TLabel - Left = 286 + Left = 334 Top = 19 Width = 39 Height = 13 + Anchors = [akTop, akRight] Caption = 'seconds' FocusControl = TimeoutEdit end object TimeoutEdit: TUpDownEdit - Left = 208 + Left = 256 Top = 14 Width = 73 Height = 21 @@ -906,6 +922,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog MaxValue = 6000.000000000000000000 MinValue = 5.000000000000000000 Value = 5.000000000000000000 + Anchors = [akTop, akRight] MaxLength = 4 TabOrder = 0 OnChange = DataChange @@ -914,13 +931,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object PingGroup: TGroupBox Left = 0 Top = 132 - Width = 345 + Width = 393 Height = 117 Anchors = [akLeft, akTop, akRight] Caption = 'Keepalives' TabOrder = 3 DesignSize = ( - 345 + 393 117) object PingIntervalLabel: TLabel Left = 12 @@ -931,7 +948,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = PingIntervalSecEdit end object PingIntervalSecEdit: TUpDownEdit - Left = 208 + Left = 256 Top = 85 Width = 73 Height = 21 @@ -939,6 +956,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog MaxValue = 3600.000000000000000000 MinValue = 1.000000000000000000 Value = 1.000000000000000000 + Anchors = [akTop, akRight] MaxLength = 4 TabOrder = 3 OnChange = DataChange @@ -946,7 +964,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object PingOffButton: TRadioButton Left = 12 Top = 19 - Width = 317 + Width = 365 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Off' @@ -956,7 +974,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object PingNullPacketButton: TRadioButton Left = 12 Top = 42 - Width = 317 + Width = 365 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Sending of &null SSH packets' @@ -966,7 +984,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object PingDummyCommandButton: TRadioButton Left = 12 Top = 65 - Width = 317 + Width = 365 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Executing &dummy protocol commands' @@ -977,20 +995,16 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object IPvGroup: TGroupBox Left = 0 Top = 255 - Width = 345 + Width = 393 Height = 46 Anchors = [akLeft, akTop, akRight] Caption = 'Internet protocol version' TabOrder = 2 - DesignSize = ( - 345 - 46) object IPAutoButton: TRadioButton Left = 12 Top = 19 Width = 101 Height = 17 - Anchors = [akLeft, akTop, akRight] Caption = 'A&uto' TabOrder = 0 OnClick = DataChange @@ -1000,7 +1014,6 @@ object SiteAdvancedDialog: TSiteAdvancedDialog Top = 19 Width = 101 Height = 17 - Anchors = [akLeft, akTop, akRight] Caption = 'IPv&4' TabOrder = 1 OnClick = DataChange @@ -1010,7 +1023,6 @@ object SiteAdvancedDialog: TSiteAdvancedDialog Top = 19 Width = 101 Height = 17 - Anchors = [akLeft, akTop, akRight] Caption = 'IPv&6' TabOrder = 2 OnClick = DataChange @@ -1019,18 +1031,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ConnectionGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 69 Anchors = [akLeft, akTop, akRight] Caption = 'Connection' TabOrder = 0 DesignSize = ( - 345 + 393 69) object FtpPasvModeCheck: TCheckBox Left = 12 Top = 19 - Width = 321 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Passive mode' @@ -1040,7 +1052,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object BufferSizeCheck: TCheckBox Left = 12 Top = 42 - Width = 321 + Width = 369 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Optimize connection &buffer size' @@ -1057,18 +1069,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 8 TabVisible = False DesignSize = ( - 353 + 401 382) object ProxyTypeGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 136 Anchors = [akLeft, akTop, akRight] Caption = 'Proxy' TabOrder = 0 DesignSize = ( - 345 + 393 136) object ProxyMethodLabel: TLabel Left = 12 @@ -1087,7 +1099,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = ProxyHostEdit end object ProxyPortLabel: TLabel - Left = 252 + Left = 284 Top = 41 Width = 63 Height = 13 @@ -1104,7 +1116,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = ProxyUsernameEdit end object ProxyPasswordLabel: TLabel - Left = 163 + Left = 200 Top = 85 Width = 50 Height = 13 @@ -1128,9 +1140,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog 'Local') end object ProxyPortEdit: TUpDownEdit - Left = 252 + Left = 284 Top = 58 - Width = 82 + Width = 98 Height = 21 Alignment = taRightJustify MaxValue = 65535.000000000000000000 @@ -1143,7 +1155,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ProxyHostEdit: TEdit Left = 12 Top = 58 - Width = 226 + Width = 266 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 50 @@ -1154,7 +1166,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ProxyUsernameEdit: TEdit Left = 12 Top = 102 - Width = 137 + Width = 182 Height = 21 MaxLength = 50 TabOrder = 5 @@ -1162,9 +1174,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnChange = DataChange end object ProxyPasswordEdit: TPasswordEdit - Left = 163 + Left = 200 Top = 102 - Width = 171 + Width = 182 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 50 @@ -1175,9 +1187,10 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object FtpProxyMethodCombo: TComboBox Left = 128 Top = 15 - Width = 206 + Width = 254 Height = 21 Style = csDropDownList + Anchors = [akLeft, akTop, akRight] DropDownCount = 12 TabOrder = 1 OnChange = DataChange @@ -1213,13 +1226,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ProxySettingsGroup: TGroupBox Left = 0 Top = 147 - Width = 345 + Width = 393 Height = 128 Anchors = [akLeft, akTop, akRight] Caption = 'Proxy settings' TabOrder = 1 DesignSize = ( - 345 + 393 128) object ProxyTelnetCommandLabel: TLabel Left = 12 @@ -1247,7 +1260,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ProxyTelnetCommandEdit: TEdit Left = 12 Top = 35 - Width = 322 + Width = 370 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 255 @@ -1258,15 +1271,16 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ProxyLocalhostCheck: TCheckBox Left = 12 Top = 77 - Width = 313 + Width = 370 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = 'Co&nsider proxying local host connections' TabOrder = 5 end object ProxyDNSCombo: TComboBox Left = 252 Top = 94 - Width = 82 + Width = 130 Height = 21 Style = csDropDownList Anchors = [akLeft, akTop, akRight] @@ -1279,7 +1293,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object ProxyLocalCommandEdit: TEdit Left = 12 Top = 35 - Width = 226 + Width = 274 Height = 21 Anchors = [akLeft, akTop, akRight] TabOrder = 2 @@ -1287,7 +1301,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnChange = DataChange end object ProxyLocalCommandBrowseButton: TButton - Left = 252 + Left = 300 Top = 33 Width = 82 Height = 25 @@ -1297,7 +1311,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnClick = ProxyLocalCommandBrowseButtonClick end object ProxyTelnetCommandHintText: TStaticText - Left = 255 + Left = 303 Top = 58 Width = 79 Height = 16 @@ -1309,7 +1323,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog TabStop = True end object ProxyLocalCommandHintText: TStaticText - Left = 159 + Left = 207 Top = 58 Width = 79 Height = 16 @@ -1330,18 +1344,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 14 TabVisible = False DesignSize = ( - 353 + 401 382) object TunnelSessionGroup: TGroupBox Left = 0 Top = 32 - Width = 345 + Width = 393 Height = 118 Anchors = [akLeft, akTop, akRight] Caption = 'Host to setup tunnel on' TabOrder = 1 DesignSize = ( - 345 + 393 118) object Label6: TLabel Left = 12 @@ -1352,7 +1366,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = TunnelHostNameEdit end object Label14: TLabel - Left = 252 + Left = 284 Top = 18 Width = 63 Height = 13 @@ -1369,7 +1383,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = TunnelUserNameEdit end object Label16: TLabel - Left = 163 + Left = 200 Top = 68 Width = 50 Height = 13 @@ -1379,7 +1393,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object TunnelHostNameEdit: TEdit Left = 12 Top = 35 - Width = 226 + Width = 266 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 100 @@ -1390,7 +1404,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object TunnelUserNameEdit: TEdit Left = 12 Top = 85 - Width = 137 + Width = 182 Height = 21 MaxLength = 50 TabOrder = 1 @@ -1398,9 +1412,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnChange = DataChange end object TunnelPasswordEdit: TPasswordEdit - Left = 163 + Left = 200 Top = 85 - Width = 171 + Width = 182 Height = 21 Anchors = [akLeft, akTop, akRight] MaxLength = 50 @@ -1409,9 +1423,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnChange = DataChange end object TunnelPortNumberEdit: TUpDownEdit - Left = 252 + Left = 284 Top = 35 - Width = 82 + Width = 98 Height = 21 Alignment = taRightJustify MaxValue = 65535.000000000000000000 @@ -1423,10 +1437,11 @@ object SiteAdvancedDialog: TSiteAdvancedDialog end end object TunnelCheck: TCheckBox - Left = 11 + Left = 12 Top = 8 - Width = 307 + Width = 382 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Connect through SSH tunnel' TabOrder = 0 OnClick = DataChange @@ -1434,13 +1449,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object TunnelOptionsGroup: TGroupBox Left = 0 Top = 156 - Width = 345 + Width = 393 Height = 47 Anchors = [akLeft, akTop, akRight] Caption = 'Tunnel options' TabOrder = 2 DesignSize = ( - 345 + 393 47) object Label21: TLabel Left = 12 @@ -1451,12 +1466,12 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = TunnelLocalPortNumberEdit end object TunnelLocalPortNumberEdit: TComboBox - Left = 252 + Left = 284 Top = 15 - Width = 82 + Width = 98 Height = 21 AutoComplete = False - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] MaxLength = 50 TabOrder = 0 Text = 'TunnelLocalPortNumberEdit' @@ -1468,13 +1483,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object TunnelAuthenticationParamsGroup: TGroupBox Left = 0 Top = 209 - Width = 345 + Width = 393 Height = 68 Anchors = [akLeft, akTop, akRight] Caption = 'Tunnel authentication parameters' TabOrder = 3 DesignSize = ( - 345 + 393 68) object Label18: TLabel Left = 12 @@ -1487,7 +1502,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object TunnelPrivateKeyEdit: TFilenameEdit Left = 12 Top = 35 - Width = 322 + Width = 370 Height = 21 AcceptFiles = True OnBeforeDialog = PathEditBeforeDialog @@ -1511,19 +1526,19 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 13 TabVisible = False DesignSize = ( - 353 + 401 382) object SslGroup: TGroupBox Left = 0 Top = 6 - Width = 345 - Height = 71 + Width = 393 + Height = 99 Anchors = [akLeft, akTop, akRight] Caption = 'TLS/SSL options' TabOrder = 0 DesignSize = ( - 345 - 71) + 393 + 99) object Label1: TLabel Left = 12 Top = 20 @@ -1541,7 +1556,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = MaxTlsVersionCombo end object MinTlsVersionCombo: TComboBox - Left = 256 + Left = 304 Top = 15 Width = 77 Height = 21 @@ -1557,7 +1572,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog 'TLS 1.2') end object MaxTlsVersionCombo: TComboBox - Left = 256 + Left = 304 Top = 39 Width = 77 Height = 21 @@ -1572,6 +1587,16 @@ object SiteAdvancedDialog: TSiteAdvancedDialog 'TLS 1.1' 'TLS 1.2') end + object SslSessionReuseCheck: TCheckBox + Left = 12 + Top = 68 + Width = 365 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = '&Reuse TLS/SSL session ID for data connections' + TabOrder = 2 + OnClick = DataChange + end end end object AdvancedSheet: TTabSheet @@ -1582,18 +1607,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 2 TabVisible = False DesignSize = ( - 353 + 401 382) object ProtocolGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 87 Anchors = [akLeft, akTop, akRight] Caption = 'Protocol options' TabOrder = 0 DesignSize = ( - 345 + 393 87) object Label7: TLabel Left = 12 @@ -1604,27 +1629,27 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = SshProt1onlyButton end object SshProt1Button: TRadioButton - Left = 88 + Left = 96 Top = 59 - Width = 65 + Width = 74 Height = 17 Caption = '&1' TabOrder = 2 OnClick = DataChange end object SshProt2Button: TRadioButton - Left = 160 + Left = 176 Top = 59 - Width = 65 + Width = 74 Height = 17 Caption = '&2' TabOrder = 3 OnClick = DataChange end object CompressionCheck: TCheckBox - Left = 12 + Left = 16 Top = 19 - Width = 324 + Width = 367 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Enable &compression' @@ -1634,7 +1659,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object SshProt1onlyButton: TRadioButton Left = 16 Top = 59 - Width = 65 + Width = 74 Height = 17 Caption = '1 on&ly' Checked = True @@ -1643,9 +1668,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnClick = DataChange end object SshProt2onlyButton: TRadioButton - Left = 232 + Left = 256 Top = 59 - Width = 65 + Width = 74 Height = 17 Caption = '2 o&nly' TabOrder = 4 @@ -1655,13 +1680,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object EncryptionGroup: TGroupBox Left = 0 Top = 100 - Width = 345 + Width = 393 Height = 163 Anchors = [akLeft, akTop, akRight] Caption = 'Encryption options' TabOrder = 1 DesignSize = ( - 345 + 393 163) object Label8: TLabel Left = 12 @@ -1674,8 +1699,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object CipherListBox: TListBox Left = 12 Top = 36 - Width = 190 + Width = 285 Height = 91 + Anchors = [akLeft, akTop, akRight] DragMode = dmAutomatic ItemHeight = 13 TabOrder = 0 @@ -1687,26 +1713,28 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object Ssh2LegacyDESCheck: TCheckBox Left = 16 Top = 134 - Width = 317 + Width = 367 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Enable legacy use of single-&DES in SSH-2' TabOrder = 3 end object CipherUpButton: TButton - Left = 211 + Left = 303 Top = 36 - Width = 70 + Width = 80 Height = 25 + Anchors = [akTop, akRight] Caption = '&Up' TabOrder = 1 OnClick = CipherButtonClick end object CipherDownButton: TButton - Left = 211 + Left = 303 Top = 68 - Width = 70 + Width = 80 Height = 25 + Anchors = [akTop, akRight] Caption = '&Down' TabOrder = 2 OnClick = CipherButtonClick @@ -1721,16 +1749,19 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 13 TabVisible = False DesignSize = ( - 353 + 401 382) object KexOptionsGroup: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 137 Anchors = [akLeft, akTop, akRight] Caption = 'Key exchange algorithm options' TabOrder = 0 + DesignSize = ( + 393 + 137) object Label28: TLabel Left = 12 Top = 19 @@ -1742,8 +1773,9 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object KexListBox: TListBox Left = 12 Top = 36 - Width = 190 + Width = 285 Height = 89 + Anchors = [akLeft, akTop, akRight] DragMode = dmAutomatic ItemHeight = 13 TabOrder = 0 @@ -1753,19 +1785,21 @@ object SiteAdvancedDialog: TSiteAdvancedDialog OnStartDrag = AlgListBoxStartDrag end object KexUpButton: TButton - Left = 211 + Left = 303 Top = 36 - Width = 70 + Width = 80 Height = 25 + Anchors = [akTop, akRight] Caption = '&Up' TabOrder = 1 OnClick = KexButtonClick end object KexDownButton: TButton - Left = 211 + Left = 303 Top = 68 - Width = 70 + Width = 80 Height = 25 + Anchors = [akTop, akRight] Caption = '&Down' TabOrder = 2 OnClick = KexButtonClick @@ -1774,11 +1808,14 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object KexReexchangeGroup: TGroupBox Left = 0 Top = 150 - Width = 345 + Width = 393 Height = 69 Anchors = [akLeft, akTop, akRight] Caption = 'Options controlling key re-exchange' TabOrder = 1 + DesignSize = ( + 393 + 69) object Label31: TLabel Left = 12 Top = 20 @@ -1800,21 +1837,23 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ParentColor = False end object RekeyTimeEdit: TUpDownEdit - Left = 256 - Top = 15 - Width = 73 + Left = 303 + Top = 12 + Width = 80 Height = 21 Alignment = taRightJustify MaxValue = 1440.000000000000000000 + Anchors = [akTop, akRight] MaxLength = 4 TabOrder = 0 OnChange = DataChange end object RekeyDataEdit: TEdit - Left = 256 + Left = 303 Top = 39 - Width = 73 + Width = 80 Height = 21 + Anchors = [akTop, akRight] MaxLength = 10 TabOrder = 1 OnChange = DataChange @@ -1829,13 +1868,14 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 10 TabVisible = False DesignSize = ( - 353 + 401 382) object SshNoUserAuthCheck: TCheckBox Left = 12 Top = 8 - Width = 307 + Width = 382 Height = 17 + Anchors = [akLeft, akTop, akRight] Caption = '&Bypass authentication entirely (SSH-2)' TabOrder = 0 OnClick = DataChange @@ -1843,18 +1883,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AuthenticationGroup: TGroupBox Left = 0 Top = 32 - Width = 345 + Width = 393 Height = 117 Anchors = [akLeft, akTop, akRight] Caption = 'Authentication options' TabOrder = 1 DesignSize = ( - 345 + 393 117) object TryAgentCheck: TCheckBox Left = 12 Top = 19 - Width = 325 + Width = 373 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Attempt authentication using &Pageant' @@ -1864,7 +1904,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AuthTISCheck: TCheckBox Left = 12 Top = 42 - Width = 325 + Width = 373 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Atte&mpt TIS or CryptoCard authentication (SSH-1)' @@ -1874,7 +1914,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AuthKICheck: TCheckBox Left = 12 Top = 65 - Width = 325 + Width = 373 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Attempt '#39'keyboard-&interactive'#39' authentication (SSH-2)' @@ -1884,7 +1924,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AuthKIPasswordCheck: TCheckBox Left = 32 Top = 88 - Width = 305 + Width = 353 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Respond with pass&word to the first prompt' @@ -1895,13 +1935,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AuthenticationParamsGroup: TGroupBox Left = 2 Top = 154 - Width = 345 + Width = 393 Height = 94 Anchors = [akLeft, akTop, akRight] Caption = 'Authentication parameters' TabOrder = 2 DesignSize = ( - 345 + 393 94) object PrivateKeyLabel: TLabel Left = 12 @@ -1914,7 +1954,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object AgentFwdCheck: TCheckBox Left = 12 Top = 19 - Width = 325 + Width = 373 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Allow agent &forwarding' @@ -1924,7 +1964,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object PrivateKeyEdit: TFilenameEdit Left = 12 Top = 59 - Width = 324 + Width = 372 Height = 21 AcceptFiles = True OnBeforeDialog = PathEditBeforeDialog @@ -1942,18 +1982,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object GSSAPIGroup: TGroupBox Left = 0 Top = 254 - Width = 345 + Width = 393 Height = 71 Anchors = [akLeft, akTop, akRight] Caption = 'GSSAPI' TabOrder = 3 DesignSize = ( - 345 + 393 71) object AuthGSSAPICheck3: TCheckBox Left = 12 Top = 19 - Width = 325 + Width = 373 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Attempt &GSSAPI authentication (SSH-2)' @@ -1963,7 +2003,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog object GSSAPIFwdTGTCheck: TCheckBox Left = 12 Top = 42 - Width = 325 + Width = 373 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = 'Allow GSSAPI &credential delegation' @@ -1980,18 +2020,18 @@ object SiteAdvancedDialog: TSiteAdvancedDialog ImageIndex = 9 TabVisible = False DesignSize = ( - 353 + 401 382) object BugsGroupBox: TGroupBox Left = 0 Top = 6 - Width = 345 + Width = 393 Height = 265 Anchors = [akLeft, akTop, akRight] Caption = 'Detection of known bugs in SSH servers' TabOrder = 0 DesignSize = ( - 345 + 393 265) object BugIgnore1Label: TLabel Left = 12 @@ -2074,102 +2114,102 @@ object SiteAdvancedDialog: TSiteAdvancedDialog FocusControl = BugIgnore2Combo end object BugIgnore1Combo: TComboBox - Left = 272 + Left = 320 Top = 15 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 0 OnChange = DataChange end object BugPlainPW1Combo: TComboBox - Left = 272 + Left = 320 Top = 39 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 1 OnChange = DataChange end object BugRSA1Combo: TComboBox - Left = 272 + Left = 320 Top = 63 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 2 OnChange = DataChange end object BugHMAC2Combo: TComboBox - Left = 272 + Left = 320 Top = 111 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 4 OnChange = DataChange end object BugDeriveKey2Combo: TComboBox - Left = 272 + Left = 320 Top = 135 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 5 OnChange = DataChange end object BugRSAPad2Combo: TComboBox - Left = 272 + Left = 320 Top = 159 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 6 OnChange = DataChange end object BugPKSessID2Combo: TComboBox - Left = 272 + Left = 320 Top = 183 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 7 OnChange = DataChange end object BugRekey2Combo: TComboBox - Left = 272 + Left = 320 Top = 207 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 8 OnChange = DataChange end object BugMaxPkt2Combo: TComboBox - Left = 272 + Left = 320 Top = 231 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 9 OnChange = DataChange end object BugIgnore2Combo: TComboBox - Left = 272 + Left = 320 Top = 87 Width = 61 Height = 21 Style = csDropDownList - Anchors = [akLeft, akTop, akRight] + Anchors = [akTop, akRight] TabOrder = 3 OnChange = DataChange end @@ -2230,7 +2270,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog end end object OKBtn: TButton - Left = 259 + Left = 307 Top = 401 Width = 75 Height = 25 @@ -2241,7 +2281,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog TabOrder = 1 end object CancelBtn: TButton - Left = 344 + Left = 392 Top = 401 Width = 75 Height = 25 @@ -2252,7 +2292,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog TabOrder = 2 end object HelpButton: TButton - Left = 427 + Left = 475 Top = 401 Width = 75 Height = 25 diff --git a/source/forms/SiteAdvanced.h b/source/forms/SiteAdvanced.h index 9ce7f0f83..b81981e0c 100644 --- a/source/forms/SiteAdvanced.h +++ b/source/forms/SiteAdvanced.h @@ -245,6 +245,7 @@ __published: TComboBox *MinTlsVersionCombo; TLabel *Label2; TComboBox *MaxTlsVersionCombo; + TCheckBox *SslSessionReuseCheck; void __fastcall DataChange(TObject *Sender); void __fastcall FormShow(TObject *Sender); void __fastcall PageControlChange(TObject *Sender); diff --git a/source/forms/Symlink.cpp b/source/forms/Symlink.cpp index cdb58692f..50ed1ac48 100644 --- a/source/forms/Symlink.cpp +++ b/source/forms/Symlink.cpp @@ -114,7 +114,7 @@ void __fastcall TSymlinkDialog::SetAllowSymbolic(bool value) //--------------------------------------------------------------------------- bool __fastcall TSymlinkDialog::Execute() { - return ShowModal() == mrOk; + return (ShowModal() == DefaultResult(this)); } //--------------------------------------------------------------------------- void __fastcall TSymlinkDialog::FormShow(TObject * /*Sender*/) diff --git a/source/forms/Symlink.dfm b/source/forms/Symlink.dfm index 67df86b87..95356a5e5 100644 --- a/source/forms/Symlink.dfm +++ b/source/forms/Symlink.dfm @@ -9,11 +9,7 @@ object SymlinkDialog: TSymlinkDialog ClientHeight = 183 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 OnShow = FormShow @@ -35,7 +31,7 @@ object SymlinkDialog: TSymlinkDialog object FileNameLabel: TLabel Left = 11 Top = 16 - Width = 82 + Width = 83 Height = 13 Caption = '&Link/shortcut file:' FocusControl = FileNameEdit @@ -43,7 +39,7 @@ object SymlinkDialog: TSymlinkDialog object Label1: TLabel Left = 11 Top = 64 - Width = 101 + Width = 103 Height = 13 Caption = '&Point link/shortcut to:' FocusControl = PointToEdit diff --git a/source/forms/Synchronize.cpp b/source/forms/Synchronize.cpp index 6feb963d0..dc4b28ef1 100644 --- a/source/forms/Synchronize.cpp +++ b/source/forms/Synchronize.cpp @@ -218,13 +218,13 @@ void __fastcall TSynchronizeDialog::SetOptions(int value) } } //--------------------------------------------------------------------------- -void __fastcall TSynchronizeDialog::CopyParamListPopup(TPoint P, int AdditionalOptions) +void __fastcall TSynchronizeDialog::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()); } //--------------------------------------------------------------------------- @@ -233,9 +233,7 @@ void __fastcall TSynchronizeDialog::TransferSettingsButtonClick( { if (FLAGCLEAR(FOptions, soDoNotUsePresets) && !SupportsSplitButton()) { - CopyParamListPopup( - TransferSettingsButton->ClientToScreen(TPoint(0, TransferSettingsButton->Height)), - 0); + CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0); } else { @@ -490,7 +488,7 @@ void __fastcall TSynchronizeDialog::CopyParamGroupContextPopup( { if (FLAGCLEAR(FOptions, soDoNotUsePresets)) { - CopyParamListPopup(CopyParamGroup->ClientToScreen(MousePos), + CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault); Handled = true; } @@ -558,8 +556,6 @@ void __fastcall TSynchronizeDialog::FormKeyDown(TObject * /*Sender*/, WORD & Key //--------------------------------------------------------------------------- void __fastcall TSynchronizeDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/) { - CopyParamListPopup( - TransferSettingsButton->ClientToScreen(TPoint(0, TransferSettingsButton->Height)), - cplCustomizeDefault); + CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault); } //--------------------------------------------------------------------------- diff --git a/source/forms/Synchronize.dfm b/source/forms/Synchronize.dfm index 2d7c13bbc..cb95fa096 100644 --- a/source/forms/Synchronize.dfm +++ b/source/forms/Synchronize.dfm @@ -7,13 +7,9 @@ object SynchronizeDialog: TSynchronizeDialog BorderStyle = bsDialog Caption = 'Keep remote directory up to date X' ClientHeight = 421 - ClientWidth = 396 + ClientWidth = 436 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 Position = poOwnerFormCenter @@ -21,25 +17,25 @@ object SynchronizeDialog: TSynchronizeDialog OnKeyDown = FormKeyDown OnShow = FormShow DesignSize = ( - 396 + 436 421) PixelsPerInch = 96 TextHeight = 13 object DirectoriesGroup: TGroupBox Left = 8 Top = 6 - Width = 381 + Width = 421 Height = 119 Anchors = [akLeft, akTop, akRight] Caption = 'Directories' TabOrder = 0 DesignSize = ( - 381 + 421 119) object LocalDirectoryLabel: TLabel Left = 11 Top = 19 - Width = 191 + Width = 235 Height = 13 Anchors = [akLeft, akTop, akRight] Caption = '&Watch for changes in the local directory:' @@ -48,7 +44,7 @@ object SynchronizeDialog: TSynchronizeDialog object RemoteDirectoryLabel: TLabel Left = 11 Top = 68 - Width = 266 + Width = 321 Height = 13 Anchors = [akLeft, akTop, akRight] Caption = '... &and automatically reflect them on the remote directory:' @@ -57,7 +53,7 @@ object SynchronizeDialog: TSynchronizeDialog object RemoteDirectoryEdit: THistoryComboBox Left = 11 Top = 84 - Width = 359 + Width = 399 Height = 21 AutoComplete = False Anchors = [akLeft, akTop, akRight] @@ -69,7 +65,7 @@ object SynchronizeDialog: TSynchronizeDialog object LocalDirectoryEdit: THistoryComboBox Left = 11 Top = 35 - Width = 276 + Width = 316 Height = 21 AutoComplete = False Anchors = [akLeft, akTop, akRight] @@ -79,7 +75,7 @@ object SynchronizeDialog: TSynchronizeDialog OnChange = ControlChange end object LocalDirectoryBrowseButton: TButton - Left = 293 + Left = 335 Top = 33 Width = 75 Height = 25 @@ -90,19 +86,21 @@ object SynchronizeDialog: TSynchronizeDialog end end object StopButton: TButton - Left = 152 + Left = 192 Top = 288 Width = 74 Height = 25 + Anchors = [akTop, akRight] Caption = '&Stop' TabOrder = 4 OnClick = StopButtonClick end object CancelButton: TButton - Left = 232 + Left = 272 Top = 288 Width = 74 Height = 25 + Anchors = [akTop, akRight] Cancel = True Caption = 'Close' ModalResult = 2 @@ -111,18 +109,18 @@ object SynchronizeDialog: TSynchronizeDialog object OptionsGroup: TGroupBox Left = 8 Top = 130 - Width = 381 + Width = 421 Height = 95 Anchors = [akLeft, akTop, akRight] Caption = 'Synchronize options' TabOrder = 1 DesignSize = ( - 381 + 421 95) object SynchronizeDeleteCheck: TCheckBox Left = 11 Top = 20 - Width = 182 + Width = 196 Height = 17 Caption = '&Delete files' TabOrder = 0 @@ -131,16 +129,16 @@ object SynchronizeDialog: TSynchronizeDialog object SaveSettingsCheck: TCheckBox Left = 11 Top = 68 - Width = 182 + Width = 196 Height = 17 Caption = 'Use same &options next time' TabOrder = 4 OnClick = ControlChange end object SynchronizeExistingOnlyCheck: TCheckBox - Left = 203 + Left = 213 Top = 20 - Width = 166 + Width = 197 Height = 17 Anchors = [akLeft, akTop, akRight] Caption = '&Existing files only' @@ -150,16 +148,16 @@ object SynchronizeDialog: TSynchronizeDialog object SynchronizeRecursiveCheck: TCheckBox Left = 11 Top = 44 - Width = 182 + Width = 196 Height = 17 Caption = 'Update s&ubdirectories' TabOrder = 2 OnClick = ControlChange end object SynchronizeSynchronizeCheck: TGrayedCheckBox - Left = 203 + Left = 213 Top = 68 - Width = 166 + Width = 197 Height = 17 AllowGrayed = True Anchors = [akLeft, akTop, akRight] @@ -168,9 +166,9 @@ object SynchronizeDialog: TSynchronizeDialog OnClick = ControlChange end object SynchronizeSelectedOnlyCheck: TCheckBox - Left = 203 + Left = 213 Top = 44 - Width = 166 + Width = 197 Height = 17 Caption = 'Selected files o&nly' TabOrder = 3 @@ -178,7 +176,7 @@ object SynchronizeDialog: TSynchronizeDialog end end object StartButton: TButton - Left = 152 + Left = 192 Top = 288 Width = 74 Height = 25 @@ -189,7 +187,7 @@ object SynchronizeDialog: TSynchronizeDialog OnClick = StartButtonClick end object MinimizeButton: TButton - Left = 233 + Left = 273 Top = 288 Width = 74 Height = 25 @@ -201,7 +199,7 @@ object SynchronizeDialog: TSynchronizeDialog object TransferSettingsButton: TButton Left = 8 Top = 288 - Width = 137 + Width = 161 Height = 25 Caption = 'Transfer settin&gs...' TabOrder = 2 @@ -211,19 +209,20 @@ object SynchronizeDialog: TSynchronizeDialog object CopyParamGroup: TGroupBox Left = 8 Top = 230 - Width = 381 + Width = 421 Height = 50 + Anchors = [akLeft, akTop, akRight] Caption = 'Transfer settings' TabOrder = 7 OnClick = CopyParamGroupClick OnContextPopup = CopyParamGroupContextPopup DesignSize = ( - 381 + 421 50) object CopyParamLabel: TLabel Left = 7 Top = 15 - Width = 367 + Width = 407 Height = 26 Anchors = [akLeft, akTop, akRight, akBottom] AutoSize = False @@ -233,7 +232,7 @@ object SynchronizeDialog: TSynchronizeDialog end end object HelpButton: TButton - Left = 313 + Left = 353 Top = 288 Width = 75 Height = 25 @@ -245,18 +244,18 @@ object SynchronizeDialog: TSynchronizeDialog object LogPanel: TPanel Left = 0 Top = 321 - Width = 396 + Width = 436 Height = 100 Align = alBottom BevelOuter = bvNone TabOrder = 9 DesignSize = ( - 396 + 436 100) object LogView: TListView Left = 8 Top = 2 - Width = 380 + Width = 420 Height = 90 Anchors = [akLeft, akTop, akRight, akBottom] Columns = < @@ -271,10 +270,6 @@ object SynchronizeDialog: TSynchronizeDialog -1) end> DoubleBuffered = True - Items.ItemData = { - 03510000000100000000000000FFFFFFFFFFFFFFFF01000000FFFFFFFF000000 - 000B320030003A00330030003A0034003500200050004D000F44006500740065 - 00630074006500640020006300680061006E0067006500FFFF} ReadOnly = True RowSelect = True ParentDoubleBuffered = False diff --git a/source/forms/Synchronize.h b/source/forms/Synchronize.h index 1a2bb8749..6ead8bd18 100644 --- a/source/forms/Synchronize.h +++ b/source/forms/Synchronize.h @@ -95,7 +95,7 @@ protected: void __fastcall CopyLog(); int __fastcall ActualCopyParamAttrs(); void __fastcall GlobalMinimize(TObject * Sender); - void __fastcall CopyParamListPopup(TPoint P, int AdditionalOptions); + void __fastcall CopyParamListPopup(TRect R, int AdditionalOptions); public: __fastcall TSynchronizeDialog(TComponent * Owner, diff --git a/source/forms/SynchronizeChecklist.cpp b/source/forms/SynchronizeChecklist.cpp index 1f9d7ea13..026702d24 100644 --- a/source/forms/SynchronizeChecklist.cpp +++ b/source/forms/SynchronizeChecklist.cpp @@ -54,6 +54,8 @@ __fastcall TSynchronizeChecklistDialog::TSynchronizeChecklistDialog( FRemoteDirectory = UnixExcludeTrailingBackslash(RemoteDirectory); FOnCustomCommandMenu = OnCustomCommandMenu; UseSystemSettings(this); + UseDesktopFont(ListView); + UseDesktopFont(StatusBar); FChecklist = NULL; FChangingItem = NULL; FChangingItemIgnore = false; @@ -71,6 +73,7 @@ __fastcall TSynchronizeChecklistDialog::TSynchronizeChecklistDialog( ListView->HeaderImages = ArrowImages; CustomCommandsButton->Visible = (FOnCustomCommandMenu != NULL); + MenuButton(CustomCommandsButton); } //--------------------------------------------------------------------- __fastcall TSynchronizeChecklistDialog::~TSynchronizeChecklistDialog() @@ -83,7 +86,7 @@ bool __fastcall TSynchronizeChecklistDialog::Execute(TSynchronizeChecklist * Che { FChecklist = Checklist; - bool Result = (ShowModal() != mrCancel); + bool Result = (ShowModal() == DefaultResult(this)); if (Result) { @@ -374,7 +377,7 @@ void __fastcall TSynchronizeChecklistDialog::ListViewWindowProc(TMessage & Messa // doing this from ListViewAdvancedCustomDraw corrupts list view on Windows 7 ImageList_Draw(reinterpret_cast(ActionImages->Handle), int(ChecklistItem->Action), CustomDraw->nmcd.hdc, - R.Left, R.Top, ILD_TRANSPARENT); + R.Left, ((R.Top + R.Bottom - ActionImages->Height) / 2), ILD_TRANSPARENT); } } } @@ -451,9 +454,14 @@ void __fastcall TSynchronizeChecklistDialog::StatusBarDrawPanel( PanelText = LoadStrPart(SYNCHRONIZE_SELECTED_ACTIONS, 2); } - StatusBar->Canvas->TextRect(Rect, Rect.left + 18, Rect.top + 1, PanelText); - ActionImages->Draw(StatusBar->Canvas, - Rect.Left + 1, Rect.Top, ImageIndex, Possible); + int TextHeight = StatusBar->Canvas->TextHeight(PanelText); + int X = Rect.Left + ActionImages->Width + 4; + int Y = (Rect.Top + Rect.Bottom - TextHeight) / 2; + StatusBar->Canvas->TextRect(Rect, X, Y, PanelText); + + X = Rect.Left + 1; + Y = ((Rect.Top + Rect.Bottom - ActionImages->Height) / 2); + ActionImages->Draw(StatusBar->Canvas, X, Y, ImageIndex, Possible); } //--------------------------------------------------------------------------- int __fastcall TSynchronizeChecklistDialog::PanelAt(int X) @@ -593,12 +601,6 @@ void __fastcall TSynchronizeChecklistDialog::ListViewSelectItem( UpdateTimer->Enabled = true; } //--------------------------------------------------------------------------- -void __fastcall TSynchronizeChecklistDialog::StatusBarResize( - TObject * Sender) -{ - RepaintStatusBar(dynamic_cast(Sender)); -} -//--------------------------------------------------------------------------- void __fastcall TSynchronizeChecklistDialog::UpdateTimerTimer( TObject * /*Sender*/) { @@ -819,7 +821,6 @@ void __fastcall TSynchronizeChecklistDialog::CustomCommandsButtonClick( assert(FOnCustomCommandMenu != NULL); FOnCustomCommandMenu(CustomCommandsButton, - CustomCommandsButton->ClientToScreen(TPoint(0, CustomCommandsButton->Height)), - LocalFileList, RemoteFileList); + CalculatePopupRect(CustomCommandsButton), LocalFileList, RemoteFileList); } //--------------------------------------------------------------------------- diff --git a/source/forms/SynchronizeChecklist.dfm b/source/forms/SynchronizeChecklist.dfm index 1cce4d0bf..1d73afb7c 100644 --- a/source/forms/SynchronizeChecklist.dfm +++ b/source/forms/SynchronizeChecklist.dfm @@ -55,18 +55,22 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog PixelsPerInch = 96 TextHeight = 13 object Panel: TPanel - Left = 579 + Left = 571 Top = 0 - Width = 116 + Width = 124 Height = 402 Align = alRight BevelOuter = bvNone TabOrder = 1 + DesignSize = ( + 124 + 402) object OkButton: TButton Left = 8 Top = 8 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = 'OK' Default = True ModalResult = 1 @@ -75,8 +79,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog object CancelButton: TButton Left = 8 Top = 40 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Cancel = True Caption = 'Cancel' ModalResult = 2 @@ -85,8 +90,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog object CheckAllButton: TButton Left = 8 Top = 182 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = 'Check &all' TabOrder = 5 OnClick = CheckAllButtonClick @@ -94,8 +100,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog object UncheckAllButton: TButton Left = 8 Top = 214 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = 'Uncheck a&ll' TabOrder = 6 OnClick = CheckAllButtonClick @@ -104,8 +111,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog Tag = 1 Left = 8 Top = 118 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = '&Check' TabOrder = 3 OnClick = CheckButtonClick @@ -113,8 +121,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog object UncheckButton: TButton Left = 8 Top = 150 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = '&Uncheck' TabOrder = 4 OnClick = CheckButtonClick @@ -122,8 +131,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog object HelpButton: TButton Left = 8 Top = 72 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = '&Help' TabOrder = 2 OnClick = HelpButtonClick @@ -132,8 +142,9 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog Tag = 1 Left = 8 Top = 260 - Width = 100 + Width = 108 Height = 25 + Anchors = [akLeft, akTop, akRight] Caption = 'Custom co&mmands' TabOrder = 7 OnClick = CustomCommandsButtonClick @@ -142,7 +153,7 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog object ListView: TIEListView Left = 0 Top = 0 - Width = 579 + Width = 571 Height = 402 Align = alClient Checkboxes = True @@ -203,6 +214,11 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog Width = 695 Height = 20 Hint = 'Click to select all actions of this type' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBtnText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] Panels = < item Style = psOwnerDraw @@ -244,10 +260,10 @@ object SynchronizeChecklistDialog: TSynchronizeChecklistDialog end> ParentShowHint = False ShowHint = True + UseSystemFont = False OnMouseDown = StatusBarMouseDown OnMouseMove = StatusBarMouseMove OnDrawPanel = StatusBarDrawPanel - OnResize = StatusBarResize end object ActionImages: TPngImageList PngImages = < diff --git a/source/forms/SynchronizeChecklist.h b/source/forms/SynchronizeChecklist.h index 954c990fe..0c66d299d 100644 --- a/source/forms/SynchronizeChecklist.h +++ b/source/forms/SynchronizeChecklist.h @@ -51,7 +51,6 @@ __published: void __fastcall CheckButtonClick(TObject *Sender); void __fastcall ListViewSelectItem(TObject *Sender, TListItem *Item, bool Selected); - void __fastcall StatusBarResize(TObject *Sender); void __fastcall UpdateTimerTimer(TObject *Sender); void __fastcall SelectAllItemClick(TObject *Sender); void __fastcall StatusBarMouseDown(TObject *Sender, TMouseButton Button, diff --git a/source/forms/SynchronizeProgress.dfm b/source/forms/SynchronizeProgress.dfm index cc508d207..1ef86d9cf 100644 --- a/source/forms/SynchronizeProgress.dfm +++ b/source/forms/SynchronizeProgress.dfm @@ -5,13 +5,13 @@ object SynchronizeProgressForm: TSynchronizeProgressForm BorderStyle = bsDialog Caption = 'Synchronization X' ClientHeight = 127 - ClientWidth = 370 + ClientWidth = 382 Color = clBtnFace ParentFont = True OldCreateOrder = False Position = poOwnerFormCenter DesignSize = ( - 370 + 382 127) PixelsPerInch = 96 TextHeight = 13 @@ -30,8 +30,8 @@ object SynchronizeProgressForm: TSynchronizeProgressForm Caption = 'Remote:' end object RemoteDirectoryLabel: TPathLabel - Left = 88 - Top = 29 + Left = 101 + Top = 30 Width = 273 Height = 13 UnixPath = True @@ -42,7 +42,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm AutoSize = False end object LocalDirectoryLabel: TPathLabel - Left = 88 + Left = 100 Top = 9 Width = 273 Height = 13 @@ -53,7 +53,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm AutoSize = False end object StartTimeLabel: TLabel - Left = 88 + Left = 100 Top = 49 Width = 81 Height = 13 @@ -75,7 +75,7 @@ object SynchronizeProgressForm: TSynchronizeProgressForm Caption = 'Time elapsed:' end object TimeElapsedLabel: TLabel - Left = 88 + Left = 100 Top = 69 Width = 79 Height = 13 @@ -83,21 +83,21 @@ object SynchronizeProgressForm: TSynchronizeProgressForm Caption = '00:00:00' end object CancelButton: TButton - Left = 105 - Top = 93 + Left = 222 + Top = 94 Width = 73 Height = 25 - Anchors = [akLeft, akBottom] + Anchors = [akRight, akBottom] Caption = 'Cancel' TabOrder = 0 OnClick = CancelButtonClick end object MinimizeButton: TButton - Left = 190 - Top = 93 + Left = 301 + Top = 94 Width = 73 Height = 25 - Anchors = [akTop, akRight] + Anchors = [akRight, akBottom] Caption = '&Minimize' TabOrder = 1 OnClick = MinimizeButtonClick diff --git a/source/packages/filemng/BaseUtils.pas b/source/packages/filemng/BaseUtils.pas index b7a7b38ea..b16895869 100644 --- a/source/packages/filemng/BaseUtils.pas +++ b/source/packages/filemng/BaseUtils.pas @@ -35,7 +35,6 @@ type function CheckFileExists(FileName: string): Boolean; function DirExists(Dir: string): Boolean; overload; function DirExists(Dir: string; var Attrs: Integer): Boolean; overload; -function DiskSize(Drive: Byte): Int64; function ExtractFileNameOnly(Name: string): string; function FileOrDirExists(FileName: string): Boolean; function FormatBytes(Bytes: Int64; UseOrders: Boolean = True; UseUnitsForBytes: Boolean = True): string; @@ -63,10 +62,6 @@ implementation uses IEDriveInfo, DateUtils, ShellApi, SysConst; -var - GetDiskFreeSpaceEx: function (Directory: PChar; - var FreeAvailable, TotalSpace: TLargeInteger; TotalFree: PLargeInteger): Bool stdcall = nil; - function AnyValidPath: string; var Drive: TDrive; @@ -212,62 +207,6 @@ begin end; end; {FreePIDL} -function InternalGetDiskSpace(Drive: Byte; - var TotalSpace, FreeSpaceAvailable: Int64): Bool; -var - RootPath: array[0..4] of Char; - RootPtr: PChar; -begin - RootPtr := nil; - if Drive > 0 then - begin - RootPath[0] := Char(Drive + $40); - RootPath[1] := ':'; - RootPath[2] := '\'; - RootPath[3] := #0; - RootPtr := RootPath; - end; - Result := GetDiskFreeSpaceEx(RootPtr, FreeSpaceAvailable, TotalSpace, nil); -end; - -// This function is used if the OS doesn't support GetDiskFreeSpaceEx -function BackfillGetDiskFreeSpaceEx(Directory: PChar; var FreeAvailable, - TotalSpace: TLargeInteger; TotalFree: PLargeInteger): Bool; stdcall; -var - SectorsPerCluster, BytesPerSector, FreeClusters, TotalClusters: LongWord; - Temp: Int64; - Dir: PChar; -begin - if Directory <> nil then - Dir := Directory - else - Dir := nil; - Result := GetDiskFreeSpace(Dir, SectorsPerCluster, BytesPerSector, - FreeClusters, TotalClusters); - Temp := SectorsPerCluster * BytesPerSector; - FreeAvailable := Temp * FreeClusters; - TotalSpace := Temp * TotalClusters; -end; - -function DiskSize(Drive: Byte): Int64; -var - FreeSpace: Int64; -begin - if not InternalGetDiskSpace(Drive, Result, FreeSpace) then - Result := -1; -end; - -procedure InitDriveSpacePtr; -var - Kernel: THandle; -begin - Kernel := GetModuleHandle(Windows.Kernel32); - if Kernel <> 0 then - @GetDiskFreeSpaceEx := GetProcAddress(Kernel, 'GetDiskFreeSpaceExW'); - if not Assigned(GetDiskFreeSpaceEx) then - GetDiskFreeSpaceEx := @BackfillGetDiskFreeSpaceEx; -end; - // duplicated in RemoteFiles.cpp procedure ReduceDateTimePrecision(var DateTime: TDateTime; Precision: TDateTimePrecision); @@ -343,5 +282,4 @@ begin end; initialization - InitDriveSpacePtr; end. diff --git a/source/packages/filemng/CustomDirView.pas b/source/packages/filemng/CustomDirView.pas index 2bdf91ab9..fad43d931 100644 --- a/source/packages/filemng/CustomDirView.pas +++ b/source/packages/filemng/CustomDirView.pas @@ -856,14 +856,9 @@ end; { TCustomDirView } constructor TCustomDirView.Create(AOwner: TComponent); -var - WinVer: TOSVersionInfo; begin inherited; - WinVer.dwOSVersionInfoSize := SizeOf(WinVer); - GetVersionEx(WinVer); - FWatchForChanges := False; FFilesSize := 0; FFilesSelSize := 0; @@ -909,7 +904,7 @@ begin FDragDrive := #0; FExeDrag := False; FMask := ''; - FDoubleBufferedScrollingWorkaround := not IsVista(); + FDoubleBufferedScrollingWorkaround := not IsVistaHard(); FOnHistoryChange := nil; FOnPathChange := nil; @@ -2403,7 +2398,8 @@ function TCustomDirView.AnyFileSelected(OnlyFocused: Boolean; FilesOnly: Boolean var Item: TListItem; begin - if OnlyFocused or (SelCount = 0) then + if OnlyFocused or + ((SelCount = 0) and Focused and GetParentForm(Self).Active) then begin Result := Assigned(ItemFocused) and ItemIsFile(ItemFocused) and ((not FilesOnly) or (not ItemIsDirectory(ItemFocused))); diff --git a/source/packages/filemng/CustomDriveView.pas b/source/packages/filemng/CustomDriveView.pas index 36e1336b9..dc3c78160 100644 --- a/source/packages/filemng/CustomDriveView.pas +++ b/source/packages/filemng/CustomDriveView.pas @@ -224,14 +224,9 @@ uses IEListView, BaseUtils; constructor TCustomDriveView.Create(AOwner: TComponent); -var - WinVer: TOSVersionInfo; begin inherited; - WinVer.dwOSVersionInfoSize := SizeOf(WinVer); - GetVersionEx(WinVer); - DragMode := dmAutomatic; FDragFileList := TStringList.Create; FDragDrive := #0; diff --git a/source/packages/filemng/DirView.pas b/source/packages/filemng/DirView.pas index bb17edfe6..56074cb3f 100644 --- a/source/packages/filemng/DirView.pas +++ b/source/packages/filemng/DirView.pas @@ -3426,7 +3426,7 @@ end; {ChangeInvalid} function TDirView.WatchThreadActive: Boolean; begin Result := WatchForChanges and Assigned(FDiscMonitor) and - FDiscMonitor.Active; + FDiscMonitor.Active and FDiscMonitor.Enabled; end; {WatchThreadActive} {$ENDIF} diff --git a/source/packages/filemng/DriveView.pas b/source/packages/filemng/DriveView.pas index 0459b2d3b..d1827eb52 100644 --- a/source/packages/filemng/DriveView.pas +++ b/source/packages/filemng/DriveView.pas @@ -2235,8 +2235,7 @@ var Drive: TDrive; begin Drive := GetDriveToNode(Node); - Result := Assigned(DriveStatus[Drive].DiscMonitor) and - DriveStatus[Drive].DiscMonitor.Active; + Result := WatchThreadActive(Drive); end; {NodeWatched} procedure TDriveView.ChangeInvalid(Sender: TObject; const Directory: string; @@ -2372,7 +2371,8 @@ function TDriveView.WatchThreadActive(Drive: TDrive): Boolean; begin Result := FWatchDirectory and Assigned(DriveStatus[Drive].DiscMonitor) and - DriveStatus[Drive].DiscMonitor.Active; + DriveStatus[Drive].DiscMonitor.Active and + DriveStatus[Drive].DiscMonitor.Enabled; end; {WatchThreadActive} function TDriveView.WatchThreadActive: Boolean; @@ -2387,9 +2387,7 @@ begin Drive := GetDriveToNode(Selected); - Result := FWatchDirectory and - Assigned(DriveStatus[Drive].DiscMonitor) and - DriveStatus[Drive].DiscMonitor.Active; + Result := WatchThreadActive(Drive); end; {WatchThreadActive} {$ENDIF} diff --git a/source/packages/filemng/IEDriveInfo.pas b/source/packages/filemng/IEDriveInfo.pas index 4573f9779..59e25e2ee 100644 --- a/source/packages/filemng/IEDriveInfo.pas +++ b/source/packages/filemng/IEDriveInfo.pas @@ -328,7 +328,7 @@ begin try { drive 1 = a, 2 = b, 3 = c, etc. } - Size := BaseUtils.DiskSize(Ord(Drive) - $40); + Size := DiskSize(Ord(Drive) - $40); DriveReady := (Size >= 0); if DriveReady then begin @@ -497,54 +497,29 @@ const USE_CONN = 4; USE_RECONN = 5; -var - NetUseGetInfo: function(UncServerName: LMSTR; UseName: LMSTR; Level: DWORD; - var BufPtr: LPBYTE): NET_API_STATUS; stdcall; - NetApiBufferFree: function(Buffer: LPVOID): NET_API_STATUS; stdcall; +function NetUseGetInfo(UncServerName: LMSTR; UseName: LMSTR; Level: DWORD; var BufPtr: LPBYTE): NET_API_STATUS; stdcall; external 'netapi32.dll'; +function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external 'netapi32.dll'; function GetNetWorkConnected(Drive: Char): Boolean; var BufPtr: LPBYTE; NetResult: Integer; begin - if Assigned(NetUseGetInfo) then + NetResult := NetUseGetInfo(nil, PChar(Drive + ':'), 1, BufPtr); + if NetResult = 0 then begin - NetResult := NetUseGetInfo(nil, PChar(Drive + ':'), 1, BufPtr); - if NetResult = 0 then - begin - Result := (PUSE_INFO_1(BufPtr)^.ui1_status = USE_OK); - Assert(Assigned(NetApiBufferFree)); - NetApiBufferFree(LPVOID(BufPtr)); - end - else - begin - // NetUseGetInfo works for DFS shares only, hence when it fails - // we suppose different share type and fallback to "connected" - Result := True; - end; + Result := (PUSE_INFO_1(BufPtr)^.ui1_status = USE_OK); + NetApiBufferFree(LPVOID(BufPtr)); end else begin + // NetUseGetInfo works for DFS shares only, hence when it fails + // we suppose different share type and fallback to "connected" Result := True; end; end; -var - NetApiDll: THandle; - initialization - NetApiDll := SafeLoadLibrary('netapi32.dll'); - if NetApiDll <> 0 then - begin - @NetUseGetInfo := GetProcAddress(NetApiDll, 'NetUseGetInfo'); - @NetApiBufferFree := GetProcAddress(NetApiDll, 'NetApiBufferFree'); - end - else - begin - @NetUseGetInfo := nil; - @NetApiBufferFree := nil; - end; - if not Assigned(DriveInfo) then DriveInfo := TDriveInfo.Create; @@ -554,6 +529,4 @@ finalization DriveInfo.Free; DriveInfo := nil; end; - - if NetApiDll <> 0 then FreeLibrary(NetApiDll); end. diff --git a/source/packages/my/ListViewColProperties.pas b/source/packages/my/ListViewColProperties.pas index 32a930356..630d347ff 100644 --- a/source/packages/my/ListViewColProperties.pas +++ b/source/packages/my/ListViewColProperties.pas @@ -36,7 +36,7 @@ type procedure CheckBounds(Index: Integer); procedure SetMaxWidth(Value: Integer); procedure SetMinWidth(Value: Integer); - procedure SetWidthsStr(Value: string); + procedure SetWidthsStr(Value: string; PixelsPerInch: Integer); function GetWidthsStr: string; procedure SetOrderStr(Value: string); protected @@ -97,9 +97,6 @@ implementation uses SysUtils, CommCtrl, Windows, PasTools, Controls; -const - MaxOrderColumns = 30 - 1; - { TODO : V ListView zamezit zmenu velikosti neviditelnych sloupecku } constructor TCustomListViewColProperty.Create(AOrder: Integer); @@ -145,7 +142,7 @@ begin FProperties.Free; end; -procedure TCustomListViewColProperties.SetWidthsStr(Value: string); +procedure TCustomListViewColProperties.SetWidthsStr(Value: string; PixelsPerInch: Integer); var ColStr: string; Index: Integer; @@ -156,8 +153,8 @@ begin while (Value <> '') and (Index < Count) do begin ColStr := CutToChar(Value, ';', True); - Widths[Index] := StrToInt(CutToChar(ColStr, ',', True)); - Visible[Index] := Boolean(StrToInt(ColStr)); + Widths[Index] := LoadDimension(StrToInt(CutToChar(ColStr, ',', True)), PixelsPerInch); + Visible[Index] := Boolean(StrToInt(CutToChar(ColStr, ',', True))); Inc(Index); end; finally @@ -171,7 +168,7 @@ var begin Result := ''; for Index := 0 to Count-1 do - Result := Format('%s;%d,%d', [Result, Widths[Index], Integer(Visible[Index])]); + Result := Format('%s;%d,%d', [Result, SaveDimension(Widths[Index]), Integer(Visible[Index])]); Delete(Result, 1, 1); end; @@ -323,14 +320,20 @@ end; procedure TCustomListViewColProperties.SetParamsStr(Value: string); var - W: string; + S: string; + WidthsStr: string; + OrderStr: string; + PixelsPerInch: Integer; begin - W := CutToChar(Value, '|', True); + S := CutToChar(Value, '|', True); + WidthsStr := CutToChar(S, '@', True); + PixelsPerInch := LoadPixelsPerInch(S); + OrderStr := CutToChar(Value, '|', True); // set first orders, only than the widths/visibility, // as setting visibility can reorder hidden/visible columns // as needed, while setting order cannot ensure this - SetOrderStr(Value); - SetWidthsStr(W); + SetOrderStr(OrderStr); + SetWidthsStr(WidthsStr, PixelsPerInch); end; procedure TCustomListViewColProperties.SetVisible(Index: Integer; Value: Boolean); @@ -467,7 +470,16 @@ end; function TCustomListViewColProperties.GetParamsStr: string; begin - Result := Format('%s|%s', [GetWidthsStr, GetOrderStr]); + // WORKAROUND + // Adding an additional semicolon after the list, + // to ensure that old versions that did not expect the pixels-per-inch part, + // stop at the semicolon, otherwise they try to parse the + // "last-column-width|pixels-per-inch" as integer and throw. + // For the other instance of this hack, see GetListViewStr. + // The new pixels-per-inch part is inserted after the widths part + // as parsing of this was always robust to stop at "count" elements, + // what order part was not (due to its logic of skipping hidden columns) + Result := Format('%s;@%s|%s', [GetWidthsStr, SavePixelsPerInch, GetOrderStr]); end; function TCustomListViewColProperties.GetVisible(Index: Integer): Boolean; diff --git a/source/packages/my/NortonLikeListView.pas b/source/packages/my/NortonLikeListView.pas index 1b2d4f9fe..09f4d11be 100644 --- a/source/packages/my/NortonLikeListView.pas +++ b/source/packages/my/NortonLikeListView.pas @@ -214,7 +214,7 @@ begin // So we need to manage selection state ourselves // cannot use Win32MajorVersion as it is affected by compatibility mode and // the bug is present even in compatibility mode - FManageSelection := IsVista; + FManageSelection := IsVistaHard; FFocused := 0; FIgnoreSetFocusFrom := INVALID_HANDLE_VALUE; // On Windows 7 we have to force item update when it looses focus, @@ -549,6 +549,15 @@ begin Message.Result := 1; end else + if (NortonLike <> nlOff) and (Message.CharCode = VK_SPACE) and + ((KeyDataToShiftState(Message.KeyData) * [ssCtrl]) <> []) then + begin + // prevent Ctrl+Space landing in else branch below, + // this can safely get processed by default handler as Ctrl+Space + // toggles only focused item, not affecting others + inherited; + end + else if (Message.CharCode in [VK_SPACE, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_SELECT]) then begin @@ -559,6 +568,8 @@ begin FDontSelectItem := FDontSelectItem or ((NortonLike <> nlOff) and ((KeyDataToShiftState(Message.KeyData) * [ssShift]) = [])); + // Note that Space (selecting toggling) is processed by default handler for WM_CHAR, + // otherwise the below condition would prevent unselection FDontUnSelectItem := FDontUnSelectItem or (NortonLike = nlOn) or diff --git a/source/packages/my/PasTools.pas b/source/packages/my/PasTools.pas index d4cbff2f4..7ede9acd7 100644 --- a/source/packages/my/PasTools.pas +++ b/source/packages/my/PasTools.pas @@ -3,20 +3,43 @@ unit PasTools; interface uses - Windows, Types, Classes, ComCtrls, ExtCtrls, Controls, Dialogs; + Windows, Types, Classes, ComCtrls, ExtCtrls, Controls, Dialogs, Forms; function Construct(ComponentClass: TComponentClass; Owner: TComponent): TComponent; +function IsVistaHard: Boolean; + function IsVista: Boolean; function IsExactly2008R2: Boolean; function IsWin7: Boolean; +function IsWin8: Boolean; + function CutToChar(var Str: string; Ch: Char; Trim: Boolean): string; procedure FilterToFileTypes(Filter: string; FileTypes: TFileTypeItems); +// Note that while we based our scaling on pixels-per-inch, +// VCL actually scales based on font size +function LoadDimension(Dimension: Integer; PixelsPerInch: Integer): Integer; +function StrToDimensionDef(Str: string; PixelsPerInch: Integer; Default: Integer): Integer; +function SaveDimension(Dimension: Integer): Integer; +function DimensionToDefaultPixelsPerInch(Dimension: Integer): Integer; + +function LoadPixelsPerInch(S: string): Integer; +function SavePixelsPerInch: string; +function SaveDefaultPixelsPerInch: string; + +function ScaleByTextHeight(Control: TControl; Dimension: Integer): Integer; +function ScaleByTextHeightRunTime(Control: TControl; Dimension: Integer): Integer; + +function ControlHasRecreationPersistenceData(Control: TControl): Boolean; + +function IsAppIconic: Boolean; +procedure SetAppIconic(Value: Boolean); + type TControlScrollBeforeUpdate = procedure(ObjectToValidate: TObject) of object; TControlScrollAfterUpdate = procedure of object; @@ -84,11 +107,17 @@ end; // detects vista, even in compatibility mode // (GetLocaleInfoEx is available since Vista only) -function IsVista: Boolean; +function IsVistaHard: Boolean; begin Result := (GetProcAddress(GetModuleHandle(Kernel32), 'GetLocaleInfoEx') <> nil); end; +function IsVista: Boolean; +begin + Result := CheckWin32Version(6, 0); +end; + +// Duplicated in Common.cpp function IsExactly2008R2: Boolean; var GetProductInfo: function(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion: DWORD; var dwReturnedProductType: DWORD): BOOL stdcall; @@ -146,6 +175,11 @@ begin Result := CheckWin32Version(6, 1); end; +function IsWin8: Boolean; +begin + Result := CheckWin32Version(6, 2); +end; + function CutToChar(var Str: string; Ch: Char; Trim: Boolean): string; var P: Integer; @@ -176,6 +210,181 @@ begin end; end; +function LoadDimension(Dimension: Integer; PixelsPerInch: Integer): Integer; +begin + Result := MulDiv(Dimension, Screen.PixelsPerInch, PixelsPerInch); +end; + +function StrToDimensionDef(Str: string; PixelsPerInch: Integer; Default: Integer): Integer; +begin + if TryStrToInt(Str, Result) then + begin + Result := LoadDimension(Result, PixelsPerInch); + end + else + begin + Result := Default; + end; +end; + +function SaveDimension(Dimension: Integer): Integer; +begin + // noop + Result := Dimension; +end; + +function DimensionToDefaultPixelsPerInch(Dimension: Integer): Integer; +begin + Result := MulDiv(Dimension, USER_DEFAULT_SCREEN_DPI, Screen.PixelsPerInch); +end; + +function LoadPixelsPerInch(S: string): Integer; +begin + // for backward compatibility with version that did not save the DPI, + // make reasonable assumption that the configuration was saved with + // the same DPI as we run now + Result := StrToIntDef(S, Screen.PixelsPerInch); +end; + +function SavePixelsPerInch: string; +begin + Result := IntToStr(Screen.PixelsPerInch); +end; + +function SaveDefaultPixelsPerInch: string; +begin + Result := IntToStr(USER_DEFAULT_SCREEN_DPI); +end; + +// WORKAROUND +// http://stackoverflow.com/questions/9410485/how-do-i-use-class-helpers-to-access-strict-private-members-of-a-class + +type + TFormHelper = class helper for TCustomForm + public + function RetrieveTextHeight: Integer; + function CalculateTextHeight: Integer; + end; + +function TFormHelper.RetrieveTextHeight: Integer; +begin + Result := Self.FTextHeight; +end; + +function TFormHelper.CalculateTextHeight: Integer; +begin + Result := Self.GetTextHeight; +end; + +function ScaleByTextHeightImpl(Control: TControl; Dimension: Integer; TextHeight: Integer): Integer; +var + Form: TCustomForm; + NewTextHeight: Integer; +begin + // RTL_COPY (TCustomForm.ReadState) + Form := ValidParentForm(Control); + NewTextHeight := Form.CalculateTextHeight; + if TextHeight <> NewTextHeight then + begin + Dimension := MulDiv(Dimension, NewTextHeight, TextHeight); + end; + Result := Dimension; +end; + +const + OurDesignTimeTextHeight = 13; + +function ScaleByTextHeight(Control: TControl; Dimension: Integer): Integer; +var + Form: TCustomForm; + TextHeight: Integer; +begin + // RTL_COPY (TCustomForm.ReadState) + Form := ValidParentForm(Control); + TextHeight := Form.RetrieveTextHeight; + // that's our design text-size, we do not expect any other value + Assert(TextHeight = OurDesignTimeTextHeight); + Result := ScaleByTextHeightImpl(Control, Dimension, TextHeight); +end; + +// this differs from ScaleByTextHeight only by enforcing +// constant design-time text height +function ScaleByTextHeightRunTime(Control: TControl; Dimension: Integer): Integer; +begin + Result := ScaleByTextHeightImpl(Control, Dimension, OurDesignTimeTextHeight); +end; + +type + TListViewHelper = class helper for TCustomListView + public + function HasMemStream: Boolean; + end; + +function TListViewHelper.HasMemStream: Boolean; +begin + Result := Assigned(Self.FMemStream); +end; + +type + TTreeViewHelper = class helper for TCustomTreeView + public + function HasMemStream: Boolean; + end; + +function TTreeViewHelper.HasMemStream: Boolean; +begin + Result := Assigned(Self.FMemStream); +end; + +type + TRichEditHelper = class helper for TCustomRichEdit + public + function HasMemStream: Boolean; + end; + +function TRichEditHelper.HasMemStream: Boolean; +begin + Result := Assigned(Self.FMemStream); +end; + +function ControlHasRecreationPersistenceData(Control: TControl): Boolean; +begin + // not implemented for this class as we do not use it as of now + Assert(not (Control is TCustomComboBoxEx)); + Result := + ((Control is TCustomListView) and (Control as TCustomListView).HasMemStream) or + ((Control is TCustomTreeView) and (Control as TCustomTreeView).HasMemStream) or + ((Control is TCustomRichEdit) and (Control as TCustomRichEdit).HasMemStream); +end; + +type + TApplicationHelper = class helper for TApplication + public + function IsAppIconic: Boolean; + procedure SetAppIconic(Value: Boolean); + end; + +function TApplicationHelper.IsAppIconic: Boolean; +begin + Result := Self.FAppIconic; +end; + +procedure TApplicationHelper.SetAppIconic(Value: Boolean); +begin + Self.FAppIconic := Value; +end; + +function IsAppIconic: Boolean; +begin + Result := Application.IsAppIconic; +end; + +procedure SetAppIconic(Value: Boolean); +begin + Application.SetAppIconic(Value); +end; + + { TCustomControlScrollOnDragOver } constructor TCustomControlScrollOnDragOver.Create(Control: TControl; diff --git a/source/packages/my/PathLabel.pas b/source/packages/my/PathLabel.pas index 7e1ac0188..481586bcb 100644 --- a/source/packages/my/PathLabel.pas +++ b/source/packages/my/PathLabel.pas @@ -50,6 +50,7 @@ type protected procedure AdjustBounds; override; procedure Click; override; + procedure DoDrawTextIntern(var Rect: TRect; Flags: Longint; S: string); procedure DoDrawText(var Rect: TRect; Flags: Longint); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; @@ -493,10 +494,9 @@ begin end; end; -procedure TCustomPathLabel.DoDrawText(var Rect: TRect; Flags: Longint); +procedure TCustomPathLabel.DoDrawTextIntern(var Rect: TRect; Flags: Longint; S: string); var i: Integer; - StandardColor: TColor; Width: Integer; WidthMask: Integer; WidthPath: Integer; @@ -505,15 +505,15 @@ var Separator: string; Str: string; begin - if (Flags and DT_CALCRECT <> 0) and ((Text = '') or ShowAccelChar and - (Text[1] = '&') and (Text[2] = #0)) then Text := Text + ' '; + if (Flags and DT_CALCRECT <> 0) and ((S = '') or ShowAccelChar and + (S[1] = '&') and (S[2] = #0)) then S := S + ' '; if not ShowAccelChar then Flags := Flags or DT_NOPREFIX; Flags := DrawTextBiDiModeFlags(Flags); Canvas.Font := Font; Width := (Rect.Right - Rect.Left); - FDisplayPath := Caption; + FDisplayPath := S; FDisplayMask := Mask; Separator := ''; @@ -577,12 +577,12 @@ begin end; ShowHint := - (FDisplayPath <> Caption) or + (FDisplayPath <> S) or (FDisplayMask <> Mask) or (WidthPath + WidthMask > Width); if not ShowHint then Hint := '' - else Hint := Caption + Separator + Mask; + else Hint := S + Separator + Mask; Str := FDisplayPath + FDisplayMask; if not Enabled then @@ -599,11 +599,19 @@ begin FDisplayHotTrack := HotTrackPath(FDisplayPath); if FDisplayHotTrack <> '' then begin - StandardColor := Canvas.Font.Color; if TrackingActive then - Canvas.Font.Color := FColors[4 + Integer(FIsActive)]; + begin + Canvas.Font.Color := FColors[4 + Integer(FIsActive)] + end + else + begin + // We do not have a path label with hot-track and not tracking-active, + // so this is untested branch + Assert(False); + // As if it were active + Canvas.Font.Color := FColors[2 + 1]; + end; DrawText(Canvas.Handle, PChar(FDisplayHotTrack), Length(FDisplayHotTrack), Rect, Flags); - Canvas.Font.Color := StandardColor; HotTrackOffset := Canvas.TextWidth(FDisplayHotTrack); Inc(Rect.Left, HotTrackOffset); Delete(Str, 1, Length(FDisplayHotTrack)); @@ -615,6 +623,10 @@ begin HotTrackBottom := 0; end; + if TrackingActive then + Canvas.Font.Color := FColors[2 + Integer(FIsActive)] + else + Canvas.Font.Color := clWindowText; DrawText(Canvas.Handle, PChar(Str), Length(Str), Rect, Flags); Dec(Rect.Left, HotTrackOffset); @@ -622,6 +634,11 @@ begin end; end; +procedure TCustomPathLabel.DoDrawText(var Rect: TRect; Flags: Longint); +begin + DoDrawTextIntern(Rect, Flags, Caption); +end; + function TCustomPathLabel.HotTrackPath(Path: string): string; var P: TPoint; @@ -713,15 +730,17 @@ var AAlignment: TAlignment; AWidth: Integer; AHeight: Integer; + S: string; begin if not (csReading in ComponentState) and - (AutoSize or AutoSizeVertical) and - (Caption <> '') then + (AutoSize or AutoSizeVertical) then begin Rect := ClientRect; DC := GetDC(0); Canvas.Handle := DC; - DoDrawText(Rect, (DT_EXPANDTABS or DT_CALCRECT) or WordWraps[WordWrap]); + S := Caption; + if S = '' then S := 'SomeTextForSizing'; + DoDrawTextIntern(Rect, (DT_EXPANDTABS or DT_CALCRECT) or WordWraps[WordWrap], S); Canvas.Handle := 0; ReleaseDC(0, DC); X := Left; @@ -755,15 +774,24 @@ begin end; procedure TCustomPathLabel.UpdateStatus; +var + NewIsActive: Boolean; + NewColor: TColor; begin if TrackingActive then begin - FIsActive := IsActive; - Color := FColors[Integer(FIsActive)]; - // We don't want to store Font properties in DFM - // which would be if Font.Color is set to something else than clWindowText - if not (csDesigning in ComponentState) then - Font.Color := FColors[2 + Integer(FIsActive)]; + NewIsActive := IsActive; + NewColor := FColors[Integer(NewIsActive)]; + if (NewIsActive <> FIsActive) or (NewColor <> Color) then + begin + FIsActive := NewIsActive; + Color := NewColor; + Invalidate; + end; + end + else + begin + Color := clBtnFace; end; end; { UpdateStatus } diff --git a/source/packages/tb2k/TB2Acc.pas b/source/packages/tb2k/TB2Acc.pas index 5ac94811e..c8b629c97 100644 --- a/source/packages/tb2k/TB2Acc.pas +++ b/source/packages/tb2k/TB2Acc.pas @@ -143,16 +143,7 @@ type procedure HandleAccSelect(const AExecute: Boolean); end; -procedure CallNotifyWinEvent(event: DWORD; hwnd: HWND; idObject: DWORD; - idChild: Longint); -function InitializeOleAcc: Boolean; - var - LresultFromObjectFunc: function(const riid: TGUID; wParam: WPARAM; - pUnk: IUnknown): LRESULT; stdcall; - AccessibleObjectFromWindowFunc: function(hwnd: HWND; dwId: DWORD; - const riid: TGUID; out ppvObject: Pointer): HRESULT; stdcall; - { For debugging purposes only: } ViewAccObjectInstances: Integer = 0; ItemViewerAccObjectInstances: Integer = 0; @@ -160,7 +151,7 @@ var implementation uses - {$IFDEF JR_D6} Variants, {$ENDIF} ActiveX, Menus, TB2Common; + {$IFDEF JR_D6} Variants, {$ENDIF} ActiveX, Menus, TB2Common, Winapi.oleacc; const { Constants from OleAcc.h } @@ -196,49 +187,11 @@ var LastAccObject: TTBCustomAccObject; { last object in the linked list } LastAccObjectCritSect: TRTLCriticalSection; - NotifyWinEventInited: BOOL; - NotifyWinEventFunc: procedure(event: DWORD; hwnd: HWND; idObject: DWORD; - idChild: Longint); stdcall; - -procedure CallNotifyWinEvent(event: DWORD; hwnd: HWND; idObject: DWORD; - idChild: Longint); -begin - if not NotifyWinEventInited then begin - NotifyWinEventFunc := GetProcAddress(GetModuleHandle(user32), 'NotifyWinEvent'); - InterlockedExchange(Integer(NotifyWinEventInited), Ord(True)); - end; - if Assigned(NotifyWinEventFunc) then - NotifyWinEventFunc(event, hwnd, idObject, idChild); -end; - -var - OleAccInited: BOOL; - OleAccAvailable: BOOL; - -function InitializeOleAcc: Boolean; -var - M: HMODULE; -begin - if not OleAccInited then begin - M := {$IFDEF JR_D5} SafeLoadLibrary {$ELSE} LoadLibrary {$ENDIF} ('oleacc.dll'); - if M <> 0 then begin - LresultFromObjectFunc := GetProcAddress(M, 'LresultFromObject'); - AccessibleObjectFromWindowFunc := GetProcAddress(M, 'AccessibleObjectFromWindow'); - if Assigned(LresultFromObjectFunc) and - Assigned(AccessibleObjectFromWindowFunc) then - OleAccAvailable := True; - end; - InterlockedExchange(Integer(OleAccInited), Ord(True)); - end; - Result := OleAccAvailable; -end; - function AccObjectFromWindow(const Wnd: HWND; out ADisp: IDispatch): Boolean; var P: Pointer; begin - if Assigned(AccessibleObjectFromWindowFunc) and - (AccessibleObjectFromWindowFunc(Wnd, OBJID_WINDOW, IDispatch, P) = S_OK) then begin + if AccessibleObjectFromWindow(Wnd, OBJID_WINDOW, IDispatch, P) = S_OK then begin ADisp := IDispatch(P); IDispatch(P)._Release; Result := True; diff --git a/source/packages/tb2k/TB2Anim.pas b/source/packages/tb2k/TB2Anim.pas index abda0f1ef..8cd32b934 100644 --- a/source/packages/tb2k/TB2Anim.pas +++ b/source/packages/tb2k/TB2Anim.pas @@ -82,11 +82,6 @@ type StepMessagePending: BOOL; end; -var - UpdateLayeredWindowProc: function(Handle: THandle; hdcDest: HDC; - pptDst: PPoint; _psize: PSize; hdcSrc: HDC; pptSrc: PPoint; - crKey: COLORREF; pblend: PBLENDFUNCTION; dwFlags: DWORD): BOOL; stdcall; - function AnimateThreadFunc(Parameter: Pointer): Integer; var StartTime, FrameStartTime, NextFrameStartTime: DWORD; @@ -188,7 +183,7 @@ begin with PAnimateThreadFuncData(@AnimateData)^ do begin SequenceID := AnimationSequenceID; Wnd := AWnd; - Blending := ABlend and Assigned(UpdateLayeredWindowProc); + Blending := ABlend; Direction := ADirection; GetCursorPos(LastPos); GetClientRect(Wnd, ScreenClientRect); @@ -214,7 +209,7 @@ begin Longint(Blend) := 0; Blend.BlendOp := AC_SRC_OVER; Blend.SourceConstantAlpha := CurStep; - UpdateLayeredWindowProc(Wnd, 0, @R.TopLeft, @Size, BmpDC, @ZeroPt, 0, + UpdateLayeredWindow(Wnd, 0, @R.TopLeft, @Size, BmpDC, @ZeroPt, 0, @Blend, ULW_ALPHA); end else begin @@ -258,7 +253,7 @@ begin Longint(Blend) := 0; Blend.BlendOp := AC_SRC_OVER; Blend.SourceConstantAlpha := AnimateData.CurStep; - UpdateLayeredWindowProc(Wnd, 0, nil, nil, 0, nil, 0, @Blend, ULW_ALPHA); + UpdateLayeredWindow(Wnd, 0, nil, nil, 0, nil, 0, @Blend, ULW_ALPHA); end else begin if tbadDown in Direction then @@ -286,8 +281,6 @@ begin end; initialization - UpdateLayeredWindowProc := GetProcAddress(GetModuleHandle(user32), - 'UpdateLayeredWindow'); finalization TBEndAnimation(0); end. diff --git a/source/packages/tb2k/TB2Common.pas b/source/packages/tb2k/TB2Common.pas index 30ebb56b8..6459c9fd8 100644 --- a/source/packages/tb2k/TB2Common.pas +++ b/source/packages/tb2k/TB2Common.pas @@ -72,7 +72,6 @@ procedure HandleWMPrintClient(const Control: TWinControl; var Message: TMessage); procedure ListSortEx(const List: TList; const Compare: TListSortExCompare; const ExtraData: Pointer); -procedure InitTrackMouseEvent; function Max(A, B: Integer): Integer; function Min(A, B: Integer): Integer; function MethodsEqual(const M1, M2: TMethod): Boolean; @@ -768,42 +767,15 @@ begin Result := GetRectOfPrimaryMonitor(WorkArea); end; -var - TrackMouseEventInited: BOOL; - -procedure InitTrackMouseEvent; -var - TrackMouseEventComCtlModule: THandle; -begin - { First look for TrackMouseEvent which is available on Windows 98 & NT 4 only. - If it doesn't exist, look for _TrackMouseEvent which is available on - Windows 95 if IE 3.0 or later is installed. } - if not TrackMouseEventInited then begin - TrackMouseEventFunc := GetProcAddress(GetModuleHandle(user32), - 'TrackMouseEvent'); - if @TrackMouseEventFunc = nil then begin - TrackMouseEventComCtlModule := - {$IFDEF JR_D5} SafeLoadLibrary {$ELSE} LoadLibrary {$ENDIF} (comctl32); - if TrackMouseEventComCtlModule <> 0 then - TrackMouseEventFunc := GetProcAddress(TrackMouseEventComCtlModule, - '_TrackMouseEvent'); - end; - InterlockedExchange(Integer(TrackMouseEventInited), Ord(True)); - end; -end; - function CallTrackMouseEvent(const Wnd: HWND; const Flags: DWORD): Boolean; var Track: TTrackMouseEvent; begin - Result := False; - if Assigned(TrackMouseEventFunc) then begin - Track.cbSize := SizeOf(Track); - Track.dwFlags := Flags; - Track.hwndTrack := Wnd; - Track.dwHoverTime := 0; - Result := TrackMouseEventFunc(Track); - end; + Track.cbSize := SizeOf(Track); + Track.dwFlags := Flags; + Track.hwndTrack := Wnd; + Track.dwHoverTime := 0; + Result := TrackMouseEvent(Track); end; {$IFNDEF JR_D5} diff --git a/source/packages/tb2k/TB2Dock.pas b/source/packages/tb2k/TB2Dock.pas index 072f5f22f..771637ee4 100644 --- a/source/packages/tb2k/TB2Dock.pas +++ b/source/packages/tb2k/TB2Dock.pas @@ -2592,7 +2592,6 @@ begin if not(csDesigning in ComponentState) then InstallHookProc(Self, ToolbarHookProc, [hpSendActivate, hpSendActivateApp, hpSendWindowPosChanged, hpPreDestroy]); - InitTrackMouseEvent; end; destructor TTBCustomDockableWindow.Destroy; diff --git a/source/packages/tb2k/TB2Item.pas b/source/packages/tb2k/TB2Item.pas index 1ca79e7ca..961313fbe 100644 --- a/source/packages/tb2k/TB2Item.pas +++ b/source/packages/tb2k/TB2Item.pas @@ -887,7 +887,7 @@ function ProcessDoneAction(const DoneActionData: TTBDoneActionData; implementation uses - MMSYSTEM, TB2Consts, TB2Common, IMM, TB2Acc; + MMSYSTEM, TB2Consts, TB2Common, IMM, TB2Acc, Winapi.oleacc; var LastPos: TPoint; @@ -2085,7 +2085,7 @@ begin Result.Visible := True; end; end; - CallNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, Result.View.FWindow.Handle, + NotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, Result.View.FWindow.Handle, OBJID_CLIENT, CHILDID_SELF); { Call NotifyFocusEvent now that the window is visible } if Assigned(Result.View.Selected) then @@ -2697,10 +2697,6 @@ end; function TTBItemViewer.GetAccObject: IDispatch; begin if FAccObjectInstance = nil then begin - if not InitializeOleAcc then begin - Result := nil; - Exit; - end; FAccObjectInstance := TTBItemViewerAccObject.Create(Self); end; Result := FAccObjectInstance; @@ -3547,10 +3543,6 @@ end; function TTBView.GetAccObject: IDispatch; begin if FAccObjectInstance = nil then begin - if not InitializeOleAcc then begin - Result := nil; - Exit; - end; FAccObjectInstance := TTBViewAccObject.Create(Self); { Strictly as an optimization, take a reference for ourself and keep it for the lifetime of the view. (Destroy calls _Release.) } @@ -3561,8 +3553,8 @@ end; function TTBView.HandleWMGetObject(var Message: TMessage): Boolean; begin - if (Message.LParam = Integer(OBJID_CLIENT)) and InitializeOleAcc then begin - Message.Result := LresultFromObjectFunc(ITBAccessible, Message.WParam, GetAccObject); + if (Message.LParam = Integer(OBJID_CLIENT)) then begin + Message.Result := LresultFromObject(ITBAccessible, Message.WParam, GetAccObject); Result := True; end else @@ -4136,7 +4128,7 @@ begin when a standard context menu has no selection. } ChildID := CHILDID_SELF; end; - CallNotifyWinEvent(EVENT_OBJECT_FOCUS, FWindow.Handle, OBJID_CLIENT, ChildID); + NotifyWinEvent(EVENT_OBJECT_FOCUS, FWindow.Handle, OBJID_CLIENT, ChildID); end; end; end; @@ -5892,7 +5884,7 @@ begin end; SetCapture(FWnd); SetCursor(LoadCursor(0, IDC_ARROW)); - CallNotifyWinEvent(EVENT_SYSTEM_MENUSTART, FWnd, OBJID_CLIENT, CHILDID_SELF); + NotifyWinEvent(EVENT_SYSTEM_MENUSTART, FWnd, OBJID_CLIENT, CHILDID_SELF); FInited := True; end; @@ -5904,7 +5896,7 @@ begin if GetCapture = FWnd then ReleaseCapture; if FInited then - CallNotifyWinEvent(EVENT_SYSTEM_MENUEND, FWnd, OBJID_CLIENT, CHILDID_SELF); + NotifyWinEvent(EVENT_SYSTEM_MENUEND, FWnd, OBJID_CLIENT, CHILDID_SELF); if FCreatedWnd then {$IFDEF JR_D6}Classes.{$ENDIF} DeallocateHWnd(FWnd); end; @@ -6410,7 +6402,7 @@ destructor TTBPopupWindow.Destroy; begin Destroying; { Ensure window handle is destroyed *before* FView is freed, since - DestroyWindowHandle calls CallNotifyWinEvent which may result in + DestroyWindowHandle calls NotifyWinEvent which may result in FView.HandleWMObject being called } if HandleAllocated then DestroyWindowHandle; @@ -6487,7 +6479,7 @@ begin { Cleanly destroy any timers before the window handle is destroyed } if Assigned(FView) then FView.StopAllTimers; - CallNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, WindowHandle, OBJID_CLIENT, + NotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, WindowHandle, OBJID_CLIENT, CHILDID_SELF); inherited; end; diff --git a/source/packages/tbx/TBXStatusBars.pas b/source/packages/tbx/TBXStatusBars.pas index cd3e5871e..a580b1aab 100644 --- a/source/packages/tbx/TBXStatusBars.pas +++ b/source/packages/tbx/TBXStatusBars.pas @@ -514,8 +514,27 @@ begin end; procedure TTBXCustomStatusBar.ChangeScale(M, D: Integer); +var + I: Integer; + Panel: TTBXStatusPanel; begin if UseSystemFont then ScalingFlags := [sfTop]; + + { MP } + // For VCL status bars, this is implemented in ApplySystemSettingsOnControl + if sfWidth in ScalingFlags then + begin + for I := 0 to Panels.Count - 1 do + begin + Panel := Panels[I]; + if Panel.StretchPriority = 0 then + begin + Panel.Size := MulDiv(Panel.Size, M, D); + end; + Panel.MaxSize := MulDiv(Panel.MaxSize, M, D); + end; + end; + inherited; end; diff --git a/source/packages/tbx/TBXUtils.pas b/source/packages/tbx/TBXUtils.pas index 498372f68..3288e1b8f 100644 --- a/source/packages/tbx/TBXUtils.pas +++ b/source/packages/tbx/TBXUtils.pas @@ -120,7 +120,7 @@ const { Support for window shadows } type TShadowEdges = set of (seTopLeft, seBottomRight); - TShadowStyle = (ssFlat, ssLayered, ssAlphaBlend); + TShadowStyle = (ssFlat, ssLayered); TShadow = class(TCustomControl) protected @@ -138,7 +138,6 @@ type procedure CreateParams(var Params: TCreateParams); override; procedure FillBuffer; virtual; abstract; procedure WMNCHitTest(var Message: TMessage); message WM_NCHITTEST; - procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND; public constructor Create(const Bounds: TRect; Opacity: Byte; LoColor: Boolean; Edges: TShadowEdges); reintroduce; procedure Clear(const R: TRect); @@ -176,33 +175,6 @@ type procedure RecreateStock; -type - PBlendFunction = ^TBlendFunction; - TBlendFunction = packed record - BlendOp: Byte; - BlendFlags: Byte; - SourceConstantAlpha: Byte; - AlphaFormat: Byte; - end; - - TUpdateLayeredWindow = function(hWnd : hWnd; hdcDst : hDC; pptDst : PPoint; - psize : PSize; hdcSrc : hDC; pptSrc : PPoint; crKey : TColorRef; - pblend : PBlendFunction; dwFlags : Integer): Integer; stdcall; - - TAlphaBlend = function(hdcDest: HDC; nXOriginDest, nYOriginDest, - nWidthDest, nHeightDest: Integer; hdcSrc: HDC; - nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc: Integer; - blendFunction: TBlendFunction): BOOL; stdcall; - - TGradientFill = function(Handle: HDC; pVertex: Pointer; dwNumVertex: DWORD; - pMesh: Pointer; dwNumMesh: DWORD; dwMode: DWORD): DWORD; stdcall; - -var - UpdateLayeredWindow: TUpdateLayeredWindow = nil; - AlphaBlend: TAlphaBlend = nil; - GradientFill: TGradientFill = nil; - - implementation {$R-}{$Q-} @@ -1473,12 +1445,7 @@ begin FSaveBits := False; if LoColor then FStyle := ssFlat - else if (@UpdateLayeredWindow <> nil) and (@AlphaBlend <> nil) then - FStyle := ssLayered - else if @AlphaBlend <> nil then - FStyle := ssAlphaBlend - else - FStyle := ssFlat; + else FStyle := ssLayered; end; procedure TShadow.CreateParams(var Params: TCreateParams); @@ -1623,7 +1590,6 @@ var BlendFunc: TBlendFunction; begin if FStyle <> ssLayered then Exit; - Assert(Assigned(UpdateLayeredWindow)); SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or $00080000{WS_EX_LAYERED}); DstDC := GetDC(0); @@ -1671,48 +1637,6 @@ begin SWP_NOOWNERZORDER or SWP_NOSIZE or SWP_SHOWWINDOW); end; -procedure TShadow.WMEraseBkgnd(var Message: TWMEraseBkgnd); -var - SrcPos, DstPos: TPoint; - TheSize: TSize; - BlendFunc: TBlendFunction; -begin - if FStyle = ssAlphaBlend then - begin - Assert(Assigned(AlphaBlend)); - - { Dispatch all the painting messages } - ProcessPaintMessages; - - SrcPos := Point(0, 0); - with BoundsRect do - begin - DstPos := Point(Left, Top); - TheSize.cx := Right - Left; - TheSize.cy := Bottom - Top; - end; - - FBuffer := TBitmap.Create; - FBuffer.PixelFormat := pf32bit; - FBuffer.Width := TheSize.cx; - FBuffer.Height := TheSize.cy; - - FillBuffer; - - { Blend the buffer directly into the screen } - BlendFunc.BlendOp := 0; - BlendFunc.BlendFlags := 0; - BlendFunc.SourceConstantAlpha := FOpacity; - BlendFunc.AlphaFormat := 1; - AlphaBlend(Message.DC, 0, 0, TheSize.cx, TheSize.cy, - FBuffer.Canvas.Handle, 0, 0, TheSize.cx, TheSize.cy, BlendFunc); - FBuffer.Free; - - Message.Result := 1; - end - else inherited; -end; - procedure TShadow.WMNCHitTest(var Message: TMessage); begin Message.Result := HTTRANSPARENT; @@ -1794,8 +1718,7 @@ var R: TRect; R1Valid, R2Valid: Boolean; begin - if LoColor or - ((@UpdateLayeredWindow = nil) and (@AlphaBlend = nil)) then + if LoColor then begin TheSize := TheSize div 2; end; @@ -1987,71 +1910,32 @@ type var V: array [0..1] of TriVertex; GR: GRADIENT_RECT; - Size, I, Start, Finish: Integer; - GradIndex: Integer; - R, CR: TRect; - Brush: HBRUSH; begin if not RectVisible(DC, ARect) then Exit; ClrTopLeft := ColorToRGB(ClrTopLeft); ClrBottomRight := ColorToRGB(ClrBottomRight); - if @GradientFill <> nil then - begin - { Use msimg32.dll } - with V[0] do - begin - X := ARect.Left; - Y := ARect.Top; - R := ClrTopLeft shl 8 and $FF00; - G := ClrTopLeft and $FF00; - B := ClrTopLeft shr 8 and $FF00; - A := 0; - end; - with V[1] do - begin - X := ARect.Right; - Y := ARect.Bottom; - R := ClrBottomRight shl 8 and $FF00; - G := ClrBottomRight and $FF00; - B := ClrBottomRight shr 8 and $FF00; - A := 0; - end; - GR.UpperLeft := 0; GR.LowerRight := 1; - GradientFill(DC, @V, 2, @GR, 1, GRAD_MODE[Kind]); - end - else - begin - { Have to do it manually if msimg32.dll is not available } - GetClipBox(DC, CR); - if Kind = gkHorz then - begin - Size := ARect.Right - ARect.Left; - if Size <= 0 then Exit; - Start := 0; Finish := Size - 1; - if CR.Left > ARect.Left then Inc(Start, CR.Left - ARect.Left); - if CR.Right < ARect.Right then Dec(Finish, ARect.Right - CR.Right); - R := ARect; Inc(R.Left, Start); R.Right := R.Left + 1; - end - else - begin - Size := ARect.Bottom - ARect.Top; - if Size <= 0 then Exit; - Start := 0; Finish := Size - 1; - if CR.Top > ARect.Top then Inc(Start, CR.Top - ARect.Top); - if CR.Bottom < ARect.Bottom then Dec(Finish, ARect.Bottom - CR.Bottom); - R := ARect; Inc(R.Top, Start); R.Bottom := R.Top + 1; - end; - GradIndex := GetGradient(Size, ClrTopLeft, ClrBottomRight); - for I := Start to Finish do - begin - Brush := CreateSolidBrush(GradientCache[GradIndex][I]); - Windows.FillRect(DC, R, Brush); - OffsetRect(R, Integer(Kind = gkHorz), Integer(Kind = gkVert)); - DeleteObject(Brush); - end; + with V[0] do + begin + X := ARect.Left; + Y := ARect.Top; + R := ClrTopLeft shl 8 and $FF00; + G := ClrTopLeft and $FF00; + B := ClrTopLeft shr 8 and $FF00; + A := 0; end; + with V[1] do + begin + X := ARect.Right; + Y := ARect.Bottom; + R := ClrBottomRight shl 8 and $FF00; + G := ClrBottomRight and $FF00; + B := ClrBottomRight shr 8 and $FF00; + A := 0; + end; + GR.UpperLeft := 0; GR.LowerRight := 1; + GradientFill(DC, @V, 2, @GR, 1, GRAD_MODE[Kind]); end; { Brushed Fill } /////////////////////////////////////////////////////////////// @@ -2295,23 +2179,11 @@ begin RestoreDC(DC, -1); end; -var - hMSImg: HModule; - initialization - @UpdateLayeredWindow := GetProcAddress( - GetModuleHandle('user32.dll'), 'UpdateLayeredWindow'); - hMSImg := LoadLibrary('msimg32.dll'); - if hMSImg <> 0 then - begin - @AlphaBlend := GetProcAddress(hMSImg, 'AlphaBlend'); - @GradientFill := GetProcAddress(hMSImg, 'GradientFill'); - end; InitializeStock; InitializeBrushedFill; ResetBrushedFillCache; finalization FinalizeBrushedFill; FinalizeStock; - if hMSImg <> 0 then FreeLibrary(hMSImg); end. diff --git a/source/putty/MISC.C b/source/putty/MISC.C index 38d65dd79..b0ad75955 100644 --- a/source/putty/MISC.C +++ b/source/putty/MISC.C @@ -656,3 +656,43 @@ char const *cfg_dest(const Config *cfg) else return cfg->host; } + +#ifndef PLATFORM_HAS_SMEMCLR +/* + * Securely wipe memory. + * + * The actual wiping is no different from what memset would do: the + * point of 'securely' is to try to be sure over-clever compilers + * won't optimise away memsets on variables that are about to be freed + * or go out of scope. See + * https://buildsecurityin.us-cert.gov/bsi-rules/home/g1/771-BSI.html + * + * Some platforms (e.g. Windows) may provide their own version of this + * function. + */ +void smemclr(void *b, size_t n) { + volatile char *vp; + + if (b && n > 0) { + /* + * Zero out the memory. + */ + memset(b, 0, n); + + /* + * Perform a volatile access to the object, forcing the + * compiler to admit that the previous memset was important. + * + * This while loop should in practice run for zero iterations + * (since we know we just zeroed the object out), but in + * theory (as far as the compiler knows) it might range over + * the whole object. (If we had just written, say, '*vp = + * *vp;', a compiler could in principle have 'helpfully' + * optimised the memset into only zeroing out the first byte. + * This should be robust.) + */ + vp = b; + while (*vp) vp++; + } +} +#endif diff --git a/source/putty/MISC.H b/source/putty/MISC.H index 11233147a..9050767cd 100644 --- a/source/putty/MISC.H +++ b/source/putty/MISC.H @@ -49,6 +49,8 @@ void bufchain_fetch(bufchain *ch, void *data, int len); struct tm ltime(void); +void smemclr(void *b, size_t len); + /* * Debugging functions. * diff --git a/source/putty/PORTFWD.C b/source/putty/PORTFWD.C index 2234a48ba..f5df938f0 100644 --- a/source/putty/PORTFWD.C +++ b/source/putty/PORTFWD.C @@ -346,6 +346,7 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port, addr = name_lookup(hostname, port, &dummy_realhost, cfg, addressfamily); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); + sfree(dummy_realhost); return err; } diff --git a/source/putty/PROXY.C b/source/putty/PROXY.C index ddcd8abc0..6a68051a2 100644 --- a/source/putty/PROXY.C +++ b/source/putty/PROXY.C @@ -444,6 +444,7 @@ Socket new_connection(SockAddr addr, char *hostname, &proxy_canonical_name, cfg->addressfamily); if (sk_addr_error(proxy_addr) != NULL) { ret->error = "Proxy error: Unable to resolve proxy host name"; + sk_addr_free(proxy_addr); return (Socket)ret; } sfree(proxy_canonical_name); diff --git a/source/putty/SSHBN.C b/source/putty/SSHBN.C index 37573e9fa..1997393d6 100644 --- a/source/putty/SSHBN.C +++ b/source/putty/SSHBN.C @@ -6,6 +6,7 @@ #include #include #include +#include #include "misc.h" @@ -131,7 +132,11 @@ Bignum Zero = bnZero, One = bnOne; static Bignum newbn(int length) { - Bignum b = snewn(length + 1, BignumInt); + Bignum b; + + assert(length >= 0 && length < INT_MAX / BIGNUM_INT_BITS); + + b = snewn(length + 1, BignumInt); if (!b) abort(); /* FIXME */ memset(b, 0, (length + 1) * sizeof(*b)); @@ -159,13 +164,17 @@ void freebn(Bignum b) /* * Burn the evidence, just in case. */ - memset(b, 0, sizeof(b[0]) * (b[0] + 1)); + smemclr(b, sizeof(b[0]) * (b[0] + 1)); sfree(b); } Bignum bn_power_2(int n) { - Bignum ret = newbn(n / BIGNUM_INT_BITS + 1); + Bignum ret; + + assert(n >= 0); + + ret = newbn(n / BIGNUM_INT_BITS + 1); bignum_set_bit(ret, n, 1); return ret; } @@ -609,6 +618,7 @@ static void internal_add_shifted(BignumInt *number, addend = (BignumDblInt)n << bshift; while (addend) { + assert(word <= number[0]); addend += number[word]; number[word] = (BignumInt) addend & BIGNUM_INT_MASK; addend >>= BIGNUM_INT_BITS; @@ -635,6 +645,7 @@ static void internal_mod(BignumInt *a, int alen, int i, k; m0 = m[0]; + assert(m0 >> (BIGNUM_INT_BITS-1) == 1); if (mlen > 1) m1 = m[1]; else @@ -826,20 +837,15 @@ Bignum modpow_simple(Bignum base_in, Bignum exp, Bignum mod) result[0]--; /* Free temporary arrays */ - for (i = 0; i < 2 * mlen; i++) - a[i] = 0; + smemclr(a, 2 * mlen * sizeof(*a)); sfree(a); - for (i = 0; i < scratchlen; i++) - scratch[i] = 0; + smemclr(scratch, scratchlen * sizeof(*scratch)); sfree(scratch); - for (i = 0; i < 2 * mlen; i++) - b[i] = 0; + smemclr(b, 2 * mlen * sizeof(*b)); sfree(b); - for (i = 0; i < mlen; i++) - m[i] = 0; + smemclr(m, mlen * sizeof(*m)); sfree(m); - for (i = 0; i < mlen; i++) - n[i] = 0; + smemclr(n, mlen * sizeof(*n)); sfree(n); freebn(base); @@ -884,6 +890,7 @@ Bignum modpow(Bignum base_in, Bignum exp, Bignum mod) len = mod[0]; r = bn_power_2(BIGNUM_INT_BITS * len); inv = modinv(mod, r); + assert(inv); /* cannot fail, since mod is odd and r is a power of 2 */ /* * Multiply the base by r mod n, to get it into Montgomery @@ -976,23 +983,17 @@ Bignum modpow(Bignum base_in, Bignum exp, Bignum mod) result[0]--; /* Free temporary arrays */ - for (i = 0; i < scratchlen; i++) - scratch[i] = 0; + smemclr(scratch, scratchlen * sizeof(*scratch)); sfree(scratch); - for (i = 0; i < 2 * len; i++) - a[i] = 0; + smemclr(a, 2 * len * sizeof(*a)); sfree(a); - for (i = 0; i < 2 * len; i++) - b[i] = 0; + smemclr(b, 2 * len * sizeof(*b)); sfree(b); - for (i = 0; i < len; i++) - mninv[i] = 0; + smemclr(mninv, len * sizeof(*mninv)); sfree(mninv); - for (i = 0; i < len; i++) - n[i] = 0; + smemclr(n, len * sizeof(*n)); sfree(n); - for (i = 0; i < len; i++) - x[i] = 0; + smemclr(x, len * sizeof(*x)); sfree(x); return result; @@ -1010,6 +1011,12 @@ Bignum modmul(Bignum p, Bignum q, Bignum mod) int pqlen, mlen, rlen, i, j; Bignum result; + /* + * The most significant word of mod needs to be non-zero. It + * should already be, but let's make sure. + */ + assert(mod[mod[0]] != 0); + /* Allocate m of size mlen, copy mod to m */ /* We use big endian internally */ mlen = mod[0]; @@ -1029,6 +1036,13 @@ Bignum modmul(Bignum p, Bignum q, Bignum mod) pqlen = (p[0] > q[0] ? p[0] : q[0]); + /* + * Make sure that we're allowing enough space. The shifting below + * will underflow the vectors we allocate if pqlen is too small. + */ + if (2*pqlen <= mlen) + pqlen = mlen/2 + 1; + /* Allocate n of size pqlen, copy p to n */ n = snewn(pqlen, BignumInt); i = pqlen - p[0]; @@ -1075,20 +1089,15 @@ Bignum modmul(Bignum p, Bignum q, Bignum mod) result[0]--; /* Free temporary arrays */ - for (i = 0; i < scratchlen; i++) - scratch[i] = 0; + smemclr(scratch, scratchlen * sizeof(*scratch)); sfree(scratch); - for (i = 0; i < 2 * pqlen; i++) - a[i] = 0; + smemclr(a, 2 * pqlen * sizeof(*a)); sfree(a); - for (i = 0; i < mlen; i++) - m[i] = 0; + smemclr(m, mlen * sizeof(*m)); sfree(m); - for (i = 0; i < pqlen; i++) - n[i] = 0; + smemclr(n, pqlen * sizeof(*n)); sfree(n); - for (i = 0; i < pqlen; i++) - o[i] = 0; + smemclr(o, pqlen * sizeof(*o)); sfree(o); return result; @@ -1107,6 +1116,12 @@ static void bigdivmod(Bignum p, Bignum mod, Bignum result, Bignum quotient) int mshift; int plen, mlen, i, j; + /* + * The most significant word of mod needs to be non-zero. It + * should already be, but let's make sure. + */ + assert(mod[mod[0]] != 0); + /* Allocate m of size mlen, copy mod to m */ /* We use big endian internally */ mlen = mod[0]; @@ -1158,11 +1173,9 @@ static void bigdivmod(Bignum p, Bignum mod, Bignum result, Bignum quotient) } /* Free temporary arrays */ - for (i = 0; i < mlen; i++) - m[i] = 0; + smemclr(m, mlen * sizeof(*m)); sfree(m); - for (i = 0; i < plen; i++) - n[i] = 0; + smemclr(n, plen * sizeof(*n)); sfree(n); } @@ -1182,6 +1195,8 @@ Bignum bignum_from_bytes(const unsigned char *data, int nbytes) Bignum result; int w, i; + assert(nbytes >= 0 && nbytes < INT_MAX/8); + w = (nbytes + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES; /* bytes->words */ result = newbn(w); @@ -1258,7 +1273,7 @@ int ssh2_bignum_length(Bignum bn) */ int bignum_byte(Bignum bn, int i) { - if (i >= (int)(BIGNUM_INT_BYTES * bn[0])) + if (i < 0 || i >= (int)(BIGNUM_INT_BYTES * bn[0])) return 0; /* beyond the end */ else return (bn[i / BIGNUM_INT_BYTES + 1] >> @@ -1270,7 +1285,7 @@ int bignum_byte(Bignum bn, int i) */ int bignum_bit(Bignum bn, int i) { - if (i >= (int)(BIGNUM_INT_BITS * bn[0])) + if (i < 0 || i >= (int)(BIGNUM_INT_BITS * bn[0])) return 0; /* beyond the end */ else return (bn[i / BIGNUM_INT_BITS + 1] >> (i % BIGNUM_INT_BITS)) & 1; @@ -1281,7 +1296,7 @@ int bignum_bit(Bignum bn, int i) */ void bignum_set_bit(Bignum bn, int bitnum, int value) { - if (bitnum >= (int)(BIGNUM_INT_BITS * bn[0])) + if (bitnum < 0 || bitnum >= (int)(BIGNUM_INT_BITS * bn[0])) abort(); /* beyond the end */ else { int v = bitnum / BIGNUM_INT_BITS + 1; @@ -1317,7 +1332,18 @@ int ssh1_write_bignum(void *data, Bignum bn) int bignum_cmp(Bignum a, Bignum b) { int amax = a[0], bmax = b[0]; - int i = (amax > bmax ? amax : bmax); + int i; + + /* Annoyingly we have two representations of zero */ + if (amax == 1 && a[amax] == 0) + amax = 0; + if (bmax == 1 && b[bmax] == 0) + bmax = 0; + + assert(amax == 0 || a[amax] != 0); + assert(bmax == 0 || b[bmax] != 0); + + i = (amax > bmax ? amax : bmax); while (i) { BignumInt aval = (i > amax ? 0 : a[i]); BignumInt bval = (i > bmax ? 0 : b[i]); @@ -1339,6 +1365,8 @@ Bignum bignum_rshift(Bignum a, int shift) int i, shiftw, shiftb, shiftbb, bits; BignumInt ai, ai1; + assert(shift >= 0); + bits = bignum_bitcount(a) - shift; ret = newbn((bits + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS); @@ -1409,8 +1437,7 @@ Bignum bigmuladd(Bignum a, Bignum b, Bignum addend) } ret[0] = maxspot; - for (i = 0; i < wslen; i++) - workspace[i] = 0; + smemclr(workspace, wslen * sizeof(*workspace)); sfree(workspace); return ret; } @@ -1640,9 +1667,26 @@ Bignum modinv(Bignum number, Bignum modulus) Bignum x = copybn(One); int sign = +1; + assert(number[number[0]] != 0); + assert(modulus[modulus[0]] != 0); + while (bignum_cmp(b, One) != 0) { - Bignum t = newbn(b[0]); - Bignum q = newbn(a[0]); + Bignum t, q; + + if (bignum_cmp(b, Zero) == 0) { + /* + * Found a common factor between the inputs, so we cannot + * return a modular inverse at all. + */ + freebn(b); + freebn(a); + freebn(xp); + freebn(x); + return NULL; + } + + t = newbn(b[0]); + q = newbn(a[0]); bigdivmod(a, b, t, q); while (t[0] > 1 && t[t[0]] == 0) t[0]--; @@ -1761,6 +1805,7 @@ char *bignum_decimal(Bignum x) /* * Done. */ + smemclr(workspace, x[0] * sizeof(*workspace)); sfree(workspace); return ret; } @@ -1772,7 +1817,7 @@ char *bignum_decimal(Bignum x) #include /* - * gcc -g -O0 -DTESTBN -o testbn sshbn.c misc.c -I unix -I charset + * gcc -Wall -g -O0 -DTESTBN -o testbn sshbn.c misc.c conf.c tree234.c unix/uxmisc.c -I. -I unix -I charset * * Then feed to this program's standard input the output of * testdata/bignum.py . @@ -1846,7 +1891,7 @@ int main(int argc, char **argv) Bignum a, b, c, p; if (ptrnum != 3) { - printf("%d: mul with %d parameters, expected 3\n", line); + printf("%d: mul with %d parameters, expected 3\n", line, ptrnum); exit(1); } a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); @@ -1875,11 +1920,49 @@ int main(int argc, char **argv) freebn(b); freebn(c); freebn(p); + } else if (!strcmp(buf, "modmul")) { + Bignum a, b, m, c, p; + + if (ptrnum != 4) { + printf("%d: modmul with %d parameters, expected 4\n", + line, ptrnum); + exit(1); + } + a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); + b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); + m = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); + c = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); + p = modmul(a, b, m); + + if (bignum_cmp(c, p) == 0) { + passes++; + } else { + char *as = bignum_decimal(a); + char *bs = bignum_decimal(b); + char *ms = bignum_decimal(m); + char *cs = bignum_decimal(c); + char *ps = bignum_decimal(p); + + printf("%d: fail: %s * %s mod %s gave %s expected %s\n", + line, as, bs, ms, ps, cs); + fails++; + + sfree(as); + sfree(bs); + sfree(ms); + sfree(cs); + sfree(ps); + } + freebn(a); + freebn(b); + freebn(m); + freebn(c); + freebn(p); } else if (!strcmp(buf, "pow")) { Bignum base, expt, modulus, expected, answer; if (ptrnum != 4) { - printf("%d: mul with %d parameters, expected 3\n", line); + printf("%d: mul with %d parameters, expected 4\n", line, ptrnum); exit(1); } diff --git a/source/putty/SSHDSS.C b/source/putty/SSHDSS.C index 5bf76c838..8aec7d6b2 100644 --- a/source/putty/SSHDSS.C +++ b/source/putty/SSHDSS.C @@ -20,7 +20,7 @@ static void sha_mpint(SHA_State * s, Bignum b) lenbuf[0] = bignum_byte(b, len); SHA_Bytes(s, lenbuf, 1); } - memset(lenbuf, 0, sizeof(lenbuf)); + smemclr(lenbuf, sizeof(lenbuf)); } static void sha512_mpint(SHA512_State * s, Bignum b) @@ -34,7 +34,7 @@ static void sha512_mpint(SHA512_State * s, Bignum b) lenbuf[0] = bignum_byte(b, len); SHA512_Bytes(s, lenbuf, 1); } - memset(lenbuf, 0, sizeof(lenbuf)); + smemclr(lenbuf, sizeof(lenbuf)); } static void getstring(char **data, int *datalen, char **p, int *length) @@ -72,6 +72,9 @@ static Bignum get160(char **data, int *datalen) { Bignum b; + if (*datalen < 20) + return NULL; + b = bignum_from_bytes((unsigned char *)*data, 20); *data += 20; *datalen -= 20; @@ -79,6 +82,8 @@ static Bignum get160(char **data, int *datalen) return b; } +static void dss_freekey(void *key); /* forward reference */ + static void *dss_newkey(char *data, int len) { char *p; @@ -86,8 +91,6 @@ static void *dss_newkey(char *data, int len) struct dss_key *dss; dss = snew(struct dss_key); - if (!dss) - return NULL; getstring(&data, &len, &p, &slen); #ifdef DEBUG_DSS @@ -108,6 +111,14 @@ static void *dss_newkey(char *data, int len) dss->q = getmp(&data, &len); dss->g = getmp(&data, &len); dss->y = getmp(&data, &len); + dss->x = NULL; + + if (!dss->p || !dss->q || !dss->g || !dss->y || + !bignum_cmp(dss->q, Zero) || !bignum_cmp(dss->p, Zero)) { + /* Invalid key. */ + dss_freekey(dss); + return NULL; + } return dss; } @@ -115,10 +126,16 @@ static void *dss_newkey(char *data, int len) static void dss_freekey(void *key) { struct dss_key *dss = (struct dss_key *) key; + if (dss->p) freebn(dss->p); + if (dss->q) freebn(dss->q); + if (dss->g) freebn(dss->g); + if (dss->y) freebn(dss->y); + if (dss->x) + freebn(dss->x); sfree(dss); } @@ -251,13 +268,29 @@ static int dss_verifysig(void *key, char *sig, int siglen, } r = get160(&sig, &siglen); s = get160(&sig, &siglen); - if (!r || !s) + if (!r || !s) { + if (r) + freebn(r); + if (s) + freebn(s); return 0; + } + + if (!bignum_cmp(s, Zero)) { + freebn(r); + freebn(s); + return 0; + } /* * Step 1. w <- s^-1 mod q. */ w = modinv(s, dss->q); + if (!w) { + freebn(r); + freebn(s); + return 0; + } /* * Step 2. u1 <- SHA(message) * w mod q. @@ -287,12 +320,10 @@ static int dss_verifysig(void *key, char *sig, int siglen, ret = !bignum_cmp(v, r); - #ifdef MPEXT - freebn(u1); - freebn(u2); - #endif freebn(w); freebn(sha); + freebn(u1); + freebn(u2); freebn(gu1p); freebn(yu2p); freebn(gu1yu2p); @@ -383,7 +414,13 @@ static void *dss_createkey(unsigned char *pub_blob, int pub_len, Bignum ytest; dss = dss_newkey((char *) pub_blob, pub_len); + if (!dss) + return NULL; dss->x = getmp(&pb, &priv_len); + if (!dss->x) { + dss_freekey(dss); + return NULL; + } /* * Check the obsolete hash in the old DSS key format. @@ -408,6 +445,7 @@ static void *dss_createkey(unsigned char *pub_blob, int pub_len, ytest = modpow(dss->g, dss->x, dss->p); if (0 != bignum_cmp(ytest, dss->y)) { dss_freekey(dss); + freebn(ytest); return NULL; } freebn(ytest); @@ -421,8 +459,6 @@ static void *dss_openssh_createkey(unsigned char **blob, int *len) struct dss_key *dss; dss = snew(struct dss_key); - if (!dss) - return NULL; dss->p = getmp(b, len); dss->q = getmp(b, len); @@ -430,13 +466,10 @@ static void *dss_openssh_createkey(unsigned char **blob, int *len) dss->y = getmp(b, len); dss->x = getmp(b, len); - if (!dss->p || !dss->q || !dss->g || !dss->y || !dss->x) { - sfree(dss->p); - sfree(dss->q); - sfree(dss->g); - sfree(dss->y); - sfree(dss->x); - sfree(dss); + if (!dss->p || !dss->q || !dss->g || !dss->y || !dss->x || + !bignum_cmp(dss->q, Zero) || !bignum_cmp(dss->p, Zero)) { + /* Invalid key. */ + dss_freekey(dss); return NULL; } @@ -477,6 +510,8 @@ static int dss_pubkey_bits(void *blob, int len) int ret; dss = dss_newkey((char *) blob, len); + if (!dss) + return -1; ret = bignum_bitcount(dss->p); dss_freekey(dss); @@ -579,9 +614,12 @@ static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) SHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); SHA512_Bytes(&ss, digest, sizeof(digest)); - SHA512_Final(&ss, digest512); - memset(&ss, 0, sizeof(ss)); + while (1) { + SHA512_State ss2 = ss; /* structure copy */ + SHA512_Final(&ss2, digest512); + + smemclr(&ss2, sizeof(ss2)); /* * Now convert the result into a bignum, and reduce it mod q. @@ -589,8 +627,21 @@ static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) proto_k = bignum_from_bytes(digest512, 64); k = bigmod(proto_k, dss->q); freebn(proto_k); + kinv = modinv(k, dss->q); /* k^-1 mod q */ + if (!kinv) { /* very unlikely */ + freebn(k); + /* Perturb the hash to think of a different k. */ + SHA512_Bytes(&ss, "x", 1); + /* Go round and try again. */ + continue; + } - memset(digest512, 0, sizeof(digest512)); + break; + } + + smemclr(&ss, sizeof(ss)); + + smemclr(digest512, sizeof(digest512)); /* * Now we have k, so just go ahead and compute the signature. @@ -600,11 +651,11 @@ static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) freebn(gkp); hash = bignum_from_bytes(digest, 20); - kinv = modinv(k, dss->q); /* k^-1 mod q */ hxr = bigmuladd(dss->x, r, hash); /* hash + x*r */ s = modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash + x*r) mod q */ freebn(hxr); freebn(kinv); + freebn(k); freebn(hash); /* diff --git a/source/putty/SSHPUBK.C b/source/putty/SSHPUBK.C index e985357c8..28a6fd76b 100644 --- a/source/putty/SSHPUBK.C +++ b/source/putty/SSHPUBK.C @@ -67,14 +67,15 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, i += 4; /* Now the serious stuff. An ordinary SSH-1 public key. */ - i += makekey(buf + i, len, key, NULL, 1); - if (i < 0) + j = makekey(buf + i, len, key, NULL, 1); + if (j < 0) goto end; /* overran */ + i += j; /* Next, the comment field. */ j = GET_32BIT(buf + i); i += 4; - if (len - i < j) + if (j < 0 || len - i < j) goto end; comment = snewn(j + 1, char); if (comment) { @@ -108,7 +109,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7); - memset(keybuf, 0, sizeof(keybuf)); /* burn the evidence */ + smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* @@ -150,7 +151,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, ret = 1; end: - memset(buf, 0, sizeof(buf)); /* burn the evidence */ + smemclr(buf, sizeof(buf)); /* burn the evidence */ return ret; } @@ -257,8 +258,8 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen, *blob = rsa_public_blob(&key, bloblen); freersakey(&key); ret = 1; - fp = NULL; } + fp = NULL; /* loadrsakey_main unconditionally closes fp */ } else { error = "not an SSH-1 RSA file"; } @@ -358,7 +359,7 @@ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase) MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_encrypt_pubkey(keybuf, estart, p - estart); - memset(keybuf, 0, sizeof(keybuf)); /* burn the evidence */ + smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* @@ -647,6 +648,11 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, /* this is an old key file; warn and then continue */ old_keyfile_warning(); old_fmt = 1; + } else if (0 == strncmp(header, "PuTTY-User-Key-File-", 20)) { + /* this is a key file FROM THE FUTURE; refuse it, but with a + * more specific error message than the generic one below */ + error = "PuTTY key format too new"; + goto error; } else { error = "not a PuTTY SSH-2 private key"; goto error; @@ -674,7 +680,6 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, cipher = 0; cipherblk = 1; } else { - sfree(encryption); goto error; } @@ -794,14 +799,14 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, hmac_sha1_simple(mackey, 20, macdata, maclen, binary); - memset(mackey, 0, sizeof(mackey)); - memset(&s, 0, sizeof(s)); + smemclr(mackey, sizeof(mackey)); + smemclr(&s, sizeof(s)); } else { SHA_Simple(macdata, maclen, binary); } if (free_macdata) { - memset(macdata, 0, maclen); + smemclr(macdata, maclen); sfree(macdata); } @@ -891,6 +896,9 @@ unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm, if (!read_header(fp, header) || (0 != strcmp(header, "PuTTY-User-Key-File-2") && 0 != strcmp(header, "PuTTY-User-Key-File-1"))) { + if (0 == strncmp(header, "PuTTY-User-Key-File-", 20)) + error = "PuTTY key format too new"; + else error = "not a PuTTY SSH-2 private key"; goto error; } @@ -1000,9 +1008,8 @@ int ssh2_userkey_encrypted(const Filename *filename, char **commentptr) if (commentptr) *commentptr = comment; -#ifdef MPEXT - if (!commentptr) sfree(comment); -#endif + else + sfree(comment); fclose(fp); if (!strcmp(b, "aes256-cbc")) @@ -1119,10 +1126,10 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, SHA_Bytes(&s, passphrase, strlen(passphrase)); SHA_Final(&s, mackey); hmac_sha1_simple(mackey, 20, macdata, maclen, priv_mac); - memset(macdata, 0, maclen); + smemclr(macdata, maclen); sfree(macdata); - memset(mackey, 0, sizeof(mackey)); - memset(&s, 0, sizeof(s)); + smemclr(mackey, sizeof(mackey)); + smemclr(&s, sizeof(s)); } if (passphrase) { @@ -1142,8 +1149,8 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, aes256_encrypt_pubkey(key, priv_blob_encrypted, priv_encrypted_len); - memset(key, 0, sizeof(key)); - memset(&s, 0, sizeof(s)); + smemclr(key, sizeof(key)); + smemclr(&s, sizeof(s)); } fp = f_open(*filename, "w", TRUE); @@ -1163,7 +1170,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, fclose(fp); sfree(pub_blob); - memset(priv_blob, 0, priv_blob_len); + smemclr(priv_blob, priv_blob_len); sfree(priv_blob); sfree(priv_blob_encrypted); return 1; diff --git a/source/putty/SSHRSA.C b/source/putty/SSHRSA.C index f2e59fca8..a1cee4e24 100644 --- a/source/putty/SSHRSA.C +++ b/source/putty/SSHRSA.C @@ -109,7 +109,7 @@ static void sha512_mpint(SHA512_State * s, Bignum b) lenbuf[0] = bignum_byte(b, len); SHA512_Bytes(s, lenbuf, 1); } - memset(lenbuf, 0, sizeof(lenbuf)); + smemclr(lenbuf, sizeof(lenbuf)); } /* @@ -272,10 +272,19 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key) bignum_cmp(random, key->modulus) >= 0) { freebn(random); continue; - } else { + } + + /* + * Also, make sure it has an inverse mod modulus. + */ + random_inverse = modinv(random, key->modulus); + if (!random_inverse) { + freebn(random); + continue; + } + break; } - } /* * RSA blinding relies on the fact that (xy)^d mod n is equal @@ -293,7 +302,6 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key) */ random_encrypted = crt_modpow(random, key->exponent, key->modulus, key->p, key->q, key->iqmp); - random_inverse = modinv(random, key->modulus); input_blinded = modmul(input, random_encrypted, key->modulus); ret_blinded = crt_modpow(input_blinded, key->private_exponent, key->modulus, key->p, key->q, key->iqmp); @@ -412,16 +420,18 @@ int rsa_verify(struct RSAKey *key) pm1 = copybn(key->p); decbn(pm1); ed = modmul(key->exponent, key->private_exponent, pm1); + freebn(pm1); cmp = bignum_cmp(ed, One); - sfree(ed); + freebn(ed); if (cmp != 0) return 0; qm1 = copybn(key->q); decbn(qm1); ed = modmul(key->exponent, key->private_exponent, qm1); + freebn(qm1); cmp = bignum_cmp(ed, One); - sfree(ed); + freebn(ed); if (cmp != 0) return 0; @@ -440,6 +450,8 @@ int rsa_verify(struct RSAKey *key) freebn(key->iqmp); key->iqmp = modinv(key->q, key->p); + if (!key->iqmp) + return 0; } /* @@ -447,7 +459,7 @@ int rsa_verify(struct RSAKey *key) */ n = modmul(key->iqmp, key->q, key->p); cmp = bignum_cmp(n, One); - sfree(n); + freebn(n); if (cmp != 0) return 0; @@ -548,6 +560,8 @@ static Bignum getmp(char **data, int *datalen) return b; } +static void rsa2_freekey(void *key); /* forward reference */ + static void *rsa2_newkey(char *data, int len) { char *p; @@ -555,8 +569,6 @@ static void *rsa2_newkey(char *data, int len) struct RSAKey *rsa; rsa = snew(struct RSAKey); - if (!rsa) - return NULL; getstring(&data, &len, &p, &slen); if (!p || slen != 7 || memcmp(p, "ssh-rsa", 7)) { @@ -569,6 +581,11 @@ static void *rsa2_newkey(char *data, int len) rsa->p = rsa->q = rsa->iqmp = NULL; rsa->comment = NULL; + if (!rsa->exponent || !rsa->modulus) { + rsa2_freekey(rsa); + return NULL; + } + return rsa; } @@ -691,8 +708,6 @@ static void *rsa2_openssh_createkey(unsigned char **blob, int *len) struct RSAKey *rsa; rsa = snew(struct RSAKey); - if (!rsa) - return NULL; rsa->comment = NULL; rsa->modulus = getmp(b, len); @@ -704,13 +719,12 @@ static void *rsa2_openssh_createkey(unsigned char **blob, int *len) if (!rsa->modulus || !rsa->exponent || !rsa->private_exponent || !rsa->iqmp || !rsa->p || !rsa->q) { - sfree(rsa->modulus); - sfree(rsa->exponent); - sfree(rsa->private_exponent); - sfree(rsa->iqmp); - sfree(rsa->p); - sfree(rsa->q); - sfree(rsa); + rsa2_freekey(rsa); + return NULL; + } + + if (!rsa_verify(rsa)) { + rsa2_freekey(rsa); return NULL; } @@ -839,6 +853,8 @@ static int rsa2_verifysig(void *key, char *sig, int siglen, return 0; } in = getmp(&sig, &siglen); + if (!in) + return 0; out = modpow(in, rsa->exponent, rsa->modulus); freebn(in); diff --git a/source/putty/windows/WINNET.C b/source/putty/windows/WINNET.C index 49c757d71..b5546f50e 100644 --- a/source/putty/windows/WINNET.C +++ b/source/putty/windows/WINNET.C @@ -1296,7 +1296,7 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, if (p_listen(s, SOMAXCONN) == SOCKET_ERROR) { p_closesocket(s); - ret->error = winsock_error_string(err); + ret->error = winsock_error_string(p_WSAGetLastError()); return (Socket) ret; } diff --git a/source/resource/TextsCore.h b/source/resource/TextsCore.h index 0fabacc45..6dcdee70f 100644 --- a/source/resource/TextsCore.h +++ b/source/resource/TextsCore.h @@ -222,6 +222,7 @@ #define NET_TRANSL_HOST_NOT_EXIST 296 #define NET_TRANSL_PACKET_GARBLED 297 #define REPORT_ERROR 298 +#define TLS_CERT_DECODE_ERROR 299 #define CORE_CONFIRMATION_STRINGS 300 #define CONFIRM_PROLONG_TIMEOUT3 301 @@ -398,9 +399,8 @@ #define PUTTY_VERSION 602 #define PUTTY_COPYRIGHT 603 #define PUTTY_URL 604 -#define FILEZILLA_BASED_ON 605 -#define FILEZILLA_VERSION 606 -#define FILEZILLA_COPYRIGHT 607 +#define FILEZILLA_BASED_ON2 605 +#define FILEZILLA_COPYRIGHT2 607 #define FILEZILLA_URL 608 #define OPENSSL_BASED_ON 609 #define OPENSSL_COPYRIGHT 610 diff --git a/source/resource/TextsCore1.rc b/source/resource/TextsCore1.rc index 296c2050c..3905a85a1 100644 --- a/source/resource/TextsCore1.rc +++ b/source/resource/TextsCore1.rc @@ -187,6 +187,7 @@ BEGIN NET_TRANSL_HOST_NOT_EXIST, "Host does not exist." NET_TRANSL_PACKET_GARBLED, "Incoming packet was garbled on decryption" REPORT_ERROR, "%s\n\nPlease report the error on WinSCP support forum." + TLS_CERT_DECODE_ERROR, "Error decoding TLS/SSL certificate (%s)." CORE_CONFIRMATION_STRINGS, "CORE_CONFIRMATION" CONFIRM_PROLONG_TIMEOUT3, "Host is not communicating for %d seconds.\n\nWait for another %0:d seconds?" @@ -360,12 +361,11 @@ BEGIN CORE_VARIABLE_STRINGS, "CORE_VARIABLE" PUTTY_BASED_ON, "SSH and SCP code based on PuTTY %s" - PUTTY_VERSION, "0.62" - PUTTY_COPYRIGHT, "Copyright © 1997-2011 Simon Tatham" + PUTTY_VERSION, "0.63" + PUTTY_COPYRIGHT, "Copyright © 1997-2013 Simon Tatham" PUTTY_URL, "http://www.chiark.greenend.org.uk/~sgtatham/putty/" - FILEZILLA_BASED_ON, "FTP code based on FileZilla %s" - FILEZILLA_VERSION, "2.2.32" - FILEZILLA_COPYRIGHT, "Copyright © 2001-2007 Tim Kosse" + FILEZILLA_BASED_ON2, "FTP code based on FileZilla" + FILEZILLA_COPYRIGHT2, "Copyright © Tim Kosse" FILEZILLA_URL, "http://filezilla-project.org/" OPENSSL_BASED_ON, "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s." OPENSSL_COPYRIGHT, "Copyright © 1998-2013 The OpenSSL Project" diff --git a/source/resource/TextsWin.h b/source/resource/TextsWin.h index 15d152d0e..90533725d 100644 --- a/source/resource/TextsWin.h +++ b/source/resource/TextsWin.h @@ -451,6 +451,8 @@ #define LOGIN_CANCEL_EDITING 1908 #define SAVE_SESSION_FOLDER 1909 #define SAVE_SESSION_ROOT_FOLDER 1910 +#define LOGIN_SHELL_PAGE 1911 +#define LOGIN_SCP_SHELL_PAGE 1912 // 2xxx is reserved for TextsFileZilla.h diff --git a/source/resource/TextsWin1.rc b/source/resource/TextsWin1.rc index a17186f72..50b157b77 100644 --- a/source/resource/TextsWin1.rc +++ b/source/resource/TextsWin1.rc @@ -453,6 +453,8 @@ BEGIN LOGIN_CANCEL_EDITING, "This will cancel site editing. Do you want to continue?" SAVE_SESSION_FOLDER, "&Folder:" SAVE_SESSION_ROOT_FOLDER, "" + LOGIN_SHELL_PAGE, "Shell" + LOGIN_SCP_SHELL_PAGE, "SCP/Shell" WIN_VARIABLE_STRINGS, "WIN_VARIABLE" WINSCP_COPYRIGHT, "Copyright © 2000-2013 Martin Prikryl" diff --git a/source/windows/ConsoleRunner.cpp b/source/windows/ConsoleRunner.cpp index 55a0dda5e..4cbf02ce4 100644 --- a/source/windows/ConsoleRunner.cpp +++ b/source/windows/ConsoleRunner.cpp @@ -114,25 +114,13 @@ __fastcall TOwnConsole::TOwnConsole() if (WinConfiguration->MinimizeToTray) { - HINSTANCE Kernel32 = GetModuleHandle(kernel32); - - typedef HWND WINAPI (* TGetConsoleWindow)(); - TGetConsoleWindow GetConsoleWindow = - (TGetConsoleWindow)GetProcAddress(Kernel32, "GetConsoleWindow"); - if (GetConsoleWindow != NULL) + FConsoleWindow = GetConsoleWindow(); + if (ALWAYS_TRUE(FConsoleWindow != NULL)) { - FConsoleWindow = GetConsoleWindow(); - if (FConsoleWindow != NULL) - { - FWindowStateTimer = new TTimer(Application); - FWindowStateTimer->OnTimer = WindowStateTimer; - FWindowStateTimer->Interval = 250; - FWindowStateTimer->Enabled = true; - } - else - { - assert(false); - } + FWindowStateTimer = new TTimer(Application); + FWindowStateTimer->OnTimer = WindowStateTimer; + FWindowStateTimer->Interval = 250; + FWindowStateTimer->Enabled = true; } } } @@ -560,25 +548,15 @@ __fastcall TExternalConsole::TExternalConsole( throw Exception(LoadStr(EXTERNAL_CONSOLE_INIT_ERROR)); } - HINSTANCE Kernel32 = GetModuleHandle(kernel32); - typedef HANDLE WINAPI (* TOpenJobObject)(DWORD DesiredAccess, BOOL InheritHandles, LPCTSTR Name); - typedef HANDLE WINAPI (* TAssignProcessToJobObject)(HANDLE Job, HANDLE Process); - TOpenJobObject OpenJobObject = - (TOpenJobObject)GetProcAddress(Kernel32, "OpenJobObjectW"); - TAssignProcessToJobObject AssignProcessToJobObject = - (TAssignProcessToJobObject)GetProcAddress(Kernel32, "AssignProcessToJobObject"); - if ((OpenJobObject != NULL) && (AssignProcessToJobObject != NULL)) + HANDLE Job = OpenJobObject(JOB_OBJECT_ASSIGN_PROCESS, FALSE, + FORMAT(L"%s%s", (CONSOLE_JOB, Instance)).c_str()); + if (ALWAYS_TRUE(Job != NULL)) { - HANDLE Job = OpenJobObject(JOB_OBJECT_ASSIGN_PROCESS, FALSE, - FORMAT(L"%s%s", (CONSOLE_JOB, Instance)).c_str()); - if (Job != NULL) - { - AssignProcessToJobObject(Job, GetCurrentProcess()); - // winscp.com keeps the only reference to the job. - // once it gets closed (because winscp.com if forcefully terminated), - // we get terminated as well - CloseHandle(Job); - } + AssignProcessToJobObject(Job, GetCurrentProcess()); + // winscp.com/winscp.dll keeps the only reference to the job. + // once it gets closed (because winscp.com if forcefully terminated), + // we get terminated as well + CloseHandle(Job); } TConsoleCommStruct * CommStruct = GetCommStruct(); @@ -1275,6 +1253,8 @@ void __fastcall TConsoleRunner::ScriptTerminalQueryUser(TObject * /*Sender*/, NoBatchA = Params->NoBatchAnswers; } + ApplyTabs(AQuery, L' ', NULL, NULL); + unsigned int AAnswers = Answers; PrintMessage(AQuery); diff --git a/source/windows/CustomWinConfiguration.cpp b/source/windows/CustomWinConfiguration.cpp index ca79457e6..ef7d6a1b0 100644 --- a/source/windows/CustomWinConfiguration.cpp +++ b/source/windows/CustomWinConfiguration.cpp @@ -9,6 +9,7 @@ #include #include "CustomWinConfiguration.h" #include +#include //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- @@ -81,18 +82,29 @@ void __fastcall TCustomWinConfiguration::DefaultHistory() FHistory->AddObject(L"PuttyPath", Strings.release()); } //--------------------------------------------------------------------------- +UnicodeString __fastcall TCustomWinConfiguration::FormatDefaultWindowSize(int Width, int Height) +{ + return FORMAT(L"%d,%d,%s", (Width, Height, SaveDefaultPixelsPerInch())); +} +//--------------------------------------------------------------------------- +UnicodeString __fastcall TCustomWinConfiguration::FormatDefaultWindowParams(int Width, int Height) +{ + return FORMAT(L"-1;-1;%d;%d;%d;%s", (Width, Height, int(wsNormal), SaveDefaultPixelsPerInch())); +} +//--------------------------------------------------------------------------- void __fastcall TCustomWinConfiguration::Default() { TGUIConfiguration::Default(); FInterface = FDefaultInterface; FLogView = lvNone; - FSynchronizeChecklist.WindowParams = L"0;-1;-1;600;450;0"; - FSynchronizeChecklist.ListParams = L"1;1|150,1;100,1;80,1;130,1;25,1;100,1;80,1;130,1|0;1;2;3;4;5;6;7"; - FFindFile.WindowParams = L"646,481"; - FFindFile.ListParams = L"3;1|125,1;181,1;80,1;122,1|0;1;2;3"; - FConsoleWin.WindowSize = L"570,430"; - FLoginDialog.WindowSize = L"640,430"; + // 0 means no "custom-pos" + FSynchronizeChecklist.WindowParams = L"0;" + FormatDefaultWindowParams(600, 450); + FSynchronizeChecklist.ListParams = L"1;1|150,1;100,1;80,1;130,1;25,1;100,1;80,1;130,1;@" + SaveDefaultPixelsPerInch() + L"|0;1;2;3;4;5;6;7"; + FFindFile.WindowParams = FormatDefaultWindowSize(646, 481); + FFindFile.ListParams = L"3;1|125,1;181,1;80,1;122,1;@" + SaveDefaultPixelsPerInch() + L"|0;1;2;3"; + FConsoleWin.WindowSize = FormatDefaultWindowSize(570, 430); + FLoginDialog.WindowSize = FormatDefaultWindowSize(640, 430); FConfirmExitOnCompletion = true; FOperationProgressOnTop = true; @@ -451,3 +463,33 @@ void __fastcall TCustomWinConfiguration::SetConfirmExitOnCompletion(bool value) { SET_CONFIG_PROPERTY(ConfirmExitOnCompletion); } +//--------------------------------------------------------------------------- +UnicodeString __fastcall TCustomWinConfiguration::GetDefaultFixedWidthFontName() +{ + // These are defaults for respective version of Windows Notepad + UnicodeString Result; + if (IsWin8()) + { + Result = L"Consolas"; + } + else + { + Result = L"Lucida Console"; + } + return Result; +} +//--------------------------------------------------------------------------- +int __fastcall TCustomWinConfiguration::GetDefaultFixedWidthFontSize() +{ + // These are defaults for respective version of Windows Notepad + int Result; + if (IsWin8()) + { + Result = 11; + } + else + { + Result = 10; + } + return Result; +} diff --git a/source/windows/CustomWinConfiguration.h b/source/windows/CustomWinConfiguration.h index 825b140ec..2194e3530 100644 --- a/source/windows/CustomWinConfiguration.h +++ b/source/windows/CustomWinConfiguration.h @@ -57,6 +57,8 @@ private: void __fastcall SetConsoleWin(TConsoleWinConfiguration value); void __fastcall SetLoginDialog(TLoginDialogConfiguration value); void __fastcall SetConfirmExitOnCompletion(bool value); + UnicodeString __fastcall GetDefaultFixedWidthFontName(); + int __fastcall GetDefaultFixedWidthFontSize(); protected: virtual void __fastcall SaveData(THierarchicalStorage * Storage, bool All); @@ -67,6 +69,8 @@ protected: virtual void __fastcall DefaultHistory(); void __fastcall RecryptPasswords(TStrings * RecryptPasswordErrors); virtual bool __fastcall GetUseMasterPassword() = 0; + UnicodeString __fastcall FormatDefaultWindowParams(int Width, int Height); + UnicodeString __fastcall FormatDefaultWindowSize(int Width, int Height); public: __fastcall TCustomWinConfiguration(); @@ -88,6 +92,8 @@ public: __property bool OperationProgressOnTop = { read=FOperationProgressOnTop, write=FOperationProgressOnTop }; __property bool UseMasterPassword = { read = GetUseMasterPassword }; __property TNotifyEvent OnMasterPasswordRecrypt = { read = FOnMasterPasswordRecrypt, write = FOnMasterPasswordRecrypt }; + __property UnicodeString DefaultFixedWidthFontName = { read = GetDefaultFixedWidthFontName }; + __property int DefaultFixedWidthFontSize = { read = GetDefaultFixedWidthFontSize }; }; //--------------------------------------------------------------------------- #define CustomWinConfiguration \ diff --git a/source/windows/GUIConfiguration.cpp b/source/windows/GUIConfiguration.cpp index 010f74956..85a0d9e56 100644 --- a/source/windows/GUIConfiguration.cpp +++ b/source/windows/GUIConfiguration.cpp @@ -150,7 +150,8 @@ bool __fastcall TCopyParamRule::Match(const UnicodeString & Mask, } else { - TFileMasks M(Mask); + TFileMasks M(1); + M.Masks = Mask; if (Path) { Result = M.Matches(Value, Local, true); @@ -523,6 +524,8 @@ __fastcall TGUIConfiguration::TGUIConfiguration(): TConfiguration() dynamic_cast(FLocales)->CaseSensitive = false; FCopyParamList = new TCopyParamList(); CoreSetResourceModule(GetResourceModule()); + // allow loading configured locale, DetectScalingType needs to get called + // only after that, but before user can ever try to change the locale FCanApplyLocaleImmediately = true; } //--------------------------------------------------------------------------- @@ -532,6 +535,12 @@ __fastcall TGUIConfiguration::~TGUIConfiguration() delete FCopyParamList; } //--------------------------------------------------------------------------- +void __fastcall TGUIConfiguration::DetectScalingType() +{ + // USER_DEFAULT_SCREEN_DPI (96) DPI is 100% + FCanApplyLocaleImmediately = (Screen->PixelsPerInch == USER_DEFAULT_SCREEN_DPI); +} +//--------------------------------------------------------------------------- void __fastcall TGUIConfiguration::Default() { TConfiguration::Default(); diff --git a/source/windows/GUIConfiguration.h b/source/windows/GUIConfiguration.h index 392fd7bad..5b65cdbe4 100644 --- a/source/windows/GUIConfiguration.h +++ b/source/windows/GUIConfiguration.h @@ -224,6 +224,7 @@ public: bool __fastcall AnyPuttySessionForImport(TStoredSessionList * Sessions); TStoredSessionList * __fastcall SelectFilezillaSessionsForImport(TStoredSessionList * Sessions); bool __fastcall AnyFilezillaSessionForImport(TStoredSessionList * Sessions); + void __fastcall DetectScalingType(); __property bool ContinueOnError = { read = FContinueOnError, write = FContinueOnError }; __property bool ConfirmCommandSession = { read = FConfirmCommandSession, write = FConfirmCommandSession }; diff --git a/source/windows/GUITools.cpp b/source/windows/GUITools.cpp index 6c7118b53..fa7c9ee28 100644 --- a/source/windows/GUITools.cpp +++ b/source/windows/GUITools.cpp @@ -13,6 +13,7 @@ #include #include #include +#include //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- @@ -402,6 +403,103 @@ void __fastcall AddSessionColorImage( ImageList->AddMasked(Bitmap.get(), TransparentColor); } //--------------------------------------------------------------------------- +bool __fastcall IsEligibleForApplyingTabs( + UnicodeString Line, int & TabPos, UnicodeString & Start, UnicodeString & Remaining) +{ + bool Result = false; + TabPos = Line.Pos(L"\t"); + if (TabPos > 0) + { + Remaining = Line.SubString(TabPos + 1, Line.Length() - TabPos); + // WORKAROUND + // Some translations still use obsolete hack of consecutive tabs to aling the contents. + // Delete these, so that the following check does not fail on this + while (Remaining.SubString(1, 1) == L"\t") + { + Remaining.Delete(1, 1); + } + + // We do not have, not support, mutiple tabs on a single line + if (ALWAYS_TRUE(Remaining.Pos(L"\t") == 0)) + { + Start = Line.SubString(1, TabPos - 1); + // WORAROUND + // Previously we padded the string before tab with spaces, + // to aling the contents across multiple lines + Start = Start.TrimRight(); + // at least two normal spaces for separation + Start += L" "; + Result = true; + } + } + return Result; +} +//--------------------------------------------------------------------------- +static int __fastcall CalculateWidthByLength(UnicodeString Text, void * /*Arg*/) +{ + return Text.Length(); +} +//--------------------------------------------------------------------------- +void __fastcall ApplyTabs( + UnicodeString & Text, wchar_t Padding, + TCalculateWidth CalculateWidth, void * CalculateWidthArg) +{ + if (CalculateWidth == NULL) + { + assert(CalculateWidthArg == NULL); + CalculateWidth = CalculateWidthByLength; + } + + std::auto_ptr Lines(new TStringList()); + Lines->Text = Text; + + int MaxWidth = -1; + for (int Index = 0; Index < Lines->Count; Index++) + { + UnicodeString Line = Lines->Strings[Index]; + int TabPos; + UnicodeString Start; + UnicodeString Remaining; + if (IsEligibleForApplyingTabs(Line, TabPos, Start, Remaining)) + { + int Width = CalculateWidth(Start, CalculateWidthArg); + MaxWidth = Max(MaxWidth, Width); + } + } + + // Optimization and also to prevent potential regression for texts without tabs + if (MaxWidth >= 0) + { + for (int Index = 0; Index < Lines->Count; Index++) + { + UnicodeString Line = Lines->Strings[Index]; + int TabPos; + UnicodeString Start; + UnicodeString Remaining; + if (IsEligibleForApplyingTabs(Line, TabPos, Start, Remaining)) + { + int Width; + while ((Width = CalculateWidth(Start, CalculateWidthArg)) < MaxWidth) + { + int Wider = CalculateWidth(Start + Padding, CalculateWidthArg); + // If padded string is wider than max width by more pixels + // than non-padded string is shorter than max width + if ((Wider > MaxWidth) && ((Wider - MaxWidth) > (MaxWidth - Width))) + { + break; + } + Start += Padding; + } + Lines->Strings[Index] = Start + Remaining; + } + } + + Text = Lines->Text; + // remove trailing newline + Text = Text.TrimRight(); + } +} +//--------------------------------------------------------------------------- TLocalCustomCommand::TLocalCustomCommand() { } diff --git a/source/windows/GUITools.h b/source/windows/GUITools.h index 13031ce1c..a8f49594f 100644 --- a/source/windows/GUITools.h +++ b/source/windows/GUITools.h @@ -41,6 +41,10 @@ UnicodeString __fastcall UniqTempDir(const UnicodeString BaseDir, bool __fastcall DeleteDirectory(const UnicodeString DirName); UnicodeString __fastcall FormatDateTimeSpan(const UnicodeString TimeFormat, TDateTime DateTime); void __fastcall AddSessionColorImage(TCustomImageList * ImageList, TColor Color, bool Disconnected); +typedef int __fastcall (*TCalculateWidth)(UnicodeString Text, void * Arg); +void __fastcall ApplyTabs( + UnicodeString & Text, wchar_t Padding, + TCalculateWidth CalculateWidth, void * CalculateWidthArg); //--------------------------------------------------------------------------- class TLocalCustomCommand : public TFileCustomCommand { diff --git a/source/windows/TerminalManager.cpp b/source/windows/TerminalManager.cpp index 09ec1be9d..1b87d8e74 100644 --- a/source/windows/TerminalManager.cpp +++ b/source/windows/TerminalManager.cpp @@ -79,6 +79,10 @@ __fastcall TTerminalManager::TTerminalManager() : Application->OnShowHint = ApplicationShowHint; assert(Application->OnMessage == NULL); Application->OnMessage = ApplicationMessage; + assert(Application->OnModalBegin == NULL); + Application->OnModalBegin = ApplicationModalBegin; + assert(Application->OnModalEnd == NULL); + Application->OnModalEnd = ApplicationModalEnd; assert(WinConfiguration->OnMasterPasswordPrompt == NULL); WinConfiguration->OnMasterPasswordPrompt = MasterPasswordPrompt; @@ -109,6 +113,10 @@ __fastcall TTerminalManager::~TTerminalManager() Application->OnShowHint = ApplicationShowHint; assert(Application->OnMessage == ApplicationMessage); Application->OnMessage = NULL; + assert(Application->OnModalBegin == ApplicationModalBegin); + Application->OnModalBegin = NULL; + assert(Application->OnModalEnd == ApplicationModalEnd); + Application->OnModalEnd = NULL; assert(WinConfiguration->OnMasterPasswordPrompt == MasterPasswordPrompt); WinConfiguration->OnMasterPasswordPrompt = NULL; @@ -835,6 +843,16 @@ void __fastcall TTerminalManager::ApplicationMessage(TMsg & Msg, bool & Handled) } } //--------------------------------------------------------------------------- +void __fastcall TTerminalManager::ApplicationModalBegin(TObject * /*Sender*/) +{ + NonVisualDataModule->StartBusy(); +} +//--------------------------------------------------------------------------- +void __fastcall TTerminalManager::ApplicationModalEnd(TObject * /*Sender*/) +{ + NonVisualDataModule->EndBusy(); +} +//--------------------------------------------------------------------------- void __fastcall TTerminalManager::InitTaskbarButtonCreatedMessage() { @@ -1320,12 +1338,14 @@ void __fastcall TTerminalManager::OpenInPutty() try { assert(ActiveTerminal != NULL); - ScpExplorer->UpdateTerminal(ActiveTerminal); - Data->Assign(ActiveTerminal->SessionData); - Data->RemoteDirectory = - NOT_NULL(dynamic_cast(ActiveTerminal))->RemoteDirectory; + if (ScpExplorer != NULL) + { + ScpExplorer->UpdateTerminal(ActiveTerminal); + Data->RemoteDirectory = + NOT_NULL(dynamic_cast(ActiveTerminal))->RemoteDirectory; + } // putty does not support resolving environment variables in session settings Data->ExpandEnvironmentVariables(); diff --git a/source/windows/TerminalManager.h b/source/windows/TerminalManager.h index 1cda7848e..5a9ec7795 100644 --- a/source/windows/TerminalManager.h +++ b/source/windows/TerminalManager.h @@ -157,6 +157,8 @@ private: TTerminal * __fastcall DoNewTerminal(TSessionData * Data); static void __fastcall TerminalThreadIdle(void * Data, TObject * Sender); void __fastcall SetQueueConfiguration(TTerminalQueue * Queue); + void __fastcall ApplicationModalBegin(TObject * Sender); + void __fastcall ApplicationModalEnd(TObject * Sender); }; //--------------------------------------------------------------------------- #endif diff --git a/source/windows/Tools.cpp b/source/windows/Tools.cpp index 833651acd..303d9311c 100644 --- a/source/windows/Tools.cpp +++ b/source/windows/Tools.cpp @@ -1,5 +1,4 @@ //--------------------------------------------------------------------------- -#define NO_WIN32_LEAN_AND_MEAN #include #pragma hdrstop @@ -27,6 +26,45 @@ #include #include //--------------------------------------------------------------------------- +// WORAROUND +// VCL includes wininet.h (even with NO_WIN32_LEAN_AND_MEAN) +// and it cannot be compined with winhttp.h as of current Windows SDK. +// This is hack to allow that. +// http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/8f468d9f-3f15-452c-803d-fc63ab3f684e/cannot-use-both-winineth-and-winhttph +#undef BOOLAPI +#undef SECURITY_FLAG_IGNORE_CERT_DATE_INVALID +#undef SECURITY_FLAG_IGNORE_CERT_CN_INVALID + +#define URL_COMPONENTS URL_COMPONENTS_ANOTHER +#define URL_COMPONENTSA URL_COMPONENTSA_ANOTHER +#define URL_COMPONENTSW URL_COMPONENTSW_ANOTHER + +#define LPURL_COMPONENTS LPURL_COMPONENTS_ANOTHER +#define LPURL_COMPONENTSA LPURL_COMPONENTS_ANOTHER +#define LPURL_COMPONENTSW LPURL_COMPONENTS_ANOTHER + +#define INTERNET_SCHEME INTERNET_SCHEME_ANOTHER +#define LPINTERNET_SCHEME LPINTERNET_SCHEME_ANOTHER + +#define HTTP_VERSION_INFO HTTP_VERSION_INFO_ANOTHER +#define LPHTTP_VERSION_INFO LPHTTP_VERSION_INFO_ANOTHER + +#include + +#undef URL_COMPONENTS +#undef URL_COMPONENTSA +#undef URL_COMPONENTSW + +#undef LPURL_COMPONENTS +#undef LPURL_COMPONENTSA +#undef LPURL_COMPONENTSW + +#undef INTERNET_SCHEME +#undef LPINTERNET_SCHEME + +#undef HTTP_VERSION_INFO +#undef LPHTTP_VERSION_INFO +//--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- TFontStyles __fastcall IntToFontStyles(int value) @@ -69,22 +107,30 @@ UnicodeString __fastcall GetListViewStr(TListView * ListView) UnicodeString Result; for (int Index = 0; Index < ListView->Columns->Count; Index++) { - if (!Result.IsEmpty()) - { - Result += L","; - } - Result += IntToStr(ListView->Column[Index]->Width); + AddToList(Result, IntToStr(ListView->Column[Index]->Width), L","); } + // WORKAROUND + // Adding an additional comma after the list, + // to ensure that old versions that did not expect the pixels-per-inch part, + // stop at the comma, otherwise they try to parse the + // "last-column-width;pixels-per-inch" as integer and throw. + // For the other instance of this hack, see TCustomListViewColProperties.GetParamsStr + Result += L",;" + SavePixelsPerInch(); return Result; } //--------------------------------------------------------------------------- -void __fastcall LoadListViewStr(TListView * ListView, UnicodeString LayoutStr) +void __fastcall LoadListViewStr(TListView * ListView, UnicodeString ALayoutStr) { + UnicodeString LayoutStr = ::CutToChar(ALayoutStr, L';', true); + int PixelsPerInch = LoadPixelsPerInch(::CutToChar(ALayoutStr, L';', true)); int Index = 0; while (!LayoutStr.IsEmpty() && (Index < ListView->Columns->Count)) { - ListView->Column[Index]->Width = StrToIntDef( - ::CutToChar(LayoutStr, L',', true), ListView->Column[Index]->Width); + int Width; + if (TryStrToInt(::CutToChar(LayoutStr, L',', true), Width)) + { + ListView->Column[Index]->Width = LoadDimension(Width, PixelsPerInch); + } Index++; } } @@ -96,9 +142,16 @@ void __fastcall RestoreForm(UnicodeString Data, TForm * Form) { Forms::TMonitor * Monitor = FormMonitor(Form); + UnicodeString LeftStr = ::CutToChar(Data, L';', true); + UnicodeString TopStr = ::CutToChar(Data, L';', true); + UnicodeString RightStr = ::CutToChar(Data, L';', true); + UnicodeString BottomStr = ::CutToChar(Data, L';', true); + TWindowState State = (TWindowState)StrToIntDef(::CutToChar(Data, L';', true), (int)wsNormal); + int PixelsPerInch = LoadPixelsPerInch(::CutToChar(Data, L';', true)); + TRect Bounds = Form->BoundsRect; - int Left = StrToIntDef(::CutToChar(Data, L';', true), Bounds.Left); - int Top = StrToIntDef(::CutToChar(Data, L';', true), Bounds.Top); + int Left = StrToDimensionDef(LeftStr, PixelsPerInch, Bounds.Left); + int Top = StrToDimensionDef(TopStr, PixelsPerInch, Bounds.Top); bool DefaultPos = (Left == -1) && (Top == -1); if (!DefaultPos) { @@ -110,9 +163,8 @@ void __fastcall RestoreForm(UnicodeString Data, TForm * Form) Bounds.Left = 0; Bounds.Top = 0; } - Bounds.Right = StrToIntDef(::CutToChar(Data, L';', true), Bounds.Right); - Bounds.Bottom = StrToIntDef(::CutToChar(Data, L';', true), Bounds.Bottom); - TWindowState State = (TWindowState)StrToIntDef(::CutToChar(Data, L';', true), (int)wsNormal); + Bounds.Right = StrToDimensionDef(RightStr, PixelsPerInch, Bounds.Right); + Bounds.Bottom = StrToDimensionDef(BottomStr, PixelsPerInch, Bounds.Bottom); Form->WindowState = State; if (State == wsNormal) { @@ -185,24 +237,29 @@ UnicodeString __fastcall StoreForm(TCustomForm * Form) assert(Form); TRect Bounds = Form->BoundsRect; OffsetRect(Bounds, -Form->Monitor->Left, -Form->Monitor->Top); - return FORMAT(L"%d;%d;%d;%d;%d", ((int)Bounds.Left, (int)Bounds.Top, - (int)Bounds.Right, (int)Bounds.Bottom, + return FORMAT(L"%d;%d;%d;%d;%d;%s", (SaveDimension(Bounds.Left), SaveDimension(Bounds.Top), + SaveDimension(Bounds.Right), SaveDimension(Bounds.Bottom), // we do not want WinSCP to start minimized next time (we cannot handle that anyway). // note that WindowState is wsNormal when window in minimized for some reason. // actually it is wsMinimized only when minimized by MSVDM - (int)(Form->WindowState == wsMinimized ? wsNormal : Form->WindowState))); + (int)(Form->WindowState == wsMinimized ? wsNormal : Form->WindowState), + SavePixelsPerInch())); } //--------------------------------------------------------------------------- void __fastcall RestoreFormSize(UnicodeString Data, TForm * Form) { - int Width = StrToIntDef(::CutToChar(Data, L',', true), Form->Width); - int Height = StrToIntDef(::CutToChar(Data, L',', true), Form->Height); + UnicodeString WidthStr = ::CutToChar(Data, L',', true); + UnicodeString HeightStr = ::CutToChar(Data, L',', true); + int PixelsPerInch = LoadPixelsPerInch(::CutToChar(Data, L',', true)); + + int Width = StrToDimensionDef(WidthStr, PixelsPerInch, Form->Width); + int Height = StrToDimensionDef(HeightStr, PixelsPerInch, Form->Height); ResizeForm(Form, Width, Height); } //--------------------------------------------------------------------------- UnicodeString __fastcall StoreFormSize(TForm * Form) { - return FORMAT(L"%d,%d", (Form->Width, Form->Height)); + return FORMAT(L"%d,%d,%s", (Form->Width, Form->Height, SavePixelsPerInch())); } //--------------------------------------------------------------------------- bool __fastcall ExecuteShellAndWait(const UnicodeString Path, const UnicodeString Params) @@ -759,25 +816,13 @@ bool __fastcall IsWin64() static int Result = -1; if (Result < 0) { - typedef BOOL WINAPI (*IsWow64ProcessType)(HANDLE Process, PBOOL Wow64Process); - Result = 0; - - HMODULE Kernel = GetModuleHandle(kernel32); - if (Kernel != NULL) + BOOL Wow64Process = FALSE; + if (IsWow64Process(GetCurrentProcess(), &Wow64Process)) { - IsWow64ProcessType IsWow64Process = - (IsWow64ProcessType)GetProcAddress(Kernel, "IsWow64Process"); - if (IsWow64Process != NULL) + if (Wow64Process) { - BOOL Wow64Process = FALSE; - if (IsWow64Process(GetCurrentProcess(), &Wow64Process)) - { - if (Wow64Process) - { - Result = 1; - } - } + Result = 1; } } } @@ -886,43 +931,16 @@ void __fastcall VerifyKeyIncludingVersion(UnicodeString FileName, TSshProt SshPr } //--------------------------------------------------------------------------- // Code from http://gentoo.osuosl.org/distfiles/cl331.zip/io/ - -// The autoproxy functions were only documented in WinHTTP 5.1, so we have to -// provide the necessary defines and structures ourselves -#ifndef WINHTTP_ACCESS_TYPE_DEFAULT_PROXY - -#define HINTERNET HANDLE - -typedef struct -{ - WORD dwAccessType; - LPWSTR lpszProxy; - LPWSTR lpszProxyBypass; -} WINHTTP_PROXY_INFO; - -typedef struct { - BOOL fAutoDetect; - LPWSTR lpszAutoConfigUrl; - LPWSTR lpszProxy; - LPWSTR lpszProxyBypass; -} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; - -#endif /* WinHTTP 5.1 defines and structures */ - -typedef BOOL (*WINHTTPGETDEFAULTPROXYCONFIGURATION)(WINHTTP_PROXY_INFO * pProxyInfo); -typedef BOOL (*WINHTTPGETIEPROXYCONFIGFORCURRENTUSER)( - IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig); - WINHTTP_CURRENT_USER_IE_PROXY_CONFIG IEProxyInfo; -static HMODULE WinHTTP = NULL; -static WINHTTPGETDEFAULTPROXYCONFIGURATION WinHttpGetDefaultProxyConfiguration = NULL; -static WINHTTPGETIEPROXYCONFIGFORCURRENTUSER WinHttpGetIEProxyConfigForCurrentUser = NULL; +//--------------------------------------------------------------------------- +// this was moved to global scope in past in some attempt to fix crashes, +// not sure it really helped +WINHTTP_CURRENT_USER_IE_PROXY_CONFIG IEProxyInfo; //--------------------------------------------------------------------------- static bool __fastcall GetProxyUrlFromIE(UnicodeString & Proxy) { bool Result = false; memset(&IEProxyInfo, 0, sizeof(IEProxyInfo)); - if ((WinHttpGetIEProxyConfigForCurrentUser != NULL) && - WinHttpGetIEProxyConfigForCurrentUser(&IEProxyInfo)) + if (WinHttpGetIEProxyConfigForCurrentUser(&IEProxyInfo)) { if (IEProxyInfo.lpszProxy != NULL) { @@ -944,83 +962,41 @@ static bool __fastcall GetProxyUrlFromIE(UnicodeString & Proxy) //--------------------------------------------------------------------------- bool __fastcall AutodetectProxyUrl(UnicodeString & Proxy) { + bool Result = false; - bool Result = true; - - /* Under Win2K SP3, XP and 2003 (or at least Windows versions with - WinHTTP 5.1 installed in some way, it officially shipped with the - versions mentioned earlier) we can use WinHTTP AutoProxy support, - which implements the Web Proxy Auto-Discovery (WPAD) protocol from - an internet draft that expired in May 2001. Under older versions of - Windows we have to use the WinINet InternetGetProxyInfo, however this - consists of a ghastly set of kludges that were never meant to be - exposed to the outside world (they were only crowbarred out of MS - as part of the DoJ consent decree), and user experience with them is - that they don't really work except in the one special way in which - MS-internal code calls them. Since we don't know what this is, we - use the WinHTTP functions instead */ - if (WinHTTP == NULL) + /* Forst we try for proxy info direct from the registry if + it's available. */ + WINHTTP_PROXY_INFO ProxyInfo; + memset(&ProxyInfo, 0, sizeof(ProxyInfo)); + if (WinHttpGetDefaultProxyConfiguration(&ProxyInfo)) { - if ((WinHTTP = LoadLibrary(L"WinHTTP.dll")) == NULL) + if (ProxyInfo.lpszProxy != NULL) { - Result = false; + Proxy = ProxyInfo.lpszProxy; + GlobalFree(ProxyInfo.lpszProxy); + Result = true; } - else + if (ProxyInfo.lpszProxyBypass != NULL) { - WinHttpGetDefaultProxyConfiguration = (WINHTTPGETDEFAULTPROXYCONFIGURATION) - GetProcAddress(WinHTTP, "WinHttpGetDefaultProxyConfiguration"); - WinHttpGetIEProxyConfigForCurrentUser = (WINHTTPGETIEPROXYCONFIGFORCURRENTUSER) - GetProcAddress(WinHTTP, "WinHttpGetIEProxyConfigForCurrentUser"); - if ((WinHttpGetDefaultProxyConfiguration == NULL) || - (WinHttpGetIEProxyConfigForCurrentUser == NULL)) - { - FreeLibrary(WinHTTP); - Result = false; - } + GlobalFree(ProxyInfo.lpszProxyBypass); } } - if (Result) + /* The next fallback is to get the proxy info from MSIE. This is also + usually much quicker than WinHttpGetProxyForUrl(), although sometimes + it seems to fall back to that, based on the longish delay involved. + Another issue with this is that it won't work in a service process + that isn't impersonating an interactive user (since there isn't a + current user), but in that case we just fall back to + WinHttpGetProxyForUrl() */ + if (!Result) { - Result = false; - - /* Forst we try for proxy info direct from the registry if - it's available. */ - if (!Result) - { - WINHTTP_PROXY_INFO ProxyInfo; - memset(&ProxyInfo, 0, sizeof(ProxyInfo)); - if ((WinHttpGetDefaultProxyConfiguration != NULL) && - WinHttpGetDefaultProxyConfiguration(&ProxyInfo)) - { - if (ProxyInfo.lpszProxy != NULL) - { - Proxy = ProxyInfo.lpszProxy; - GlobalFree(ProxyInfo.lpszProxy); - Result = true; - } - if (ProxyInfo.lpszProxyBypass != NULL) - { - GlobalFree(ProxyInfo.lpszProxyBypass); - } - } - } - - /* The next fallback is to get the proxy info from MSIE. This is also - usually much quicker than WinHttpGetProxyForUrl(), although sometimes - it seems to fall back to that, based on the longish delay involved. - Another issue with this is that it won't work in a service process - that isn't impersonating an interactive user (since there isn't a - current user), but in that case we just fall back to - WinHttpGetProxyForUrl() */ - if (!Result) - { - Result = GetProxyUrlFromIE(Proxy); - } - - // We can also use WinHttpGetProxyForUrl, but it is lengthy - // See the source address of the code for example + Result = GetProxyUrlFromIE(Proxy); } + + // We can also use WinHttpGetProxyForUrl, but it is lengthy + // See the source address of the code for example + return Result; } //--------------------------------------------------------------------------- diff --git a/source/windows/UserInterface.cpp b/source/windows/UserInterface.cpp index 30c86c584..215e14f56 100644 --- a/source/windows/UserInterface.cpp +++ b/source/windows/UserInterface.cpp @@ -284,6 +284,22 @@ void __fastcall DoProductLicense() { DoLicenseDialog(lcWinScp); } +//--------------------------------------------------------------------------- +const UnicodeString PixelsPerInchKey = L"PixelsPerInch"; +//--------------------------------------------------------------------- +int __fastcall GetToolbarLayoutPixelsPerInch(TStrings * Storage) +{ + int Result; + if (Storage->IndexOfName(PixelsPerInchKey)) + { + Result = LoadPixelsPerInch(Storage->Values[PixelsPerInchKey]); + } + else + { + Result = -1; + } + return Result; +} //--------------------------------------------------------------------- static inline void __fastcall GetToolbarKey(const UnicodeString & ToolbarName, const UnicodeString & Value, UnicodeString & ToolbarKey) @@ -317,6 +333,28 @@ static int __fastcall ToolbarReadInt(const UnicodeString ToolbarName, if (Storage->IndexOfName(ToolbarKey) >= 0) { Result = StrToIntDef(Storage->Values[ToolbarKey], Default); + #if 0 + // this does not work well, as it scales down the stretched + // toolbars (path toolbars) too much, it has to be reimplemented smarter + if (Value == L"DockPos") + { + int PixelsPerInch = GetToolbarLayoutPixelsPerInch(Storage); + // When DPI has decreased since the last time, scale down + // toolbar position to get rid of gaps caused by smaller labels. + // Do not do this when DPI has increased as it would introduce gaps, + // as toolbars consists mostly of icons only, that do not scale. + // The toolbars shift themselves anyway, when other toolbars to the left + // get wider. We also risk a bit that toolbar order changes, + // as with very small toolbars (History) we can get scaled down position + // of the following toolbar to the left of it. + // There's special handling (also for scaling-up) stretched toolbars + // in LoadToolbarsLayoutStr + if ((PixelsPerInch > 0) && (Screen->PixelsPerInch < PixelsPerInch)) + { + Result = LoadDimension(Result, PixelsPerInch); + } + } + #endif } else { @@ -375,6 +413,7 @@ UnicodeString __fastcall GetToolbarsLayoutStr(const TComponent * OwnerComponent) { TBCustomSavePositions(OwnerComponent, ToolbarWriteInt, ToolbarWriteString, Storage); + Storage->Values[PixelsPerInchKey] = SavePixelsPerInch(); Result = Storage->CommaText; } __finally @@ -384,7 +423,7 @@ UnicodeString __fastcall GetToolbarsLayoutStr(const TComponent * OwnerComponent) return Result; } //--------------------------------------------------------------------------- -void __fastcall LoadToolbarsLayoutStr(const TComponent * OwnerComponent, UnicodeString LayoutStr) +void __fastcall LoadToolbarsLayoutStr(TComponent * OwnerComponent, UnicodeString LayoutStr) { TStrings * Storage = new TStringList(); try @@ -392,6 +431,42 @@ void __fastcall LoadToolbarsLayoutStr(const TComponent * OwnerComponent, Unicode Storage->CommaText = LayoutStr; TBCustomLoadPositions(OwnerComponent, ToolbarReadInt, ToolbarReadString, Storage); + int PixelsPerInch = GetToolbarLayoutPixelsPerInch(Storage); + // Scale toolbars stretched to the first other toolbar to the right + if ((PixelsPerInch > 0) && (PixelsPerInch != Screen->PixelsPerInch)) // optimization + { + for (int Index = 0; Index < OwnerComponent->ComponentCount; Index++) + { + TTBXToolbar * Toolbar = + dynamic_cast(OwnerComponent->Components[Index]); + if ((Toolbar != NULL) && Toolbar->Stretch && + (Toolbar->OnGetBaseSize != NULL) && + // we do not support floating of stretched toolbars + ALWAYS_TRUE(!Toolbar->Floating)) + { + TTBXToolbar * FollowingToolbar = NULL; + for (int Index2 = 0; Index2 < OwnerComponent->ComponentCount; Index2++) + { + TTBXToolbar * Toolbar2 = + dynamic_cast(OwnerComponent->Components[Index2]); + if ((Toolbar2 != NULL) && !Toolbar2->Floating && + (Toolbar2->Parent == Toolbar->Parent) && + (Toolbar2->DockRow == Toolbar->DockRow) && + (Toolbar2->DockPos > Toolbar->DockPos) && + ((FollowingToolbar == NULL) || (FollowingToolbar->DockPos > Toolbar2->DockPos))) + { + FollowingToolbar = Toolbar2; + } + } + + if (FollowingToolbar != NULL) + { + int NewWidth = LoadDimension(Toolbar->Width, PixelsPerInch); + FollowingToolbar->DockPos += NewWidth - Toolbar->Width; + } + } + } + } } __finally { @@ -406,10 +481,10 @@ void __fastcall AddMenuSeparator(TTBCustomItem * Menu) } //--------------------------------------------------------------------------- static TComponent * LastPopupComponent = NULL; -static TPoint LastPopupPoint(-1, -1); +static TRect LastPopupRect(-1, -1, -1, -1); static TDateTime LastCloseUp; //--------------------------------------------------------------------------- -void __fastcall MenuPopup(TPopupMenu * AMenu, TPoint Point, +void __fastcall MenuPopup(TPopupMenu * AMenu, TRect Rect, TComponent * PopupComponent) { // Pressing the same button within 200ms after closing its popup menu @@ -423,7 +498,7 @@ void __fastcall MenuPopup(TPopupMenu * AMenu, TPoint Point, TDateTime N = Now(); TDateTime Diff = N - LastCloseUp; if ((PopupComponent == LastPopupComponent) && - (Point == LastPopupPoint) && + (Rect == LastPopupRect) && (Diff < TDateTime(0, 0, 0, 200))) { LastPopupComponent = NULL; @@ -490,10 +565,10 @@ void __fastcall MenuPopup(TPopupMenu * AMenu, TPoint Point, } Menu->PopupComponent = PopupComponent; - Menu->Popup(Point.x, Point.y); + Menu->PopupEx(Rect); LastPopupComponent = PopupComponent; - LastPopupPoint = Point; + LastPopupRect = Rect; LastCloseUp = Now(); } } diff --git a/source/windows/VCLCommon.cpp b/source/windows/VCLCommon.cpp index 2e84bc35d..9f7861b31 100644 --- a/source/windows/VCLCommon.cpp +++ b/source/windows/VCLCommon.cpp @@ -281,6 +281,64 @@ void __fastcall FinalizeSystemSettings() { } //--------------------------------------------------------------------------- +#ifdef _DEBUG +void __fastcall VerifyControl(TControl * Control) +{ + // If at this time the control has allocated persistence data that are used + // for delayed handle recreation, we are at potential risk, as the future + // de-persistence may overwrite meanwhile changed data. + // For instance it may happen with list view that DPI scaling gets lost. + // This for example happens when the list view has both design time + // ReadOnly = true and some items set. We cannot usually explicitly + // check for the presence of items as while the listview does not have + // a handle allocated, item count querying does not work + // (see also a check below) + assert(!ControlHasRecreationPersistenceData(Control)); + + TCustomListView * ListView = dynamic_cast(Control); + if (ListView != NULL) + { + // As of now the HandleAllocated check is pointless as + // ListView->Items->Count returns 0 when the handle is not allocated yet. + // But we want to know if the implementation ever changes to allocate the handle + // on the call. Because we do not want to allocate a handle here as + // that would change the debug mode behaviour from release behaviour, + // possibly hiding away some problems. + assert(!ListView->HandleAllocated() || (ListView->Items->Count == 0)); + } +} +#endif +//--------------------------------------------------------------------------- +void __fastcall ApplySystemSettingsOnControl(TControl * Control) +{ + #ifdef _DEBUG + VerifyControl(Control); + #endif + + // WORKAROUND + // VCL does not scale status par panels (while for instance it does + // scale list view headers). Remove this if they ever "fix" this. + // For TBX status bars, this is implemented in TTBXCustomStatusBar.ChangeScale + TStatusBar * StatusBar = dynamic_cast(Control); + if (StatusBar != NULL) + { + for (int Index = 0; Index < StatusBar->Panels->Count; Index++) + { + TStatusPanel * Panel = StatusBar->Panels->Items[Index]; + Panel->Width = ScaleByTextHeight(StatusBar, Panel->Width); + } + } + + TWinControl * WinControl = dynamic_cast(Control); + if (WinControl != NULL) + { + for (int Index = 0; Index < WinControl->ControlCount; Index++) + { + ApplySystemSettingsOnControl(WinControl->Controls[Index]); + } + } +} +//--------------------------------------------------------------------------- // Settings that must be set as soon as possible. void __fastcall UseSystemSettingsPre(TCustomForm * Control, void ** Settings) { @@ -308,14 +366,13 @@ void __fastcall UseSystemSettingsPre(TCustomForm * Control, void ** Settings) Control->WindowProc = WindowProc; - assert(Control && Control->Font); - Control->Font->Name = L"MS Shell Dlg"; - if (Control->HelpKeyword.IsEmpty()) { // temporary help keyword to enable F1 key in all forms Control->HelpKeyword = L"start"; } + + ApplySystemSettingsOnControl(Control); }; //--------------------------------------------------------------------------- // Settings that must be set only after whole form is constructed @@ -694,12 +751,6 @@ static void __fastcall RemoveHiddenControlsFromOrder(TControl ** ControlsOrder, Count -= Shift; } //--------------------------------------------------------------------------- -void __fastcall RepaintStatusBar(TCustomStatusBar * StatusBar) -{ - StatusBar->SimplePanel = !StatusBar->SimplePanel; - StatusBar->SimplePanel = !StatusBar->SimplePanel; -} -//--------------------------------------------------------------------------- void __fastcall SetVerticalControlsOrder(TControl ** ControlsOrder, int Count) { RemoveHiddenControlsFromOrder(ControlsOrder, Count); @@ -784,17 +835,6 @@ void __fastcall SetHorizontalControlsOrder(TControl ** ControlsOrder, int Count) } } //--------------------------------------------------------------------------- -TPoint __fastcall GetAveCharSize(TCanvas* Canvas) -{ - Integer I; - wchar_t Buffer[52]; - TSize Result; - for (I = 0; I <= 25; I++) Buffer[I] = (wchar_t)(L'A' + I); - for (I = 0; I <= 25; I++) Buffer[I+26] = (wchar_t)(L'a' + I); - GetTextExtentPoint32(Canvas->Handle, Buffer, 52, &Result); - return TPoint(Result.cx / 52, Result.cy); -} -//--------------------------------------------------------------------------- void __fastcall MakeNextInTabOrder(TWinControl * Control, TWinControl * After) { if (After->TabOrder > Control->TabOrder) @@ -1524,6 +1564,52 @@ bool __fastcall SupportsSplitButton() return (Win32MajorVersion >= 6); } //--------------------------------------------------------------------------- +static TButton * __fastcall FindDefaultButton(TWinControl * Control) +{ + TButton * Result = NULL; + int Index = 0; + while ((Result == NULL) && (Index < Control->ControlCount)) + { + TControl * ChildControl = Control->Controls[Index]; + TButton * Button = dynamic_cast(ChildControl); + if ((Button != NULL) && Button->Default) + { + Result = Button; + } + else + { + TWinControl * WinControl = dynamic_cast(ChildControl); + if (WinControl != NULL) + { + Result = FindDefaultButton(WinControl); + } + } + Index++; + } + return Result; +} +//--------------------------------------------------------------------------- +TModalResult __fastcall DefaultResult(TCustomForm * Form) +{ + // The point of this is to avoid hardcoding mrOk when checking dialog results. + // Previously we used != mrCancel instead, as mrCancel is more reliable, + // being automatically used for Esc/X buttons (and hence kind of forced to be used + // for Cancel buttons). But that failed to be reliable in the end, for + // ModalResult being mrNone, when Windows session is being logged off. + // We interpreted mrNone as OK, causing lots of troubles. + TModalResult Result = mrNone; + TButton * Button = FindDefaultButton(Form); + if (ALWAYS_TRUE(Button != NULL)) + { + Result = Button->ModalResult; + } + if (ALWAYS_FALSE(Result == mrNone)) + { + Result = mrOk; + } + return Result; +} +//--------------------------------------------------------------------------- void __fastcall SetFormIcon(TForm * Form, int Size, const UnicodeString & IconName) { HICON Icon = LoadIcon(HInstance, IconName.c_str()); @@ -1541,3 +1627,14 @@ void __fastcall SetFormIcons(TForm * Form, const UnicodeString & BigIconName, SetFormIcon(Form, ICON_SMALL, SmallIconName); SetFormIcon(Form, ICON_BIG, BigIconName); } +//--------------------------------------------------------------------------- +void __fastcall UseDesktopFont(TControl * Control) +{ + class TPublicControl : public TControl + { + public: + __property DesktopFont; + }; + + reinterpret_cast(Control)->DesktopFont = true; +} diff --git a/source/windows/VCLCommon.h b/source/windows/VCLCommon.h index 323606e86..8983b6cab 100644 --- a/source/windows/VCLCommon.h +++ b/source/windows/VCLCommon.h @@ -42,10 +42,8 @@ TAutoSwitch __fastcall ComboAutoSwitchSave(TComboBox * ComboBox); void __fastcall CheckBoxAutoSwitchLoad(TCheckBox * CheckBox, TAutoSwitch Value); TAutoSwitch __fastcall CheckBoxAutoSwitchSave(TCheckBox * CheckBox); void __fastcall InstallPathWordBreakProc(TWinControl * Control); -void __fastcall RepaintStatusBar(TCustomStatusBar * StatusBar); void __fastcall SetVerticalControlsOrder(TControl ** ControlsOrder, int Count); void __fastcall SetHorizontalControlsOrder(TControl ** ControlsOrder, int Count); -TPoint __fastcall GetAveCharSize(TCanvas * Canvas); void __fastcall MakeNextInTabOrder(TWinControl * Control, TWinControl * After); void __fastcall CutFormToDesktop(TForm * Form); void __fastcall UpdateFormPosition(TCustomForm * Form, TPosition Position); @@ -65,6 +63,8 @@ FormType * __fastcall SafeFormCreate(TComponent * Owner = NULL) return dynamic_cast(_SafeFormCreate(__classid(FormType), Owner)); } bool __fastcall SupportsSplitButton(); +TModalResult __fastcall DefaultResult(TCustomForm * Form); +void __fastcall UseDesktopFont(TControl * Control); //--------------------------------------------------------------------------- // When exception is left to be handled by Application->OnException // memory error occurs when clearing the exception for unknown reason. diff --git a/source/windows/WinConfiguration.cpp b/source/windows/WinConfiguration.cpp index d0ca99038..ff8f76049 100644 --- a/source/windows/WinConfiguration.cpp +++ b/source/windows/WinConfiguration.cpp @@ -17,6 +17,7 @@ #include #include #include +#include //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- @@ -408,17 +409,16 @@ __fastcall TWinConfiguration::~TWinConfiguration() delete FEditorList; } //--------------------------------------------------------------------------- -UnicodeString __fastcall TWinConfiguration::FormatDefaultWindowParams(int Width, int Height) -{ - return FORMAT(L"-1;-1;%d;%d;0", (Width, Height)); -} -//--------------------------------------------------------------------------- void __fastcall TWinConfiguration::Default() { FCustomCommandsDefaults = true; TCustomWinConfiguration::Default(); + int WorkAreaWidthScaled = DimensionToDefaultPixelsPerInch(Screen->WorkAreaWidth); + int WorkAreaHeightScaled = DimensionToDefaultPixelsPerInch(Screen->WorkAreaHeight); + UnicodeString PixelsPerInchToolbarValue = "PixelsPerInch=" + SaveDefaultPixelsPerInch(); + FDDAllowMove = false; FDDAllowMoveInit = false; FDDTransferConfirmation = asAuto; @@ -482,8 +482,8 @@ void __fastcall TWinConfiguration::Default() FOpenedStoredSessionFolders = L""; FAutoImportedFromPuttyOrFilezilla = false; - FEditor.FontName = L"Courier New"; - FEditor.FontHeight = -12; + FEditor.FontName = DefaultFixedWidthFontName; + FEditor.FontSize = DefaultFixedWidthFontSize; FEditor.FontStyle = 0; FEditor.FontCharset = DEFAULT_CHARSET; FEditor.WordWrap = false; @@ -501,8 +501,12 @@ void __fastcall TWinConfiguration::Default() FEditor.WarnOnEncodingFallback = true; FQueueView.Height = 115; + FQueueView.HeightPixelsPerInch = USER_DEFAULT_SCREEN_DPI; // with 1000 pixels wide screen, both interfaces are wide enough to fit wider queue - FQueueView.Layout = (Screen->Width > 1000) ? L"70,250,250,80,80,80,80" : L"70,160,160,80,80,80,80"; + FQueueView.Layout = + UnicodeString((WorkAreaWidthScaled > 1000) ? L"70,250,250,80,80,80,80" : L"70,160,160,80,80,80,80") + + // WORKAROUND (the comma), see GetListViewStr + L",;" + SaveDefaultPixelsPerInch(); FQueueView.Show = qvHideWhenEmpty; FQueueView.LastHideShow = qvHideWhenEmpty; FQueueView.ToolBar = false; @@ -524,25 +528,28 @@ void __fastcall TWinConfiguration::Default() FUpdates.ConsoleVersion = ""; FLogWindowOnStartup = true; - FLogWindowParams = L"-1;-1;500;400"; + FLogWindowParams = FormatDefaultWindowParams(500, 400); - int ExplorerWidth = (Screen->Width > 900) ? 860 : 600; - int ExplorerHeight = (Screen->Height > 750) ? 720 : 400; + int ExplorerWidth = Min(WorkAreaWidthScaled - 40, 860); + int ExplorerHeight = Min(WorkAreaHeightScaled - 30, 720); FScpExplorer.WindowParams = FormatDefaultWindowParams(ExplorerWidth, ExplorerHeight); - FScpExplorer.DirViewParams = L"0;1;0|150,1;70,1;120,1;79,1;62,1;55,1;20,0;150,0;125,0|6;7;8;0;1;2;3;4;5"; + // WORKAROUND (the semicolon, see TCustomListViewColProperties.GetParamsStr, and see other instances below) + FScpExplorer.DirViewParams = L"0;1;0|150,1;70,1;150,1;79,1;62,1;55,0;20,0;150,0;125,0;@" + SaveDefaultPixelsPerInch() + L"|6;7;8;0;1;2;3;4;5"; FScpExplorer.ToolbarsLayout = - L"Queue_Visible=1,Queue_LastDock=QueueDock,Queue_DockRow=0,Queue_DockPos=-1,Queue_FloatLeft=0,Queue_FloatTop=0,Queue_FloatRightX=0," - "Menu_Visible=1,Menu_DockedTo=TopDock,Menu_LastDock=TopDock,Menu_DockRow=0,Menu_DockPos=0,Menu_FloatLeft=0,Menu_FloatTop=0,Menu_FloatRightX=0," - "Buttons_Visible=1,Buttons_DockedTo=TopDock,Buttons_LastDock=TopDock,Buttons_DockRow=2,Buttons_DockPos=0,Buttons_FloatLeft=0,Buttons_FloatTop=0,Buttons_FloatRightX=0," - "Selection_Visible=0,Selection_DockedTo=TopDock,Selection_LastDock=TopDock,Selection_DockRow=3,Selection_DockPos=0,Selection_FloatLeft=227,Selection_FloatTop=445,Selection_FloatRightX=0," - "Session_Visible=0,Session_DockedTo=TopDock,Session_LastDock=TopDock,Session_DockRow=6,Session_DockPos=0,Session_FloatLeft=39,Session_FloatTop=160,Session_FloatRightX=0," - "Preferences_Visible=1,Preferences_DockedTo=TopDock,Preferences_LastDock=TopDock,Preferences_DockRow=4,Preferences_DockPos=0,Preferences_FloatLeft=0,Preferences_FloatTop=0,Preferences_FloatRightX=0," - "Sort_Visible=0,Sort_DockedTo=TopDock,Sort_LastDock=TopDock,Sort_DockRow=5,Sort_DockPos=0,Sort_FloatLeft=0,Sort_FloatTop=0,Sort_FloatRightX=0," - "Address_Visible=1,Address_DockedTo=TopDock,Address_LastDock=TopDock,Address_DockRow=1,Address_DockPos=0,Address_FloatLeft=0,Address_FloatTop=0,Address_FloatRightX=0," - "Updates_Visible=1,Updates_DockedTo=TopDock,Updates_LastDock=TopDock,Updates_DockRow=4,Updates_DockPos=416,Updates_FloatLeft=0,Updates_FloatTop=0,Updates_FloatRightX=0," - "Transfer_Visible=1,Transfer_DockedTo=TopDock,Transfer_LastDock=TopDock,Transfer_DockRow=4,Transfer_DockPos=194,Transfer_FloatLeft=0,Transfer_FloatTop=0,Transfer_FloatRightX=0," - "CustomCommands_Visible=0,CustomCommands_DockedTo=TopDock,CustomCommands_LastDock=TopDock,CustomCommands_DockRow=7,CustomCommands_DockPos=0,CustomCommands_FloatLeft=0,CustomCommands_FloatTop=0,CustomCommands_FloatRightX=0"; + UnicodeString( + L"Queue_Visible=1,Queue_LastDock=QueueDock,Queue_DockRow=0,Queue_DockPos=-1,Queue_FloatLeft=0,Queue_FloatTop=0,Queue_FloatRightX=0," + "Menu_Visible=1,Menu_DockedTo=TopDock,Menu_LastDock=TopDock,Menu_DockRow=0,Menu_DockPos=0,Menu_FloatLeft=0,Menu_FloatTop=0,Menu_FloatRightX=0," + "Buttons_Visible=1,Buttons_DockedTo=TopDock,Buttons_LastDock=TopDock,Buttons_DockRow=2,Buttons_DockPos=0,Buttons_FloatLeft=0,Buttons_FloatTop=0,Buttons_FloatRightX=0," + "Selection_Visible=0,Selection_DockedTo=TopDock,Selection_LastDock=TopDock,Selection_DockRow=3,Selection_DockPos=0,Selection_FloatLeft=227,Selection_FloatTop=445,Selection_FloatRightX=0," + "Session_Visible=0,Session_DockedTo=TopDock,Session_LastDock=TopDock,Session_DockRow=6,Session_DockPos=0,Session_FloatLeft=39,Session_FloatTop=160,Session_FloatRightX=0," + "Preferences_Visible=1,Preferences_DockedTo=TopDock,Preferences_LastDock=TopDock,Preferences_DockRow=4,Preferences_DockPos=0,Preferences_FloatLeft=0,Preferences_FloatTop=0,Preferences_FloatRightX=0," + "Sort_Visible=0,Sort_DockedTo=TopDock,Sort_LastDock=TopDock,Sort_DockRow=5,Sort_DockPos=0,Sort_FloatLeft=0,Sort_FloatTop=0,Sort_FloatRightX=0," + "Address_Visible=1,Address_DockedTo=TopDock,Address_LastDock=TopDock,Address_DockRow=1,Address_DockPos=0,Address_FloatLeft=0,Address_FloatTop=0,Address_FloatRightX=0," + "Updates_Visible=1,Updates_DockedTo=TopDock,Updates_LastDock=TopDock,Updates_DockRow=4,Updates_DockPos=416,Updates_FloatLeft=0,Updates_FloatTop=0,Updates_FloatRightX=0," + "Transfer_Visible=1,Transfer_DockedTo=TopDock,Transfer_LastDock=TopDock,Transfer_DockRow=4,Transfer_DockPos=194,Transfer_FloatLeft=0,Transfer_FloatTop=0,Transfer_FloatRightX=0," + "CustomCommands_Visible=0,CustomCommands_DockedTo=TopDock,CustomCommands_LastDock=TopDock,CustomCommands_DockRow=7,CustomCommands_DockPos=0,CustomCommands_FloatLeft=0,CustomCommands_FloatTop=0,CustomCommands_FloatRightX=0,") + + PixelsPerInchToolbarValue; FScpExplorer.SessionsTabs = true; FScpExplorer.StatusBar = true; UnicodeString PersonalFolder; @@ -552,9 +559,10 @@ void __fastcall TWinConfiguration::Default() FScpExplorer.ShowFullAddress = true; FScpExplorer.DriveView = true; FScpExplorer.DriveViewWidth = 180; + FScpExplorer.DriveViewWidthPixelsPerInch = USER_DEFAULT_SCREEN_DPI; - int CommanderWidth = (Screen->Width > 1100) ? 1050 : ((Screen->Width > 1000) ? 950 : 600); - int CommanderHeight = (Screen->Height > 750) ? 700 : 400; + int CommanderWidth = Min(WorkAreaWidthScaled - 40, 1090); + int CommanderHeight = Min(WorkAreaHeightScaled - 30, 700); FScpCommander.WindowParams = FormatDefaultWindowParams(CommanderWidth, CommanderHeight); FScpCommander.LocalPanelWidth = 0.5; @@ -565,43 +573,49 @@ void __fastcall TWinConfiguration::Default() FScpCommander.PreserveLocalDirectory = false; // Toolbar2_FloatRightX=1 makes keybar apper initially "in column" when undocked FScpCommander.ToolbarsLayout = - L"Queue_Visible=1,Queue_LastDock=QueueDock,Queue_DockRow=0,Queue_DockPos=-1,Queue_FloatLeft=0,Queue_FloatTop=0,Queue_FloatRightX=0," - "Menu_Visible=1,Menu_DockedTo=TopDock,Menu_LastDock=TopDock,Menu_DockRow=0,Menu_DockPos=0,Menu_FloatLeft=0,Menu_FloatTop=0,Menu_FloatRightX=0," - "Preferences_Visible=1,Preferences_DockedTo=TopDock,Preferences_LastDock=TopDock,Preferences_DockRow=1,Preferences_DockPos=228,Preferences_FloatLeft=0,Preferences_FloatTop=0,Preferences_FloatRightX=0," - "Session_Visible=0,Session_DockedTo=TopDock,Session_LastDock=TopDock,Session_DockRow=1,Session_DockPos=602,Session_FloatLeft=380,Session_FloatTop=197,Session_FloatRightX=0," - "Sort_Visible=0,Sort_DockedTo=TopDock,Sort_LastDock=TopDock,Sort_DockRow=2,Sort_DockPos=0,Sort_FloatLeft=0,Sort_FloatTop=0,Sort_FloatRightX=0," - "Commands_Visible=1,Commands_DockedTo=TopDock,Commands_LastDock=TopDock,Commands_DockRow=1,Commands_DockPos=0,Commands_FloatLeft=0,Commands_FloatTop=0,Commands_FloatRightX=0," - "Updates_Visible=1,Updates_DockedTo=TopDock,Updates_LastDock=TopDock,Updates_DockRow=1,Updates_DockPos=619,Updates_FloatLeft=0,Updates_FloatTop=0,Updates_FloatRightX=0," - "Transfer_Visible=1,Transfer_DockedTo=TopDock,Transfer_LastDock=TopDock,Transfer_DockRow=1,Transfer_DockPos=364,Transfer_FloatLeft=0,Transfer_FloatTop=0,Transfer_FloatRightX=0," - "CustomCommands_Visible=0,CustomCommands_DockedTo=TopDock,CustomCommands_LastDock=TopDock,CustomCommands_DockRow=3,CustomCommands_DockPos=0,CustomCommands_FloatLeft=0,CustomCommands_FloatTop=0,CustomCommands_FloatRightX=0," - "RemoteHistory_Visible=1,RemoteHistory_DockedTo=RemoteTopDock,RemoteHistory_LastDock=RemoteTopDock,RemoteHistory_DockRow=0,RemoteHistory_DockPos=172,RemoteHistory_FloatLeft=0,RemoteHistory_FloatTop=0,RemoteHistory_FloatRightX=0," - "RemoteNavigation_Visible=1,RemoteNavigation_DockedTo=RemoteTopDock,RemoteNavigation_LastDock=RemoteTopDock,RemoteNavigation_DockRow=0,RemoteNavigation_DockPos=252,RemoteNavigation_FloatLeft=0,RemoteNavigation_FloatTop=0,RemoteNavigation_FloatRightX=0," - "RemotePath_Visible=1,RemotePath_DockedTo=RemoteTopDock,RemotePath_LastDock=RemoteTopDock,RemotePath_DockRow=0,RemotePath_DockPos=0,RemotePath_FloatLeft=0,RemotePath_FloatTop=0,RemotePath_FloatRightX=0," - "RemoteFile_Visible=1,RemoteFile_DockedTo=RemoteTopDock,RemoteFile_LastDock=RemoteTopDock,RemoteFile_DockRow=1,RemoteFile_DockPos=0,RemoteFile_FloatLeft=0,RemoteFile_FloatTop=0,RemoteFile_FloatRightX=0," - "RemoteSelection_Visible=1,RemoteSelection_DockedTo=RemoteTopDock,RemoteSelection_LastDock=RemoteTopDock,RemoteSelection_DockRow=1,RemoteSelection_DockPos=345,RemoteSelection_FloatLeft=0,RemoteSelection_FloatTop=0,RemoteSelection_FloatRightX=0," - "LocalHistory_Visible=1,LocalHistory_DockedTo=LocalTopDock,LocalHistory_LastDock=LocalTopDock,LocalHistory_DockRow=0,LocalHistory_DockPos=207,LocalHistory_FloatLeft=0,LocalHistory_FloatTop=0,LocalHistory_FloatRightX=0," - "LocalNavigation_Visible=1,LocalNavigation_DockedTo=LocalTopDock,LocalNavigation_LastDock=LocalTopDock,LocalNavigation_DockRow=0,LocalNavigation_DockPos=287,LocalNavigation_FloatLeft=0,LocalNavigation_FloatTop=0,LocalNavigation_FloatRightX=0," - "LocalPath_Visible=1,LocalPath_DockedTo=LocalTopDock,LocalPath_LastDock=LocalTopDock,LocalPath_DockRow=0,LocalPath_DockPos=0,LocalPath_FloatLeft=0,LocalPath_FloatTop=0,LocalPath_FloatRightX=0," - "LocalFile_Visible=1,LocalFile_DockedTo=LocalTopDock,LocalFile_LastDock=LocalTopDock,LocalFile_DockRow=1,LocalFile_DockPos=0,LocalFile_FloatLeft=0,LocalFile_FloatTop=0,LocalFile_FloatRightX=0," - "LocalSelection_Visible=1,LocalSelection_DockedTo=LocalTopDock,LocalSelection_LastDock=LocalTopDock,LocalSelection_DockRow=1,LocalSelection_DockPos=329,LocalSelection_FloatLeft=0,LocalSelection_FloatTop=0,LocalSelection_FloatRightX=0," - "Toolbar2_Visible=0,Toolbar2_DockedTo=BottomDock,Toolbar2_LastDock=BottomDock,Toolbar2_DockRow=1,Toolbar2_DockPos=0,Toolbar2_FloatLeft=0,Toolbar2_FloatTop=0,Toolbar2_FloatRightX=1," - "CommandLine_Visible=0,CommandLine_DockedTo=BottomDock,CommandLine_LastDock=BottomDock,CommandLine_DockRow=0,CommandLine_DockPos=0,CommandLine_FloatLeft=0,CommandLine_FloatTop=0,CommandLine_FloatRightX=0"; + UnicodeString( + L"Queue_Visible=1,Queue_LastDock=QueueDock,Queue_DockRow=0,Queue_DockPos=-1,Queue_FloatLeft=0,Queue_FloatTop=0,Queue_FloatRightX=0," + "Menu_Visible=1,Menu_DockedTo=TopDock,Menu_LastDock=TopDock,Menu_DockRow=0,Menu_DockPos=0,Menu_FloatLeft=0,Menu_FloatTop=0,Menu_FloatRightX=0," + "Preferences_Visible=1,Preferences_DockedTo=TopDock,Preferences_LastDock=TopDock,Preferences_DockRow=1,Preferences_DockPos=228,Preferences_FloatLeft=0,Preferences_FloatTop=0,Preferences_FloatRightX=0," + "Session_Visible=0,Session_DockedTo=TopDock,Session_LastDock=TopDock,Session_DockRow=1,Session_DockPos=602,Session_FloatLeft=380,Session_FloatTop=197,Session_FloatRightX=0," + "Sort_Visible=0,Sort_DockedTo=TopDock,Sort_LastDock=TopDock,Sort_DockRow=2,Sort_DockPos=0,Sort_FloatLeft=0,Sort_FloatTop=0,Sort_FloatRightX=0," + "Commands_Visible=1,Commands_DockedTo=TopDock,Commands_LastDock=TopDock,Commands_DockRow=1,Commands_DockPos=0,Commands_FloatLeft=0,Commands_FloatTop=0,Commands_FloatRightX=0," + "Updates_Visible=1,Updates_DockedTo=TopDock,Updates_LastDock=TopDock,Updates_DockRow=1,Updates_DockPos=619,Updates_FloatLeft=0,Updates_FloatTop=0,Updates_FloatRightX=0," + "Transfer_Visible=1,Transfer_DockedTo=TopDock,Transfer_LastDock=TopDock,Transfer_DockRow=1,Transfer_DockPos=364,Transfer_FloatLeft=0,Transfer_FloatTop=0,Transfer_FloatRightX=0," + "CustomCommands_Visible=0,CustomCommands_DockedTo=TopDock,CustomCommands_LastDock=TopDock,CustomCommands_DockRow=3,CustomCommands_DockPos=0,CustomCommands_FloatLeft=0,CustomCommands_FloatTop=0,CustomCommands_FloatRightX=0," + "RemoteHistory_Visible=1,RemoteHistory_DockedTo=RemoteTopDock,RemoteHistory_LastDock=RemoteTopDock,RemoteHistory_DockRow=0,RemoteHistory_DockPos=172,RemoteHistory_FloatLeft=0,RemoteHistory_FloatTop=0,RemoteHistory_FloatRightX=0," + "RemoteNavigation_Visible=1,RemoteNavigation_DockedTo=RemoteTopDock,RemoteNavigation_LastDock=RemoteTopDock,RemoteNavigation_DockRow=0,RemoteNavigation_DockPos=252,RemoteNavigation_FloatLeft=0,RemoteNavigation_FloatTop=0,RemoteNavigation_FloatRightX=0," + "RemotePath_Visible=1,RemotePath_DockedTo=RemoteTopDock,RemotePath_LastDock=RemoteTopDock,RemotePath_DockRow=0,RemotePath_DockPos=0,RemotePath_FloatLeft=0,RemotePath_FloatTop=0,RemotePath_FloatRightX=0," + "RemoteFile_Visible=1,RemoteFile_DockedTo=RemoteTopDock,RemoteFile_LastDock=RemoteTopDock,RemoteFile_DockRow=1,RemoteFile_DockPos=0,RemoteFile_FloatLeft=0,RemoteFile_FloatTop=0,RemoteFile_FloatRightX=0," + "RemoteSelection_Visible=1,RemoteSelection_DockedTo=RemoteTopDock,RemoteSelection_LastDock=RemoteTopDock,RemoteSelection_DockRow=1,RemoteSelection_DockPos=345,RemoteSelection_FloatLeft=0,RemoteSelection_FloatTop=0,RemoteSelection_FloatRightX=0," + "LocalHistory_Visible=1,LocalHistory_DockedTo=LocalTopDock,LocalHistory_LastDock=LocalTopDock,LocalHistory_DockRow=0,LocalHistory_DockPos=207,LocalHistory_FloatLeft=0,LocalHistory_FloatTop=0,LocalHistory_FloatRightX=0," + "LocalNavigation_Visible=1,LocalNavigation_DockedTo=LocalTopDock,LocalNavigation_LastDock=LocalTopDock,LocalNavigation_DockRow=0,LocalNavigation_DockPos=287,LocalNavigation_FloatLeft=0,LocalNavigation_FloatTop=0,LocalNavigation_FloatRightX=0," + "LocalPath_Visible=1,LocalPath_DockedTo=LocalTopDock,LocalPath_LastDock=LocalTopDock,LocalPath_DockRow=0,LocalPath_DockPos=0,LocalPath_FloatLeft=0,LocalPath_FloatTop=0,LocalPath_FloatRightX=0," + "LocalFile_Visible=1,LocalFile_DockedTo=LocalTopDock,LocalFile_LastDock=LocalTopDock,LocalFile_DockRow=1,LocalFile_DockPos=0,LocalFile_FloatLeft=0,LocalFile_FloatTop=0,LocalFile_FloatRightX=0," + "LocalSelection_Visible=1,LocalSelection_DockedTo=LocalTopDock,LocalSelection_LastDock=LocalTopDock,LocalSelection_DockRow=1,LocalSelection_DockPos=329,LocalSelection_FloatLeft=0,LocalSelection_FloatTop=0,LocalSelection_FloatRightX=0," + "Toolbar2_Visible=0,Toolbar2_DockedTo=BottomDock,Toolbar2_LastDock=BottomDock,Toolbar2_DockRow=1,Toolbar2_DockPos=0,Toolbar2_FloatLeft=0,Toolbar2_FloatTop=0,Toolbar2_FloatRightX=1," + "CommandLine_Visible=0,CommandLine_DockedTo=BottomDock,CommandLine_LastDock=BottomDock,CommandLine_DockRow=0,CommandLine_DockPos=0,CommandLine_FloatLeft=0,CommandLine_FloatTop=0,CommandLine_FloatRightX=0,") + + PixelsPerInchToolbarValue; FScpCommander.CurrentPanel = osLocal; FScpCommander.CompareByTime = true; FScpCommander.CompareBySize = false; FScpCommander.TreeOnLeft = false; FScpCommander.ExplorerKeyboardShortcuts = false; FScpCommander.SystemContextMenu = false; - FScpCommander.RemotePanel.DirViewParams = L"0;1;0|150,1;70,1;120,1;79,1;62,1;55,0;20,0;150,0;125,0|6;7;8;0;1;2;3;4;5"; + FScpCommander.RemotePanel.DirViewParams = L"0;1;0|150,1;70,1;150,1;79,1;62,1;55,0;20,0;150,0;125,0;@" + SaveDefaultPixelsPerInch() + L"|6;7;8;0;1;2;3;4;5"; FScpCommander.RemotePanel.StatusBar = true; FScpCommander.RemotePanel.DriveView = false; FScpCommander.RemotePanel.DriveViewHeight = 100; + FScpCommander.RemotePanel.DriveViewHeightPixelsPerInch = USER_DEFAULT_SCREEN_DPI; FScpCommander.RemotePanel.DriveViewWidth = 100; - FScpCommander.LocalPanel.DirViewParams = L"0;1;0|150,1;70,1;101,1;120,1;55,0;55,0|5;0;1;2;3;4"; + FScpCommander.RemotePanel.DriveViewWidthPixelsPerInch = USER_DEFAULT_SCREEN_DPI; + FScpCommander.LocalPanel.DirViewParams = L"0;1;0|150,1;70,1;120,1;150,1;55,0;55,0;@" + SaveDefaultPixelsPerInch() + L"|5;0;1;2;3;4"; FScpCommander.LocalPanel.StatusBar = true; FScpCommander.LocalPanel.DriveView = false; FScpCommander.LocalPanel.DriveViewHeight = 100; + FScpCommander.LocalPanel.DriveViewHeightPixelsPerInch = USER_DEFAULT_SCREEN_DPI; FScpCommander.LocalPanel.DriveViewWidth = 100; + FScpCommander.LocalPanel.DriveViewWidthPixelsPerInch = USER_DEFAULT_SCREEN_DPI; FBookmarks->Clear(); } @@ -707,6 +721,9 @@ TStorage __fastcall TWinConfiguration::GetStorage() { if (DetectRegistryStorage(HKEY_CURRENT_USER) || DetectRegistryStorage(HKEY_LOCAL_MACHINE) || + // FStorage is now stIniFile, so this tests writting to an INI file. + // As we fall back to user profile folder, when application folder + // is not writtable, it is actually unlikely that the below test ever fails. !CanWriteToStorage()) { FStorage = stRegistry; @@ -831,8 +848,8 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool SessionList) KEY(Bool, AutoImportedFromPuttyOrFilezilla); \ ); \ BLOCK(L"Interface\\Editor", CANCREATE, \ - KEY(String, Editor.FontName); \ - KEY(Integer, Editor.FontHeight); \ + KEYEX(String, Editor.FontName, L"FontName2"); \ + KEY(Integer, Editor.FontSize); \ KEY(Integer, Editor.FontStyle); \ KEY(Integer, Editor.FontCharset); \ KEY(Bool, Editor.WordWrap); \ @@ -851,6 +868,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool SessionList) ); \ BLOCK(L"Interface\\QueueView", CANCREATE, \ KEY(Integer, QueueView.Height); \ + KEY(Integer, QueueView.HeightPixelsPerInch); \ KEY(String, QueueView.Layout); \ KEY(Integer, QueueView.Show); \ KEY(Integer, QueueView.LastHideShow); \ @@ -888,6 +906,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool SessionList) KEY(Bool, ScpExplorer.ShowFullAddress); \ KEY(Bool, ScpExplorer.DriveView); \ KEY(Integer, ScpExplorer.DriveViewWidth); \ + KEY(Integer, ScpExplorer.DriveViewWidthPixelsPerInch); \ ); \ BLOCK(L"Interface\\Commander", CANCREATE, \ KEY(String, ScpCommander.ToolbarsLayout); \ @@ -910,14 +929,18 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool SessionList) KEY(Bool, ScpCommander.LocalPanel.StatusBar); \ KEY(Bool, ScpCommander.LocalPanel.DriveView); \ KEY(Integer, ScpCommander.LocalPanel.DriveViewHeight); \ + KEY(Integer, ScpCommander.LocalPanel.DriveViewHeightPixelsPerInch); \ KEY(Integer, ScpCommander.LocalPanel.DriveViewWidth); \ + KEY(Integer, ScpCommander.LocalPanel.DriveViewWidthPixelsPerInch); \ ); \ BLOCK(L"Interface\\Commander\\RemotePanel", CANCREATE, \ KEY(String, ScpCommander.RemotePanel.DirViewParams); \ KEY(Bool, ScpCommander.RemotePanel.StatusBar); \ KEY(Bool, ScpCommander.RemotePanel.DriveView); \ KEY(Integer, ScpCommander.RemotePanel.DriveViewHeight); \ + KEY(Integer, ScpCommander.RemotePanel.DriveViewHeightPixelsPerInch); \ KEY(Integer, ScpCommander.RemotePanel.DriveViewWidth); \ + KEY(Integer, ScpCommander.RemotePanel.DriveViewWidthPixelsPerInch); \ ); \ BLOCK(L"Logging", CANCREATE, \ KEY(Bool, LogWindowOnStartup); \ diff --git a/source/windows/WinConfiguration.h b/source/windows/WinConfiguration.h index a504710ba..099ab0dd0 100644 --- a/source/windows/WinConfiguration.h +++ b/source/windows/WinConfiguration.h @@ -19,11 +19,12 @@ struct TScpExplorerConfiguration { bool ShowFullAddress; bool DriveView; int DriveViewWidth; + int DriveViewWidthPixelsPerInch; bool __fastcall operator !=(TScpExplorerConfiguration & rhc) { return C(WindowParams) C(DirViewParams) C(ToolbarsLayout) C(SessionsTabs) C(StatusBar) C(LastLocalTargetDirectory) C(ViewStyle) C(ShowFullAddress) - C(DriveView) C(DriveViewWidth) 0; }; + C(DriveView) C(DriveViewWidth) C(DriveViewWidthPixelsPerInch) 0; }; }; //--------------------------------------------------------------------------- struct TScpCommanderPanelConfiguration { @@ -31,10 +32,13 @@ struct TScpCommanderPanelConfiguration { bool StatusBar; bool DriveView; int DriveViewHeight; + int DriveViewHeightPixelsPerInch; int DriveViewWidth; + int DriveViewWidthPixelsPerInch; bool __fastcall operator !=(TScpCommanderPanelConfiguration & rhc) { return C(DirViewParams) C(StatusBar) - C(DriveView) C(DriveViewHeight) C(DriveViewWidth) 0; }; + C(DriveView) C(DriveViewHeight) C(DriveViewHeightPixelsPerInch) + C(DriveViewWidth) C(DriveViewWidthPixelsPerInch) 0; }; }; //--------------------------------------------------------------------------- struct TScpCommanderConfiguration { @@ -79,7 +83,7 @@ struct TScpCommanderConfiguration { //--------------------------------------------------------------------------- struct TEditorConfiguration { UnicodeString FontName; - int FontHeight; + int FontSize; int FontCharset; int FontStyle; bool WordWrap; @@ -96,7 +100,7 @@ struct TEditorConfiguration { int Encoding; bool WarnOnEncodingFallback; bool __fastcall operator !=(TEditorConfiguration & rhc) - { return C(FontName) C(FontHeight) + { return C(FontName) C(FontSize) C(FontCharset) C(FontStyle) C(WordWrap) C(FindText) C(ReplaceText) C(FindMatchCase) C(FindWholeWord) C(FindDown) C(TabSize) C(MaxEditors) C(EarlyClose) C(SDIShellEditor) C(WindowParams) @@ -106,13 +110,14 @@ struct TEditorConfiguration { enum TQueueViewShow { qvShow, qvHideWhenEmpty, qvHide }; struct TQueueViewConfiguration { int Height; + int HeightPixelsPerInch; UnicodeString Layout; TQueueViewShow Show; TQueueViewShow LastHideShow; bool ToolBar; bool Label; bool __fastcall operator !=(TQueueViewConfiguration & rhc) - { return C(Height) C(Layout) C(Show) C(LastHideShow) C(ToolBar) C(Label) 0; }; + { return C(Height) C(HeightPixelsPerInch) C(Layout) C(Show) C(LastHideShow) C(ToolBar) C(Label) 0; }; }; //--------------------------------------------------------------------------- struct TUpdatesData @@ -455,7 +460,6 @@ protected: bool __fastcall DetectRegistryStorage(HKEY RootKey); bool __fastcall CanWriteToStorage(); bool __fastcall DoIsBeta(const UnicodeString & ReleaseType); - UnicodeString __fastcall FormatDefaultWindowParams(int Width, int Height); void __fastcall AskForMasterPassword(); public: diff --git a/source/windows/WinInterface.cpp b/source/windows/WinInterface.cpp index b816c80d9..a287788dd 100644 --- a/source/windows/WinInterface.cpp +++ b/source/windows/WinInterface.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "WinInterface.h" #include "CustomWinConfiguration.h" @@ -73,9 +74,9 @@ inline void TMessageParams::Reset() TimerAnswers = 0; Timeout = 0; TimeoutAnswer = 0; - NewerAskAgainTitle = L""; - NewerAskAgainAnswer = 0; - NewerAskAgainCheckedInitially = false; + NeverAskAgainTitle = L""; + NeverAskAgainAnswer = 0; + NeverAskAgainCheckedInitially = false; AllowHelp = true; ImageName = L""; } @@ -141,6 +142,11 @@ static void __fastcall NeverAskAgainCheckClick(void * /*Data*/, TObject * Sender } } //--------------------------------------------------------------------------- +static TCheckBox * __fastcall FindNeverAskAgainCheck(TForm * Dialog) +{ + return NOT_NULL(dynamic_cast(Dialog->FindComponent(L"NeverAskAgainCheck"))); +} +//--------------------------------------------------------------------------- TForm * __fastcall CreateMessageDialogEx(const UnicodeString Msg, TStrings * MoreMessages, TQueryType Type, unsigned int Answers, UnicodeString HelpKeyword, const TMessageParams * Params, TButton *& TimeoutButton) @@ -154,8 +160,9 @@ TForm * __fastcall CreateMessageDialogEx(const UnicodeString Msg, default: assert(false); } - int TimeoutAnswer = (Params != NULL) ? Params->TimeoutAnswer : 0; + unsigned int TimeoutAnswer = (Params != NULL) ? Params->TimeoutAnswer : 0; + unsigned int ActualAnswers = Answers; if ((Params == NULL) || Params->AllowHelp) { Answers = Answers | qaHelp; @@ -180,48 +187,30 @@ TForm * __fastcall CreateMessageDialogEx(const UnicodeString Msg, const TQueryButtonAlias * Aliases = (Params != NULL) ? Params->Aliases : NULL; unsigned int AliasesCount = (Params != NULL) ? Params->AliasesCount : 0; + UnicodeString NeverAskAgainCaption; + bool HasNeverAskAgain = (Params != NULL) && FLAGSET(Params->Params, mpNeverAskAgainCheck); + if (HasNeverAskAgain) + { + NeverAskAgainCaption = + !Params->NeverAskAgainTitle.IsEmpty() ? + (UnicodeString)Params->NeverAskAgainTitle : + // qaOK | qaIgnore is used, when custom "non-answer" button is required + LoadStr(((ActualAnswers == qaOK) || (ActualAnswers == (qaOK | qaIgnore))) ? + NEVER_SHOW_AGAIN : NEVER_ASK_AGAIN); + } + TForm * Dialog = CreateMoreMessageDialog(Msg, MoreMessages, DlgType, Answers, - Aliases, AliasesCount, TimeoutAnswer, &TimeoutButton, ImageName); + Aliases, AliasesCount, TimeoutAnswer, &TimeoutButton, ImageName, NeverAskAgainCaption); try { - if ((Params != NULL) && (Params->Params & mpNeverAskAgainCheck)) + if (HasNeverAskAgain && ALWAYS_TRUE(Params != NULL)) { - static const int VertSpace = 20; - Dialog->ClientHeight = Dialog->ClientHeight + VertSpace; - - for (int Index = 0; Index < Dialog->ControlCount; Index++) + TCheckBox * NeverAskAgainCheck = FindNeverAskAgainCheck(Dialog); + NeverAskAgainCheck->Checked = Params->NeverAskAgainCheckedInitially; + if (Params->NeverAskAgainAnswer > 0) { - TControl * Control = Dialog->Controls[Index]; - if (Control->Anchors.Contains(akBottom)) - { - if (Control->Anchors.Contains(akTop)) - { - Control->Height = Control->Height - VertSpace; - } - else - { - Control->Top = Control->Top - VertSpace; - } - } - } - - TCheckBox * NeverAskAgainCheck = new TCheckBox(Dialog); - NeverAskAgainCheck->Name = L"NeverAskAgainCheck"; - NeverAskAgainCheck->Parent = Dialog; - NeverAskAgainCheck->BoundsRect = TRect(60, Dialog->ClientHeight - 27, - Dialog->ClientWidth - 10, Dialog->ClientHeight - 5); - NeverAskAgainCheck->Caption = - !Params->NewerAskAgainTitle.IsEmpty() ? - (UnicodeString)Params->NewerAskAgainTitle : - // qaOK | qaIgnore is used, when custom "non-answer" button is required - LoadStr(((Answers == qaOK) || (Answers == (qaOK | qaIgnore))) ? - NEVER_SHOW_AGAIN : NEVER_ASK_AGAIN); - NeverAskAgainCheck->Checked = Params->NewerAskAgainCheckedInitially; - NeverAskAgainCheck->Anchors = TAnchors() << akBottom << akLeft; - if (Params->NewerAskAgainAnswer > 0) - { - NeverAskAgainCheck->Tag = Params->NewerAskAgainAnswer; + NeverAskAgainCheck->Tag = Params->NeverAskAgainAnswer; } TNotifyEvent OnClick; ((TMethod*)&OnClick)->Code = NeverAskAgainCheckClick; @@ -249,22 +238,21 @@ unsigned int __fastcall ExecuteMessageDialog(TForm * Dialog, unsigned int Answer unsigned int Answer = Dialog->ShowModal(); // mrCancel is returned always when X button is pressed, despite // no Cancel button was on the dialog. Find valid "cancel" answer. - if (Answer == mrCancel) + // mrNone is retuned when Windows session is closing (log off) + if ((Answer == mrCancel) || (Answer == mrNone)) { Answer = CancelAnswer(Answers); } if ((Params != NULL) && (Params->Params & mpNeverAskAgainCheck)) { - TCheckBox * NeverAskAgainCheck = - dynamic_cast(Dialog->FindComponent(L"NeverAskAgainCheck")); - assert(NeverAskAgainCheck); + TCheckBox * NeverAskAgainCheck = FindNeverAskAgainCheck(Dialog); if (NeverAskAgainCheck->Checked) { bool PositiveAnswer = - (Params->NewerAskAgainAnswer > 0) ? - (Answer == Params->NewerAskAgainAnswer) : + (Params->NeverAskAgainAnswer > 0) ? + (Answer == Params->NeverAskAgainAnswer) : IsPositiveAnswer(Answer); if (PositiveAnswer) { @@ -627,7 +615,7 @@ const int cpiConfigure = -2; const int cpiCustom = -3; const int cpiSaveSettings = -4; //--------------------------------------------------------------------------- -void __fastcall CopyParamListPopup(TPoint P, TPopupMenu * Menu, +void __fastcall CopyParamListPopup(TRect Rect, TPopupMenu * Menu, const TCopyParamType & Param, UnicodeString Preset, TNotifyEvent OnClick, int Options, int CopyParamAttrs, bool SaveSettings) { @@ -712,7 +700,7 @@ void __fastcall CopyParamListPopup(TPoint P, TPopupMenu * Menu, Item->OnClick = OnClick; Menu->Items->Add(Item); - MenuPopup(Menu, P, NULL); + MenuPopup(Menu, Rect, NULL); } //--------------------------------------------------------------------------- bool __fastcall CopyParamListPopupClick(TObject * Sender, @@ -894,45 +882,9 @@ void __fastcall TWinInteractiveCustomCommand::Execute( } } //--------------------------------------------------------------------------- -static unsigned int __fastcall ShellDllVersion() +void __fastcall MenuPopup(TPopupMenu * Menu, TButton * Button) { - static unsigned int Result = 0; - - if (Result == 0) - { - Result = 4; - HINSTANCE ShellDll = LoadLibrary(L"shell32.dll"); - if (ShellDll != NULL) - { - try - { - DLLGETVERSIONPROC DllGetVersion = - (DLLGETVERSIONPROC)GetProcAddress(ShellDll, "DllGetVersion"); - if(DllGetVersion != NULL) - { - DLLVERSIONINFO VersionInfo; - ZeroMemory(&VersionInfo, sizeof(VersionInfo)); - VersionInfo.cbSize = sizeof(VersionInfo); - if (SUCCEEDED(DllGetVersion(&VersionInfo))) - { - Result = VersionInfo.dwMajorVersion; - } - } - } - __finally - { - FreeLibrary(ShellDll); - } - } - } - - return Result; -} -//--------------------------------------------------------------------------- -void __fastcall MenuPopup(TPopupMenu * Menu, TButtonControl * Button) -{ - TPoint Point = Button->ClientToScreen(TPoint(2, Button->Height)); - MenuPopup(Menu, Point, Button); + MenuPopup(Menu, CalculatePopupRect(Button), Button); } //--------------------------------------------------------------------------- void __fastcall MenuPopup(TObject * Sender, const TPoint & MousePos, bool & Handled) @@ -950,7 +902,8 @@ void __fastcall MenuPopup(TObject * Sender, const TPoint & MousePos, bool & Hand } TPopupMenu * PopupMenu = (reinterpret_cast(Control))->PopupMenu; assert(PopupMenu != NULL); - MenuPopup(PopupMenu, Point, Control); + TRect Rect(Point, Point); + MenuPopup(PopupMenu, Rect, Control); Handled = true; } //--------------------------------------------------------------------------- @@ -962,6 +915,23 @@ void __fastcall MenuButton(TButton * Button) Button->ImageAlignment = iaRight; } //--------------------------------------------------------------------------- +TRect __fastcall CalculatePopupRect(TButton * Button) +{ + TPoint UpPoint = Button->ClientToScreen(TPoint(0, 0)); + TPoint DownPoint = Button->ClientToScreen(TPoint(Button->Width, Button->Height)); + TRect Rect(UpPoint, DownPoint); + int Offset = UseThemes() ? -1 : 0; + Rect.Inflate(Offset, Offset); + return Rect; +} +//--------------------------------------------------------------------------- +TRect __fastcall CalculatePopupRect(TControl * Control, TPoint MousePos) +{ + MousePos = Control->ClientToScreen(MousePos); + TRect Rect(MousePos, MousePos); + return Rect; +} +//--------------------------------------------------------------------------- void __fastcall SetGlobalMinimizeHandler(TCustomForm * /*Form*/, TNotifyEvent OnMinimize) { if (GlobalOnMinimize == NULL) @@ -1116,7 +1086,8 @@ void __fastcall GetFormatSettingsFix() void __fastcall WinInitialize() { SetErrorMode(SEM_FAILCRITICALERRORS); - if (IsWin7()) + // HACK + if (::IsWin7()) { GetFormatSettingsFix(); } @@ -1146,18 +1117,16 @@ struct TNotifyIconData5 DWORD dwInfoFlags; }; //--------------------------------------------------------------------------- -#undef NOTIFYICONDATA_V1_SIZE -#define NOTIFYICONDATA_V1_SIZE FIELD_OFFSET(TNotifyIconData5, szTip[64]) -//--------------------------------------------------------------------------- __fastcall ::TTrayIcon::TTrayIcon(unsigned int Id) { FVisible = false; FOnClick = NULL; FOnBalloonClick = NULL; + FBalloonUserData = NULL; FTrayIcon = new TNotifyIconData5; memset(FTrayIcon, 0, sizeof(*FTrayIcon)); - FTrayIcon->cbSize = ((ShellDllVersion() >= 5) ? sizeof(*FTrayIcon) : NOTIFYICONDATA_V1_SIZE); + FTrayIcon->cbSize = sizeof(*FTrayIcon); FTrayIcon->uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; FTrayIcon->hIcon = Application->Icon->Handle; FTrayIcon->uID = Id; @@ -1177,95 +1146,80 @@ __fastcall ::TTrayIcon::~TTrayIcon() delete FTrayIcon; } //--------------------------------------------------------------------------- -bool __fastcall ::TTrayIcon::SupportsBalloons() -{ - return (ShellDllVersion() >= 5); -} -//--------------------------------------------------------------------------- void __fastcall ::TTrayIcon::PopupBalloon(UnicodeString Title, const UnicodeString & Str, TQueryType QueryType, unsigned int Timeout, - TNotifyEvent OnBalloonClick) + TNotifyEvent OnBalloonClick, TObject * BalloonUserData) { - if (SupportsBalloons()) + if (Timeout > 30000) { - if (Timeout > 30000) - { - // this is probably system limit, do not try more, especially for - // the timeout-driven hiding of the tray icon (for Win2k) - Timeout = 30000; - } - FTrayIcon->uFlags |= NIF_INFO; - Title = FORMAT(L"%s - %s", (Title, AppNameString())); - StrPLCopy(FTrayIcon->szInfoTitle, Title, LENOF(FTrayIcon->szInfoTitle) - 1); - StrPLCopy(FTrayIcon->szInfo, Str, LENOF(FTrayIcon->szInfo) - 1); - FTrayIcon->uTimeout = Timeout; - switch (QueryType) - { - case qtError: - FTrayIcon->dwInfoFlags = NIIF_ERROR; - break; - - case qtInformation: - case qtConfirmation: - FTrayIcon->dwInfoFlags = NIIF_INFO; - break; - - case qtWarning: - default: - FTrayIcon->dwInfoFlags = NIIF_WARNING; - break; - } - - KillTimer(FTrayIcon->hWnd, 1); - if (Visible) - { - Update(); - } - else - { - Notify(NIM_ADD); - - // can be 5 only anyway, no older version supports balloons - if (ShellDllVersion() <= 5) - { - // version 5 does not notify us when the balloon is hidden, so we must - // remove the icon ourselves after own timeout - SetTimer(FTrayIcon->hWnd, 1, Timeout, NULL); - } - } - - FOnBalloonClick = OnBalloonClick; - - // Clearing the flag ensures that subsequent updates does not hide the baloon - // unless CancelBalloon is called explicitly - FTrayIcon->uFlags = FTrayIcon->uFlags & ~NIF_INFO; + // this is probably system limit, do not try more, especially for + // the timeout-driven hiding of the tray icon (for Win2k) + Timeout = 30000; } + FTrayIcon->uFlags |= NIF_INFO; + Title = FORMAT(L"%s - %s", (Title, AppNameString())); + StrPLCopy(FTrayIcon->szInfoTitle, Title, LENOF(FTrayIcon->szInfoTitle) - 1); + StrPLCopy(FTrayIcon->szInfo, Str, LENOF(FTrayIcon->szInfo) - 1); + FTrayIcon->uTimeout = Timeout; + switch (QueryType) + { + case qtError: + FTrayIcon->dwInfoFlags = NIIF_ERROR; + break; + + case qtInformation: + case qtConfirmation: + FTrayIcon->dwInfoFlags = NIIF_INFO; + break; + + case qtWarning: + default: + FTrayIcon->dwInfoFlags = NIIF_WARNING; + break; + } + + KillTimer(FTrayIcon->hWnd, 1); + if (Visible) + { + Update(); + } + else + { + Notify(NIM_ADD); + } + + FOnBalloonClick = OnBalloonClick; + delete FBalloonUserData; + FBalloonUserData = BalloonUserData; + + // Clearing the flag ensures that subsequent updates does not hide the baloon + // unless CancelBalloon is called explicitly + FTrayIcon->uFlags = FTrayIcon->uFlags & ~NIF_INFO; } //--------------------------------------------------------------------------- void __fastcall ::TTrayIcon::BalloonCancelled() { FOnBalloonClick = NULL; + delete FBalloonUserData; + FBalloonUserData = NULL; } //--------------------------------------------------------------------------- void __fastcall ::TTrayIcon::CancelBalloon() { - if (SupportsBalloons()) + KillTimer(FTrayIcon->hWnd, 1); + if (Visible) { - KillTimer(FTrayIcon->hWnd, 1); - if (Visible) - { - FTrayIcon->uFlags |= NIF_INFO; - FTrayIcon->szInfo[0] = L'\0'; - Update(); - FTrayIcon->uFlags = FTrayIcon->uFlags & ~NIF_INFO; - } - else - { - Notify(NIM_DELETE); - } - - BalloonCancelled(); + FTrayIcon->uFlags |= NIF_INFO; + FTrayIcon->szInfo[0] = L'\0'; + Update(); + FTrayIcon->uFlags = FTrayIcon->uFlags & ~NIF_INFO; } + else + { + Notify(NIM_DELETE); + } + + BalloonCancelled(); } //--------------------------------------------------------------------------- bool __fastcall ::TTrayIcon::Notify(unsigned int Message) @@ -1339,7 +1293,11 @@ void __fastcall ::TTrayIcon::WndProc(TMessage & Message) { if (FOnBalloonClick != NULL) { - FOnBalloonClick(NULL); + // prevent the user data from being freed by possible call + // to CancelBalloon or PopupBalloon during call to OnBalloonClick + std::auto_ptr UserData(FBalloonUserData); + FBalloonUserData = NULL; + FOnBalloonClick(UserData.get()); } else if (OnClick != NULL) { @@ -1397,7 +1355,7 @@ void __fastcall ::TTrayIcon::SetHint(UnicodeString value) { if (Hint != value) { - unsigned int Max = ((ShellDllVersion() >= 5) ? LENOF(FTrayIcon->szTip) : 64); + unsigned int Max = LENOF(FTrayIcon->szTip); StrPLCopy(FTrayIcon->szTip, value, Max - 1); Update(); } diff --git a/source/windows/WinInterface.h b/source/windows/WinInterface.h index 0464294dc..3c9e2439a 100644 --- a/source/windows/WinInterface.h +++ b/source/windows/WinInterface.h @@ -37,9 +37,9 @@ struct TMessageParams unsigned int TimerAnswers; unsigned int Timeout; unsigned int TimeoutAnswer; - UnicodeString NewerAskAgainTitle; - unsigned int NewerAskAgainAnswer; - bool NewerAskAgainCheckedInitially; + UnicodeString NeverAskAgainTitle; + unsigned int NeverAskAgainAnswer; + bool NeverAskAgainCheckedInitially; bool AllowHelp; UnicodeString ImageName; @@ -65,7 +65,7 @@ void __fastcall SearchHelp(const UnicodeString & Message); void __fastcall MessageWithNoHelp(const UnicodeString & Message); UnicodeString __fastcall GetToolbarsLayoutStr(const TComponent * OwnerComponent); -void __fastcall LoadToolbarsLayoutStr(const TComponent * OwnerComponent, UnicodeString LayoutStr); +void __fastcall LoadToolbarsLayoutStr(TComponent * OwnerComponent, UnicodeString LayoutStr); namespace Tb2item { class TTBCustomItem; } void __fastcall AddMenuSeparator(Tb2item::TTBCustomItem * Menu); @@ -313,7 +313,7 @@ bool __fastcall DoFullSynchronizeDialog(TSynchronizeMode & Mode, int & Params, // forms\SynchronizeChecklist.cpp class TSynchronizeChecklist; typedef void __fastcall (__closure *TCustomCommandMenuEvent) - (TObject * Sender, const TPoint & MousePos, TStrings * LocalFileList, TStrings * RemoteFileList); + (TObject * Sender, TRect Rect, TStrings * LocalFileList, TStrings * RemoteFileList); bool __fastcall DoSynchronizeChecklistDialog(TSynchronizeChecklist * Checklist, TSynchronizeMode Mode, int Params, const UnicodeString LocalDirectory, const UnicodeString RemoteDirectory, @@ -347,7 +347,7 @@ 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); + const UnicodeString & ImageName, const UnicodeString & NeverAskAgainCaption); // windows\Console.cpp int __fastcall Console(bool Help); @@ -370,17 +370,19 @@ const int cplNone = 0x00; const int cplCustomize = 0x01; const int cplCustomizeDefault = 0x02; const int cplSaveSettings = 0x04; -void __fastcall CopyParamListPopup(TPoint P, TPopupMenu * Menu, +void __fastcall CopyParamListPopup(TRect R, TPopupMenu * Menu, const TCopyParamType & Param, UnicodeString Preset, TNotifyEvent OnClick, int Options, int CopyParamAttrs, bool SaveSettings = false); bool __fastcall CopyParamListPopupClick(TObject * Sender, TCopyParamType & Param, UnicodeString & Preset, int CopyParamAttrs, bool * SaveSettings = NULL); -void __fastcall MenuPopup(TPopupMenu * Menu, TPoint Point, TComponent * PopupComponent); -void __fastcall MenuPopup(TPopupMenu * Menu, TButtonControl * Button); +void __fastcall MenuPopup(TPopupMenu * Menu, TRect Rect, TComponent * PopupComponent); +void __fastcall MenuPopup(TPopupMenu * Menu, TButton * Button); void __fastcall MenuPopup(TObject * Sender, const TPoint & MousePos, bool & Handled); void __fastcall MenuButton(TButton * Button); +TRect __fastcall CalculatePopupRect(TButton * Button); +TRect __fastcall CalculatePopupRect(TControl * Control, TPoint MousePos); void __fastcall UpgradeSpeedButton(TSpeedButton * Button); @@ -425,10 +427,9 @@ public: __fastcall TTrayIcon(unsigned int Id); __fastcall ~TTrayIcon(); - static bool __fastcall SupportsBalloons(); - void __fastcall PopupBalloon(UnicodeString Title, const UnicodeString & Str, - TQueryType QueryType, unsigned int Timeout, TNotifyEvent OnBalloonClick); + TQueryType QueryType, unsigned int Timeout, TNotifyEvent OnBalloonClick, + TObject * BalloonUserData); void __fastcall CancelBalloon(); __property bool Visible = { read = FVisible, write = SetVisible }; @@ -444,6 +445,7 @@ private: TNotifyIconData5 * FTrayIcon; TNotifyEvent FOnClick; TNotifyEvent FOnBalloonClick; + TObject * FBalloonUserData; UINT FTaskbarCreatedMsg; void __fastcall WndProc(TMessage & Message); diff --git a/source/windows/WinMain.cpp b/source/windows/WinMain.cpp index fc85d4f86..5b911ce9c 100644 --- a/source/windows/WinMain.cpp +++ b/source/windows/WinMain.cpp @@ -272,10 +272,17 @@ void __fastcall UpdateStaticUsage() UnicodeString WindowsVersion = FORMAT("%d.%d.%d %s", (Win32MajorVersion, Win32MinorVersion, Win32BuildNumber, Win32CSDVersion)); Configuration->Usage->Set(L"WindowsVersion", (WindowsVersion)); Configuration->Usage->Set(L"WindowsProductName", (WindowsProductName())); + DWORD Type; + GetWindowsProductType(Type); + Configuration->Usage->Set(L"WindowsProductType", (static_cast(Type))); Configuration->Usage->Set(L"DefaultLocale", IntToHex(static_cast(GetDefaultLCID()), 4)); Configuration->Usage->Set(L"Locale", IntToHex(static_cast(WinConfiguration->Locale), 4)); + Configuration->Usage->Set(L"PixelsPerInch", Screen->PixelsPerInch); + Configuration->Usage->Set(L"WorkAreaWidth", Screen->WorkAreaWidth); + Configuration->Usage->Set(L"WorkAreaHeight", Screen->WorkAreaHeight); + Configuration->Usage->Set(L"MonitorCount", Screen->MonitorCount); UnicodeString ProgramsFolder; ::SpecialFolderLocation(CSIDL_PROGRAM_FILES, ProgramsFolder); diff --git a/source/windows/WinSCP.exe.manifest b/source/windows/WinSCP.exe.manifest index 6ed96e584..933700d43 100644 --- a/source/windows/WinSCP.exe.manifest +++ b/source/windows/WinSCP.exe.manifest @@ -1,5 +1,5 @@ - + + + + + + + + + true + + \ No newline at end of file diff --git a/source/windows/Windows.rc b/source/windows/Windows.rc index 009e1832e..81e057c99 100644 --- a/source/windows/Windows.rc +++ b/source/windows/Windows.rc @@ -14,8 +14,6 @@ Z_ICON_LOG_BIG ICON "..\\resource\\Log32.ico" Z_ICON_EDITOR_SMALL ICON "..\\resource\\Editor16.ico" Z_ICON_EDITOR_BIG ICON "..\\resource\\Editor32.ico" -1 24 "WinSCP.exe.manifest" - LICENSE RCDATA "License.txt" DELETE_FILE RCDATA "..\\resource\\DeleteFile.png"