mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Merge branch 'release/v1.76' into develop
# Conflicts: # Tools/zip_portable_files.ps1 # mRemoteV1/Config/Putty/PuttySessionsRegistryProvider.cs
This commit is contained in:
@@ -1,7 +1,31 @@
|
||||
1.76.5 (2018-xx-xx):
|
||||
1.76.7 (2018-xx-xx):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1076: Wrong object selected when duplicating connection then switching between properties and inheritance in config window
|
||||
#1068: Fixed some toolbar positioning bugs
|
||||
|
||||
|
||||
1.76.6 (2018-08-03):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1062: Entering correct password when starting app does not load connections file
|
||||
|
||||
1.76.5 (2018-08-02):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1057: Hitting F2 with no connection node selected caused unhandled exception
|
||||
#1052: 'Switch to notification panel' feature does not always switch
|
||||
#1051: Tooltips always displayed regardless of 'Show description tooltips in connection tree' setting
|
||||
#1050: Config window retains access to previously selected node after loading new connections file
|
||||
#1045: Config window shows several incorrect properties for HTTPS connections
|
||||
#1040: Canceling "select panel" form does not cancel
|
||||
#1039: Set default theme when themes disabled
|
||||
#1038: Unable to add connection with active filter
|
||||
#1036: Exception when themes are active and options page closed on Connections then reopened
|
||||
#1034: Connection context menu not being translated
|
||||
#1030: Exception thrown if importing from port scan and no tree node is selected
|
||||
#1020: BackupFileKeepCount setting not limiting backup file count
|
||||
#1004: Duplicating root or PuTTy node through hotkey causes unhandled exception
|
||||
@@ -12,6 +36,9 @@ Fixes:
|
||||
#991: Error when deleting host in filtered view
|
||||
#971: Portable Settings now apply to any machine they are used on
|
||||
#961: Connections file overwritten if correct decryption password not provided
|
||||
#893: Removed unneeded files from build/package
|
||||
#868: if statement returned the same value
|
||||
#762: Increased button size to fit locaized text
|
||||
|
||||
|
||||
1.76.4 Alpha 6 (2018-06-03):
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
node('windows') {
|
||||
def jobDir = pwd()
|
||||
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\""
|
||||
def vsToolsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools"
|
||||
def vsExtensionsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow"
|
||||
def nunitTestAdapterPath = "C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\VisualStudio\\14.0\\Extensions"
|
||||
def msBuild = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\msbuild.exe"
|
||||
def nunitConsolePath = "${jobDir}\\packages\\NUnit.ConsoleRunner.3.7.0\\tools\\nunit3-console.exe"
|
||||
def openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe"
|
||||
def testResultFilePrefix = "TestResult"
|
||||
def testResultFileNormal = "${testResultFilePrefix}_UnitTests_normal.xml"
|
||||
def testResultFilePortable = "${testResultFilePrefix}_UnitTests_portable.xml"
|
||||
def coverageReport = "code_coverage_report.xml"
|
||||
|
||||
|
||||
stage ('Clean output dir') {
|
||||
@@ -32,24 +36,24 @@ node('windows') {
|
||||
withCredentials([file(credentialsId: '9b674d57-6792-48e3-984a-4d1bab2abb64', variable: 'CODE_SIGNING_CERT')]) {
|
||||
withCredentials([usernamePassword(credentialsId: '05b7449b-05c0-490f-8661-236242526e62', passwordVariable: 'MRNG_CERT_PASSWORD', usernameVariable: 'NO_USERNAME')]) {
|
||||
stage ('Build mRemoteNG (Normal - MSI)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /t:Clean,Build /p:Configuration=\"Release Installer\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
|
||||
bat "\"${msBuild}\" /nologo /t:Clean,Build /p:Configuration=\"Release Installer\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
|
||||
archiveArtifacts artifacts: "Release\\*.msi", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
|
||||
}
|
||||
|
||||
stage ('Build mRemoteNG (Portable)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /t:Clean,Build /p:Configuration=\"Release Portable\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
|
||||
bat "\"${msBuild}\" /nologo /t:Clean,Build /p:Configuration=\"Release Portable\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
|
||||
archiveArtifacts artifacts: "Release\\*.zip", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Run Unit Tests (Normal - MSI)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release\\mRemoteNGTests.dll\""
|
||||
}
|
||||
|
||||
stage ('Run Unit Tests (Portable)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release Portable\\mRemoteNGTests.dll\""
|
||||
}
|
||||
stage ('Run Unit Tests (Normal - MSI)') {
|
||||
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release\\mRemoteNGTests.dll\" --result=${testResultFileNormal} --x86"
|
||||
}
|
||||
|
||||
stage ('Run Unit Tests (Portable)') {
|
||||
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release portable\\mRemoteNGTests.dll\" --result=${testResultFilePortable} --x86"
|
||||
}
|
||||
|
||||
stage ('Generate UpdateCheck Files') {
|
||||
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\create_upg_chk_files.ps1\" -TagName \"${env.TagName}\" -UpdateChannel \"${env.UpdateChannel}\""
|
||||
|
||||
@@ -175,9 +175,14 @@ function Upload-GitHubReleaseAsset {
|
||||
)
|
||||
|
||||
$UploadUri = $UploadUri -replace "(\{[\w,\?]*\})$"
|
||||
$file = Get-Item -Path $FilePath
|
||||
$files = Get-Item -Path $FilePath
|
||||
|
||||
$req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
|
||||
# Get-Item could produce an array of files if a wildcard is provided. (C:\*.txt)
|
||||
# Upload each matching item individually
|
||||
foreach ($file in $files) {
|
||||
Write-Output "Uploading asset to GitHub release: '$($file.FullName)'"
|
||||
$req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,4 +46,5 @@ Format-Table -AutoSize -Wrap -InputObject @{
|
||||
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning
|
||||
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath
|
||||
& "$PSScriptRoot\zip_symbols.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
@@ -15,7 +15,6 @@ if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Removing unnecessary files from Release versions"
|
||||
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force
|
||||
$filesToDelete = Get-ChildItem -Path $TargetDir -Recurse -Include @(
|
||||
"*.pdb",
|
||||
"*.publish",
|
||||
"*.xml",
|
||||
"*.backup",
|
||||
|
||||
@@ -39,19 +39,22 @@ if ($ConfigurationName -eq "Release Portable") {
|
||||
|
||||
$PortableZip="$($SolutionDir)Release\mRemoteNG-Portable-$($version).zip"
|
||||
|
||||
Remove-Item -Recurse "$($SolutionDir)mRemoteV1\bin\package" -ErrorAction SilentlyContinue | Out-Null
|
||||
New-Item "$($SolutionDir)mRemoteV1\bin\package" -ItemType "directory" | Out-Null
|
||||
$tempFolderPath = Join-Path -Path $SolutionDir -ChildPath "mRemoteV1\bin\package"
|
||||
Remove-Item -Recurse $tempFolderPath -ErrorAction SilentlyContinue | Out-Null
|
||||
New-Item $tempFolderPath -ItemType "directory" | Out-Null
|
||||
|
||||
Copy-Item "$($SolutionDir)mRemoteV1\Resources\PuTTYNG.exe" -Destination "$($SolutionDir)mRemoteV1\bin\package"
|
||||
Copy-Item "$($SolutionDir)mRemoteV1\Resources\PuTTYNG.exe" -Destination $tempFolderPath
|
||||
|
||||
#Write-Output "$($SolutionDir)mRemoteV1\bin\$ConfigurationName"
|
||||
#Write-Output "$($SolutionDir)mRemoteV1\bin\package"
|
||||
Copy-Item "$($SolutionDir)mRemoteV1\bin\$ConfigurationName\*" -Destination "$($SolutionDir)mRemoteV1\bin\package" -Recurse -Force
|
||||
Copy-Item "$($SolutionDir)*.txt" -Destination "$($SolutionDir)mRemoteV1\bin\package"
|
||||
Copy-Item "$($SolutionDir)mRemoteV1\bin\$ConfigurationName\*" -Destination $tempFolderPath -Recurse -Force
|
||||
# Delete any PDB files that accidentally get copied into the temp folder
|
||||
Get-ChildItem -Path $tempFolderPath -Filter "*.pdb" | Remove-Item
|
||||
Copy-Item "$($SolutionDir)*.txt" -Destination $tempFolderPath
|
||||
|
||||
Write-Output "Creating portable ZIP file $($PortableZip)"
|
||||
Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue
|
||||
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip "$($SolutionDir)mRemoteV1\bin\package\*.*"
|
||||
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip (Join-Path -Path $tempFolderPath -ChildPath "*.*")
|
||||
#& $SEVENZIP a -bt -mx=9 -tzip -y $PortableZip "$($SolutionDir)*.TXT"
|
||||
}
|
||||
else {
|
||||
|
||||
56
Tools/zip_symbols.ps1
Normal file
56
Tools/zip_symbols.ps1
Normal file
@@ -0,0 +1,56 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
if(-not [string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {
|
||||
Write-Output "Too early to run via Appveyor - artifacts don't get generated properly. Exiting"
|
||||
Exit
|
||||
}
|
||||
|
||||
Write-Output "Solution Dir: '$($SolutionDir)'"
|
||||
Write-Output "Target Dir: '$($TargetDir)'"
|
||||
$ConfigurationName = $ConfigurationName.Trim()
|
||||
Write-Output "Config Name (trimmed): '$($ConfigurationName)'"
|
||||
|
||||
|
||||
# Windows Sysinternals Sigcheck from http://technet.microsoft.com/en-us/sysinternals/bb897441
|
||||
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
|
||||
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
|
||||
|
||||
# Package Zip
|
||||
if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Packaging debug symbols"
|
||||
|
||||
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe"
|
||||
|
||||
Write-Output "Version is $($version)"
|
||||
|
||||
if ($ConfigurationName -match "Portable") {
|
||||
$zipFilePrefix = "mRemoteNG-Portable-symbols"
|
||||
} else {
|
||||
$zipFilePrefix = "mRemoteNG-symbols"
|
||||
}
|
||||
|
||||
$outputZipPath="$($SolutionDir)Release\$zipFilePrefix-$($version).zip"
|
||||
|
||||
Write-Output "Creating debug symbols ZIP file $($outputZipPath)"
|
||||
Remove-Item -Force $outputZipPath -ErrorAction SilentlyContinue
|
||||
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath (Join-Path -Path $TargetDir -ChildPath "*.pdb")
|
||||
}
|
||||
else {
|
||||
Write-Output "We will not package debug symbols - this isnt a release build."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
@@ -43,6 +43,20 @@ namespace mRemoteNGTests.Connection
|
||||
Assert.That(clonedConnection.Parent, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CloneAlsoCopiesInheritanceObject()
|
||||
{
|
||||
var clonedConnection = _connectionInfo.Clone();
|
||||
Assert.That(clonedConnection.Inheritance, Is.Not.EqualTo(_connectionInfo.Inheritance));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CloneCorrectlySetsParentOfInheritanceObject()
|
||||
{
|
||||
var clonedConnection = _connectionInfo.Clone();
|
||||
Assert.That(clonedConnection.Inheritance.Parent, Is.EqualTo(clonedConnection));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFromCopiesProperties()
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ using mRemoteNG.Connection.Protocol.VNC;
|
||||
|
||||
namespace mRemoteNGTests.TestHelpers
|
||||
{
|
||||
internal class ConnectionInfoHelpers
|
||||
internal static class ConnectionInfoHelpers
|
||||
{
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
@@ -128,5 +128,5 @@ namespace mRemoteNGTests.TestHelpers
|
||||
var values = Enum.GetValues(typeof(T));
|
||||
return (T)values.GetValue(_random.Next(values.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,5 +184,19 @@ namespace mRemoteNGTests.UI.Controls
|
||||
|
||||
Assert.That(widthAfter, Is.GreaterThan(widthBefore));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Apartment(ApartmentState.STA)]
|
||||
public void RenamingNodeWithNothingSelectedDoesNothing()
|
||||
{
|
||||
var connectionTreeModel = new ConnectionTreeModel();
|
||||
var root = new RootNodeInfo(RootNodeType.Connection);
|
||||
connectionTreeModel.AddRootNode(root);
|
||||
|
||||
_connectionTree.ConnectionTreeModel = connectionTreeModel;
|
||||
_connectionTree.SelectedObject = null;
|
||||
|
||||
Assert.DoesNotThrow(() => _connectionTree.RenameSelectedNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Window;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public class ConfigWindowGeneralTests
|
||||
{
|
||||
private ConfigWindow _configWindow;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_configWindow = new ConfigWindow
|
||||
{
|
||||
PropertiesVisible = true
|
||||
};
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(ConnectionInfoGeneralTestCases))]
|
||||
public void PropertyGridShowCorrectPropertiesForConnectionInfo(ConnectionInfo connectionInfo, IEnumerable<string> expectedVisibleProperties)
|
||||
{
|
||||
_configWindow.SelectedTreeNode = connectionInfo;
|
||||
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PropertyGridShowCorrectPropertiesForRootConnectionInfo()
|
||||
{
|
||||
var expectedVisibleProperties = new[]
|
||||
{
|
||||
nameof(RootNodeInfo.Name),
|
||||
nameof(RootNodeInfo.Password),
|
||||
};
|
||||
|
||||
_configWindow.SelectedTreeNode = new RootNodeInfo(RootNodeType.Connection);
|
||||
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PropertyGridShowCorrectPropertiesForRootPuttyInfo()
|
||||
{
|
||||
var expectedVisibleProperties = new[]
|
||||
{
|
||||
nameof(RootNodeInfo.Name),
|
||||
};
|
||||
|
||||
_configWindow.SelectedTreeNode = new RootPuttySessionsNodeInfo();
|
||||
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
|
||||
}
|
||||
|
||||
private static IEnumerable<TestCaseData> ConnectionInfoGeneralTestCases()
|
||||
{
|
||||
var protocolTypes = typeof(ProtocolType).GetEnumValues().OfType<ProtocolType>();
|
||||
var testCases = new List<TestCaseData>();
|
||||
|
||||
foreach (var protocol in protocolTypes)
|
||||
{
|
||||
var expectedPropertyListConnection = BuildExpectedConnectionInfoPropertyList(protocol, false);
|
||||
var connectionInfo = ConstructConnectionInfo(protocol, false);
|
||||
var testCaseConnection = new TestCaseData(connectionInfo, expectedPropertyListConnection)
|
||||
.SetName(protocol + ", ConnectionInfo");
|
||||
testCases.Add(testCaseConnection);
|
||||
|
||||
var expectedPropertyListContainer = BuildExpectedConnectionInfoPropertyList(protocol, true);
|
||||
var containerInfo = ConstructConnectionInfo(protocol, true);
|
||||
var testCaseContainer = new TestCaseData(containerInfo, expectedPropertyListContainer)
|
||||
.SetName(protocol + ", ContainerInfo");
|
||||
testCases.Add(testCaseContainer);
|
||||
}
|
||||
|
||||
return testCases;
|
||||
}
|
||||
|
||||
internal static ConnectionInfo ConstructConnectionInfo(ProtocolType protocol, bool isContainer)
|
||||
{
|
||||
// build connection info. set certain connection properties so
|
||||
// that toggled properties are hidden in the property grid. We
|
||||
// will test those separately in the special protocol tests.
|
||||
var node = isContainer
|
||||
? new ContainerInfo()
|
||||
: new ConnectionInfo();
|
||||
|
||||
node.Protocol = protocol;
|
||||
node.Resolution = RdpProtocol.RDPResolutions.Res800x600;
|
||||
node.RDGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Never;
|
||||
node.RDGatewayUseConnectionCredentials = RdpProtocol.RDGatewayUseConnectionCredentials.Yes;
|
||||
node.RedirectSound = RdpProtocol.RDPSounds.DoNotPlay;
|
||||
node.VNCAuthMode = ProtocolVNC.AuthMode.AuthVNC;
|
||||
node.VNCProxyType = ProtocolVNC.ProxyType.ProxyNone;
|
||||
node.Inheritance.TurnOffInheritanceCompletely();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
internal static List<string> BuildExpectedConnectionInfoPropertyList(ProtocolType protocol, bool isContainer)
|
||||
{
|
||||
var expectedProperties = new List<string>
|
||||
{
|
||||
nameof(ConnectionInfo.Name),
|
||||
nameof(ConnectionInfo.Description),
|
||||
nameof(ConnectionInfo.Icon),
|
||||
nameof(ConnectionInfo.Panel),
|
||||
nameof(ConnectionInfo.Protocol),
|
||||
nameof(ConnectionInfo.PreExtApp),
|
||||
nameof(ConnectionInfo.PostExtApp),
|
||||
nameof(ConnectionInfo.MacAddress),
|
||||
nameof(ConnectionInfo.UserField),
|
||||
};
|
||||
|
||||
if (!isContainer)
|
||||
{
|
||||
expectedProperties.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Hostname),
|
||||
});
|
||||
}
|
||||
|
||||
switch (protocol)
|
||||
{
|
||||
case ProtocolType.RDP:
|
||||
expectedProperties.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Username),
|
||||
nameof(ConnectionInfo.Password),
|
||||
nameof(ConnectionInfo.Domain),
|
||||
nameof(ConnectionInfo.Port),
|
||||
nameof(ConnectionInfo.UseConsoleSession),
|
||||
nameof(ConnectionInfo.RDPAuthenticationLevel),
|
||||
nameof(ConnectionInfo.RDPMinutesToIdleTimeout),
|
||||
nameof(ConnectionInfo.LoadBalanceInfo),
|
||||
nameof(ConnectionInfo.UseCredSsp),
|
||||
nameof(ConnectionInfo.RDGatewayUsageMethod),
|
||||
nameof(ConnectionInfo.Resolution),
|
||||
nameof(ConnectionInfo.Colors),
|
||||
nameof(ConnectionInfo.CacheBitmaps),
|
||||
nameof(ConnectionInfo.DisplayWallpaper),
|
||||
nameof(ConnectionInfo.DisplayThemes),
|
||||
nameof(ConnectionInfo.EnableFontSmoothing),
|
||||
nameof(ConnectionInfo.EnableDesktopComposition),
|
||||
nameof(ConnectionInfo.RedirectKeys),
|
||||
nameof(ConnectionInfo.RedirectDiskDrives),
|
||||
nameof(ConnectionInfo.RedirectPrinters),
|
||||
nameof(ConnectionInfo.RedirectPorts),
|
||||
nameof(ConnectionInfo.RedirectSmartCards),
|
||||
nameof(ConnectionInfo.RedirectSound),
|
||||
});
|
||||
break;
|
||||
case ProtocolType.VNC:
|
||||
expectedProperties.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Password),
|
||||
nameof(ConnectionInfo.Port),
|
||||
nameof(ConnectionInfo.VNCSmartSizeMode),
|
||||
nameof(ConnectionInfo.VNCViewOnly),
|
||||
});
|
||||
break;
|
||||
case ProtocolType.SSH1:
|
||||
case ProtocolType.SSH2:
|
||||
expectedProperties.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Username),
|
||||
nameof(ConnectionInfo.Password),
|
||||
nameof(ConnectionInfo.Port),
|
||||
nameof(ConnectionInfo.PuttySession)
|
||||
});
|
||||
break;
|
||||
case ProtocolType.Telnet:
|
||||
case ProtocolType.Rlogin:
|
||||
case ProtocolType.RAW:
|
||||
expectedProperties.AddRange(new[]
|
||||
{
|
||||
nameof(ConnectionInfo.Port),
|
||||
nameof(ConnectionInfo.PuttySession),
|
||||
});
|
||||
break;
|
||||
case ProtocolType.HTTP:
|
||||
case ProtocolType.HTTPS:
|
||||
expectedProperties.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Username),
|
||||
nameof(ConnectionInfo.Password),
|
||||
nameof(ConnectionInfo.Port),
|
||||
nameof(ConnectionInfo.RenderingEngine),
|
||||
});
|
||||
break;
|
||||
case ProtocolType.ICA:
|
||||
expectedProperties.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Username),
|
||||
nameof(ConnectionInfo.Password),
|
||||
nameof(ConnectionInfo.Domain),
|
||||
nameof(ConnectionInfo.ICAEncryptionStrength),
|
||||
nameof(ConnectionInfo.Resolution),
|
||||
nameof(ConnectionInfo.Colors),
|
||||
nameof(ConnectionInfo.CacheBitmaps),
|
||||
});
|
||||
break;
|
||||
case ProtocolType.IntApp:
|
||||
expectedProperties.AddRange(new[]
|
||||
{
|
||||
nameof(ConnectionInfo.Username),
|
||||
nameof(ConnectionInfo.Password),
|
||||
nameof(ConnectionInfo.Domain),
|
||||
nameof(ConnectionInfo.Port),
|
||||
nameof(ConnectionInfo.ExtApp),
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(protocol), protocol, null);
|
||||
}
|
||||
|
||||
return expectedProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public class ConfigWindowRdpSpecialTests : ConfigWindowSpecialTestsBase
|
||||
{
|
||||
protected override ProtocolType Protocol => ProtocolType.RDP;
|
||||
|
||||
[Test]
|
||||
public void PropertyShownWhenActive_RdpMinutesToIdleTimeout()
|
||||
{
|
||||
ConnectionInfo.RDPMinutesToIdleTimeout = 1;
|
||||
ExpectedPropertyList.Add(nameof(mRemoteNG.Connection.ConnectionInfo.RDPAlertIdleTimeout));
|
||||
|
||||
RunVerification();
|
||||
}
|
||||
|
||||
[TestCase(RdpProtocol.RDGatewayUsageMethod.Always)]
|
||||
[TestCase(RdpProtocol.RDGatewayUsageMethod.Detect)]
|
||||
public void RdGatewayPropertiesShown_WhenRdGatewayUsageMethodIsNotNever(RdpProtocol.RDGatewayUsageMethod gatewayUsageMethod)
|
||||
{
|
||||
ConnectionInfo.RDGatewayUsageMethod = gatewayUsageMethod;
|
||||
ConnectionInfo.RDGatewayUseConnectionCredentials = RdpProtocol.RDGatewayUseConnectionCredentials.Yes;
|
||||
ExpectedPropertyList.AddRange(new []
|
||||
{
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayHostname),
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayUseConnectionCredentials)
|
||||
});
|
||||
|
||||
RunVerification();
|
||||
}
|
||||
|
||||
[TestCase(RdpProtocol.RDGatewayUseConnectionCredentials.No)]
|
||||
[TestCase(RdpProtocol.RDGatewayUseConnectionCredentials.SmartCard)]
|
||||
public void RdGatewayPropertiesShown_WhenRDGatewayUseConnectionCredentialsIsNotYes(RdpProtocol.RDGatewayUseConnectionCredentials useConnectionCredentials)
|
||||
{
|
||||
ConnectionInfo.RDGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Always;
|
||||
ConnectionInfo.RDGatewayUseConnectionCredentials = useConnectionCredentials;
|
||||
ExpectedPropertyList.AddRange(new []
|
||||
{
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayHostname),
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayUsername),
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayPassword),
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayDomain),
|
||||
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayUseConnectionCredentials)
|
||||
});
|
||||
|
||||
RunVerification();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SoundQualityPropertyShown_WhenRdpSoundsSetToBringToThisComputer()
|
||||
{
|
||||
ConnectionInfo.RedirectSound = RdpProtocol.RDPSounds.BringToThisComputer;
|
||||
ExpectedPropertyList.Add(nameof(mRemoteNG.Connection.ConnectionInfo.SoundQuality));
|
||||
|
||||
RunVerification();
|
||||
}
|
||||
|
||||
[TestCase(RdpProtocol.RDPResolutions.FitToWindow)]
|
||||
[TestCase(RdpProtocol.RDPResolutions.Fullscreen)]
|
||||
public void AutomaticResizePropertyShown_WhenResolutionIsDynamic(RdpProtocol.RDPResolutions resolution)
|
||||
{
|
||||
ConnectionInfo.Resolution = resolution;
|
||||
ExpectedPropertyList.Add(nameof(mRemoteNG.Connection.ConnectionInfo.AutomaticResize));
|
||||
|
||||
RunVerification();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.UI.Window;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public abstract class ConfigWindowSpecialTestsBase
|
||||
{
|
||||
protected abstract ProtocolType Protocol { get; }
|
||||
protected bool TestAgainstContainerInfo { get; set; } = false;
|
||||
protected ConfigWindow ConfigWindow;
|
||||
protected ConnectionInfo ConnectionInfo;
|
||||
protected List<string> ExpectedPropertyList;
|
||||
|
||||
[SetUp]
|
||||
public virtual void Setup()
|
||||
{
|
||||
ConnectionInfo = ConfigWindowGeneralTests.ConstructConnectionInfo(Protocol, TestAgainstContainerInfo);
|
||||
ExpectedPropertyList = ConfigWindowGeneralTests.BuildExpectedConnectionInfoPropertyList(Protocol, TestAgainstContainerInfo);
|
||||
|
||||
ConfigWindow = new ConfigWindow
|
||||
{
|
||||
PropertiesVisible = true,
|
||||
};
|
||||
}
|
||||
|
||||
public void RunVerification()
|
||||
{
|
||||
ConfigWindow.SelectedTreeNode = ConnectionInfo;
|
||||
Assert.That(
|
||||
ConfigWindow.VisibleObjectProperties,
|
||||
Is.EquivalentTo(ExpectedPropertyList));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public class ConfigWindowVncSpecialTests : ConfigWindowSpecialTestsBase
|
||||
{
|
||||
protected override ProtocolType Protocol => ProtocolType.VNC;
|
||||
|
||||
[Test]
|
||||
public void UserDomainPropertiesShown_WhenAuthModeIsWindows()
|
||||
{
|
||||
ConnectionInfo.VNCAuthMode = ProtocolVNC.AuthMode.AuthWin;
|
||||
ExpectedPropertyList.AddRange(new []
|
||||
{
|
||||
nameof(ConnectionInfo.Username),
|
||||
nameof(ConnectionInfo.Domain),
|
||||
});
|
||||
}
|
||||
|
||||
[TestCase(ProtocolVNC.ProxyType.ProxyHTTP)]
|
||||
[TestCase(ProtocolVNC.ProxyType.ProxySocks5)]
|
||||
[TestCase(ProtocolVNC.ProxyType.ProxyUltra)]
|
||||
public void ProxyPropertiesShown_WhenProxyModeIsNotNone(ProtocolVNC.ProxyType proxyType)
|
||||
{
|
||||
ConnectionInfo.VNCProxyType = proxyType;
|
||||
ExpectedPropertyList.AddRange(new[]
|
||||
{
|
||||
nameof(ConnectionInfo.VNCProxyIP),
|
||||
nameof(ConnectionInfo.VNCProxyPort),
|
||||
nameof(ConnectionInfo.VNCProxyUsername),
|
||||
nameof(ConnectionInfo.VNCProxyPassword),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,6 +233,10 @@
|
||||
<Compile Include="UI\Forms\OptionsFormSetupAndTeardown.cs" />
|
||||
<Compile Include="UI\Forms\PasswordFormTests.cs" />
|
||||
<Compile Include="UI\WindowListTests.cs" />
|
||||
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowGeneralTests.cs" />
|
||||
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowRdpSpecialTests.cs" />
|
||||
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowSpecialTestsBase.cs" />
|
||||
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowVncSpecialTests.cs" />
|
||||
<Compile Include="UI\Window\ConnectionTreeWindowTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.UI.Window;
|
||||
using System;
|
||||
using System;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.UI;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.UI.Window;
|
||||
|
||||
namespace mRemoteNG.App
|
||||
{
|
||||
@@ -15,8 +15,14 @@ namespace mRemoteNG.App
|
||||
private static PortScanWindow _portscanForm;
|
||||
private static UltraVNCWindow _ultravncscForm;
|
||||
private static ComponentsCheckWindow _componentscheckForm;
|
||||
private static ConnectionTreeWindow _treeForm;
|
||||
|
||||
internal static ConnectionTreeWindow TreeForm
|
||||
{
|
||||
get => _treeForm ?? (_treeForm = new ConnectionTreeWindow());
|
||||
set => _treeForm = value;
|
||||
}
|
||||
|
||||
internal static ConnectionTreeWindow TreeForm { get; set; } = new ConnectionTreeWindow();
|
||||
internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
|
||||
internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
|
||||
internal static ScreenshotManagerWindow ScreenshotForm { get; set; } = new ScreenshotManagerWindow();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using mRemoteNG.Tools;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree.Root;
|
||||
// ReSharper disable ArrangeAccessorOwnerBody
|
||||
|
||||
namespace mRemoteNG.Config.Putty
|
||||
{
|
||||
public class PuttySessionsManager
|
||||
public class PuttySessionsManager
|
||||
{
|
||||
public static PuttySessionsManager Instance { get; } = new PuttySessionsManager();
|
||||
|
||||
@@ -35,10 +35,12 @@ namespace mRemoteNG.Config.Putty
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSessionsFromProvider(AbstractPuttySessionsProvider provider)
|
||||
private void AddSessionsFromProvider(AbstractPuttySessionsProvider puttySessionProvider)
|
||||
{
|
||||
var rootTreeNode = provider.RootInfo;
|
||||
provider.GetSessions();
|
||||
puttySessionProvider.ThrowIfNull(nameof(puttySessionProvider));
|
||||
|
||||
var rootTreeNode = puttySessionProvider.RootInfo;
|
||||
puttySessionProvider.GetSessions();
|
||||
|
||||
if (!RootPuttySessionsNodes.Contains(rootTreeNode) && rootTreeNode.HasChildren())
|
||||
RootPuttySessionsNodes.Add(rootTreeNode);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
using Microsoft.Win32;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Microsoft.Win32;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Messages;
|
||||
|
||||
|
||||
namespace mRemoteNG.Config.Putty
|
||||
{
|
||||
public class PuttySessionsRegistryProvider : AbstractPuttySessionsProvider
|
||||
public class PuttySessionsRegistryProvider : AbstractPuttySessionsProvider
|
||||
{
|
||||
private const string PuttySessionsKey = "Software\\SimonTatham\\PuTTY\\Sessions";
|
||||
private static ManagementEventWatcher _eventWatcher;
|
||||
@@ -39,7 +39,10 @@ namespace mRemoteNG.Config.Putty
|
||||
}
|
||||
|
||||
public override PuttySessionInfo GetSession(string sessionName)
|
||||
{
|
||||
{
|
||||
if (string.IsNullOrEmpty(sessionName))
|
||||
return null;
|
||||
|
||||
var sessionsKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey);
|
||||
var sessionKey = sessionsKey?.OpenSubKey(sessionName);
|
||||
if (sessionKey == null) return null;
|
||||
@@ -50,10 +53,15 @@ namespace mRemoteNG.Config.Putty
|
||||
{
|
||||
PuttySession = sessionName,
|
||||
Name = sessionName,
|
||||
Hostname = sessionKey.GetValue("HostName").ToString(),
|
||||
Username = sessionKey.GetValue("UserName").ToString()
|
||||
Hostname = sessionKey.GetValue("HostName")?.ToString() ?? "",
|
||||
Username = sessionKey.GetValue("UserName")?.ToString() ?? ""
|
||||
};
|
||||
var protocol = string.IsNullOrEmpty(sessionKey.GetValue("Protocol").ToString()) ? sessionKey.GetValue("Protocol").ToString() : "ssh";
|
||||
|
||||
|
||||
var protocol = string.IsNullOrEmpty(sessionKey.GetValue("Protocol")?.ToString())
|
||||
? "ssh"
|
||||
: sessionKey.GetValue("Protocol").ToString();
|
||||
|
||||
switch (protocol.ToLowerInvariant())
|
||||
{
|
||||
case "raw":
|
||||
@@ -65,7 +73,7 @@ namespace mRemoteNG.Config.Putty
|
||||
case "serial":
|
||||
return null;
|
||||
case "ssh":
|
||||
int.TryParse(sessionKey.GetValue("SshProt").ToString(), out var sshVersion);
|
||||
int.TryParse(sessionKey.GetValue("SshProt")?.ToString(), out var sshVersion);
|
||||
/* Per PUTTY.H in PuTTYNG & PuTTYNG Upstream (PuTTY proper currently)
|
||||
* expect 0 for SSH1, 3 for SSH2 ONLY
|
||||
* 1 for SSH1 with a 2 fallback
|
||||
@@ -81,7 +89,12 @@ namespace mRemoteNG.Config.Putty
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
sessionInfo.Port = Convert.ToInt32(sessionKey.GetValue("PortNumber"));
|
||||
|
||||
int.TryParse(sessionKey.GetValue("PortNumber")?.ToString(), out var portNumber);
|
||||
if (portNumber == default(int))
|
||||
sessionInfo.SetDefaultPort();
|
||||
else
|
||||
sessionInfo.Port = portNumber;
|
||||
|
||||
return sessionInfo;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace mRemoteNG.Config.Putty
|
||||
foreach (var sessionName in Directory.GetFiles(sessionsFolderPath))
|
||||
{
|
||||
var sessionFileName = Path.GetFileName(sessionName);
|
||||
// ReSharper disable once ConstantConditionalAccessQualifier
|
||||
sessionNames.Add(raw ? sessionFileName : System.Web.HttpUtility.UrlDecode(sessionFileName?.Replace("+", "%2B")));
|
||||
}
|
||||
|
||||
@@ -174,7 +175,8 @@ namespace mRemoteNG.Config.Putty
|
||||
private static string GetPuttyConfPath()
|
||||
{
|
||||
var puttyPath = mRemoteNG.Settings.Default.UseCustomPuttyPath ? mRemoteNG.Settings.Default.CustomPuttyPath : App.Info.GeneralAppInfo.PuttyPath;
|
||||
return Path.Combine(Path.GetDirectoryName(puttyPath), "putty.conf");
|
||||
puttyPath = Path.GetDirectoryName(puttyPath);
|
||||
return string.IsNullOrEmpty(puttyPath) ? null : Path.Combine(puttyPath, "putty.conf");
|
||||
}
|
||||
|
||||
private static string GetSessionsFolderPath()
|
||||
@@ -201,6 +203,9 @@ namespace mRemoteNG.Config.Putty
|
||||
|
||||
private static PuttySessionInfo ModifyRegistrySessionInfo(PuttySessionInfo sessionInfo)
|
||||
{
|
||||
if (sessionInfo == null)
|
||||
return null;
|
||||
|
||||
sessionInfo.Name = string.Format(RegistrySessionNameFormat, sessionInfo.Name);
|
||||
sessionInfo.PuttySession = string.Format(RegistrySessionNameFormat, sessionInfo.PuttySession);
|
||||
return sessionInfo;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace mRemoteNG.Config.Settings
|
||||
{
|
||||
private readonly ExternalAppsLoader _externalAppsLoader;
|
||||
private readonly MessageCollector _messageCollector;
|
||||
private readonly MenuStrip _mainMenu;
|
||||
private readonly QuickConnectToolStrip _quickConnectToolStrip;
|
||||
private readonly ExternalToolsToolStrip _externalToolsToolStrip;
|
||||
private readonly MultiSshToolStrip _multiSshToolStrip;
|
||||
@@ -31,7 +32,8 @@ namespace mRemoteNG.Config.Settings
|
||||
MessageCollector messageCollector,
|
||||
QuickConnectToolStrip quickConnectToolStrip,
|
||||
ExternalToolsToolStrip externalToolsToolStrip,
|
||||
MultiSshToolStrip multiSshToolStrip)
|
||||
MultiSshToolStrip multiSshToolStrip,
|
||||
MenuStrip mainMenu)
|
||||
{
|
||||
if (mainForm == null)
|
||||
throw new ArgumentNullException(nameof(mainForm));
|
||||
@@ -43,13 +45,16 @@ namespace mRemoteNG.Config.Settings
|
||||
throw new ArgumentNullException(nameof(externalToolsToolStrip));
|
||||
if (multiSshToolStrip == null)
|
||||
throw new ArgumentNullException(nameof(multiSshToolStrip));
|
||||
if (mainMenu == null)
|
||||
throw new ArgumentNullException(nameof(mainMenu));
|
||||
|
||||
MainForm = mainForm;
|
||||
_messageCollector = messageCollector;
|
||||
_quickConnectToolStrip = quickConnectToolStrip;
|
||||
_externalToolsToolStrip = externalToolsToolStrip;
|
||||
_multiSshToolStrip = multiSshToolStrip;
|
||||
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
|
||||
_mainMenu = mainMenu;
|
||||
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
@@ -197,6 +202,7 @@ namespace mRemoteNG.Config.Settings
|
||||
private void LoadToolbarsFromSettings()
|
||||
{
|
||||
ResetAllToolbarLocations();
|
||||
AddMainMenuPanel();
|
||||
AddExternalAppsPanel();
|
||||
AddQuickConnectPanel();
|
||||
AddMultiSshPanel();
|
||||
@@ -210,31 +216,49 @@ namespace mRemoteNG.Config.Settings
|
||||
private void ResetAllToolbarLocations()
|
||||
{
|
||||
var tempToolStrip = new ToolStripPanel();
|
||||
tempToolStrip.Join(_mainMenu);
|
||||
tempToolStrip.Join(_quickConnectToolStrip);
|
||||
tempToolStrip.Join(_externalToolsToolStrip);
|
||||
tempToolStrip.Join(_multiSshToolStrip);
|
||||
}
|
||||
|
||||
private void AddMainMenuPanel()
|
||||
{
|
||||
SetToolstripGripStyle(_mainMenu);
|
||||
var toolStripPanel = ToolStripPanelFromString("top");
|
||||
toolStripPanel.Join(_mainMenu, new Point(3, 0));
|
||||
}
|
||||
|
||||
private void AddQuickConnectPanel()
|
||||
{
|
||||
SetToolstripGripStyle(_quickConnectToolStrip);
|
||||
_quickConnectToolStrip.Visible = mRemoteNG.Settings.Default.QuickyTBVisible;
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.QuickyTBParentDock);
|
||||
toolStripPanel.Join(_quickConnectToolStrip, mRemoteNG.Settings.Default.QuickyTBLocation);
|
||||
_quickConnectToolStrip.Visible = mRemoteNG.Settings.Default.QuickyTBVisible;
|
||||
}
|
||||
|
||||
private void AddExternalAppsPanel()
|
||||
{
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
|
||||
toolStripPanel.Join(_externalToolsToolStrip, mRemoteNG.Settings.Default.ExtAppsTBLocation);
|
||||
SetToolstripGripStyle(_externalToolsToolStrip);
|
||||
_externalToolsToolStrip.Visible = mRemoteNG.Settings.Default.ExtAppsTBVisible;
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
|
||||
toolStripPanel.Join(_externalToolsToolStrip, mRemoteNG.Settings.Default.ExtAppsTBLocation);
|
||||
}
|
||||
|
||||
private void AddMultiSshPanel()
|
||||
{
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
|
||||
toolStripPanel.Join(_multiSshToolStrip, mRemoteNG.Settings.Default.MultiSshToolbarLocation);
|
||||
SetToolstripGripStyle(_multiSshToolStrip);
|
||||
_multiSshToolStrip.Visible = mRemoteNG.Settings.Default.MultiSshToolbarVisible;
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.MultiSshToolbarParentDock);
|
||||
toolStripPanel.Join(_multiSshToolStrip, mRemoteNG.Settings.Default.MultiSshToolbarLocation);
|
||||
}
|
||||
|
||||
private void SetToolstripGripStyle(ToolStrip toolbar)
|
||||
{
|
||||
toolbar.GripStyle = mRemoteNG.Settings.Default.LockToolbars
|
||||
? ToolStripGripStyle.Hidden
|
||||
: ToolStripGripStyle.Visible;
|
||||
}
|
||||
|
||||
private ToolStripPanel ToolStripPanelFromString(string panel)
|
||||
{
|
||||
|
||||
@@ -78,7 +78,8 @@ namespace mRemoteNG.Connection
|
||||
var newConnectionInfo = new ConnectionInfo();
|
||||
newConnectionInfo.CopyFrom(this);
|
||||
newConnectionInfo.Inheritance = Inheritance.Clone();
|
||||
return newConnectionInfo;
|
||||
newConnectionInfo.Inheritance.Parent = newConnectionInfo;
|
||||
return newConnectionInfo;
|
||||
}
|
||||
|
||||
public void CopyFrom(ConnectionInfo sourceConnectionInfo)
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace mRemoteNG.Connection
|
||||
var newProtocol = protocolFactory.CreateProtocol(connectionInfo);
|
||||
|
||||
var connectionPanel = SetConnectionPanel(connectionInfo, force);
|
||||
if (string.IsNullOrEmpty(connectionPanel)) return;
|
||||
var connectionForm = SetConnectionForm(conForm, connectionPanel);
|
||||
var connectionContainer = SetConnectionContainer(connectionInfo, connectionForm);
|
||||
SetConnectionFormEventHandlers(newProtocol, connectionForm);
|
||||
@@ -163,6 +164,10 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
connectionPanel = frmPnl.Panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -32,11 +32,6 @@ namespace mRemoteNG.Connection
|
||||
public DateTime LastSqlUpdate { get; set; }
|
||||
|
||||
public ConnectionTreeModel ConnectionTreeModel { get; private set; }
|
||||
//public ConnectionTreeModel ConnectionTreeModel
|
||||
//{
|
||||
// get { return Windows.TreeForm.ConnectionTree.ConnectionTreeModel; }
|
||||
// set { Windows.TreeForm.ConnectionTree.ConnectionTreeModel = value; }
|
||||
//}
|
||||
|
||||
public ConnectionsService(PuttySessionsManager puttySessionsManager)
|
||||
{
|
||||
@@ -50,6 +45,7 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
try
|
||||
{
|
||||
filename.ThrowIfNullOrEmpty(nameof(filename));
|
||||
var newConnectionsModel = new ConnectionTreeModel();
|
||||
newConnectionsModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection));
|
||||
SaveConnections(newConnectionsModel, false, new SaveFilter(), filename, true);
|
||||
@@ -83,6 +79,10 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
newConnectionInfo.Port = uri.Port;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newConnectionInfo.Panel))
|
||||
newConnectionInfo.Panel = Language.strGeneral;
|
||||
|
||||
newConnectionInfo.IsQuickConnect = true;
|
||||
|
||||
return newConnectionInfo;
|
||||
@@ -131,11 +131,22 @@ namespace mRemoteNG.Connection
|
||||
RaiseConnectionsLoadedEvent(oldConnectionTreeModel, newConnectionTreeModel, oldIsUsingDatabaseValue, useDatabase, connectionFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When turned on, calls to <see cref="SaveConnections()"/> or
|
||||
/// <see cref="SaveConnectionsAsync"/> will not immediately execute.
|
||||
/// Instead, they will be deferred until <see cref="EndBatchingSaves"/>
|
||||
/// is called.
|
||||
/// </summary>
|
||||
public void BeginBatchingSaves()
|
||||
{
|
||||
_batchingSaves = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immediately executes a single <see cref="SaveConnections()"/> or
|
||||
/// <see cref="SaveConnectionsAsync"/> if one has been requested
|
||||
/// since calling <see cref="BeginBatchingSaves"/>.
|
||||
/// </summary>
|
||||
public void EndBatchingSaves()
|
||||
{
|
||||
_batchingSaves = false;
|
||||
@@ -222,9 +233,10 @@ namespace mRemoteNG.Connection
|
||||
|
||||
private void SaveConnectionsBGd()
|
||||
{
|
||||
Monitor.Enter(SaveLock);
|
||||
SaveConnections();
|
||||
Monitor.Exit(SaveLock);
|
||||
lock (SaveLock)
|
||||
{
|
||||
SaveConnections();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStartupConnectionFileName()
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace mRemoteNG.Connection
|
||||
connectionInfo.Hostname = url;
|
||||
connectionInfo.Protocol = url.StartsWith("https:") ? ProtocolType.HTTPS : ProtocolType.HTTP;
|
||||
connectionInfo.SetDefaultPort();
|
||||
if (string.IsNullOrEmpty(connectionInfo.Panel))
|
||||
connectionInfo.Panel = Language.strGeneral;
|
||||
connectionInfo.IsQuickConnect = true;
|
||||
var connectionInitiator = new ConnectionInitiator();
|
||||
connectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Messages.MessageWriters;
|
||||
using mRemoteNG.UI.Forms;
|
||||
@@ -12,29 +13,21 @@ namespace mRemoteNG.Messages.WriterDecorators
|
||||
private readonly IMessageTypeFilteringOptions _filter;
|
||||
private readonly IMessageWriter _decoratedWriter;
|
||||
private readonly ErrorAndInfoWindow _messageWindow;
|
||||
private Timer _ecTimer;
|
||||
private readonly FrmMain _frmMain = FrmMain.Default;
|
||||
|
||||
public MessageFocusDecorator(ErrorAndInfoWindow messageWindow, IMessageTypeFilteringOptions filter, IMessageWriter decoratedWriter)
|
||||
{
|
||||
if (filter == null)
|
||||
throw new ArgumentNullException(nameof(filter));
|
||||
if (messageWindow == null)
|
||||
throw new ArgumentNullException(nameof(messageWindow));
|
||||
if (decoratedWriter == null)
|
||||
throw new ArgumentNullException(nameof(decoratedWriter));
|
||||
|
||||
_filter = filter;
|
||||
_messageWindow = messageWindow;
|
||||
_decoratedWriter = decoratedWriter;
|
||||
CreateTimer();
|
||||
_filter = filter ?? throw new ArgumentNullException(nameof(filter));
|
||||
_messageWindow = messageWindow ?? throw new ArgumentNullException(nameof(messageWindow));
|
||||
_decoratedWriter = decoratedWriter ?? throw new ArgumentNullException(nameof(decoratedWriter));
|
||||
}
|
||||
|
||||
public void Write(IMessage message)
|
||||
public async void Write(IMessage message)
|
||||
{
|
||||
if (WeShouldFocusNotificationPanel(message))
|
||||
BeginSwitchToPanel();
|
||||
_decoratedWriter.Write(message);
|
||||
|
||||
if (WeShouldFocusNotificationPanel(message))
|
||||
await SwitchToMessageAsync();
|
||||
}
|
||||
|
||||
private bool WeShouldFocusNotificationPanel(IMessage message)
|
||||
@@ -43,7 +36,8 @@ namespace mRemoteNG.Messages.WriterDecorators
|
||||
switch (message.Class)
|
||||
{
|
||||
case MessageClass.InformationMsg:
|
||||
if (_filter.AllowInfoMessages) return true;
|
||||
if (_filter.AllowInfoMessages)
|
||||
return true;
|
||||
break;
|
||||
case MessageClass.WarningMsg:
|
||||
if (_filter.AllowWarningMessages) return true;
|
||||
@@ -55,43 +49,46 @@ namespace mRemoteNG.Messages.WriterDecorators
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CreateTimer()
|
||||
private async Task SwitchToMessageAsync()
|
||||
{
|
||||
_ecTimer = new Timer
|
||||
{
|
||||
Enabled = false,
|
||||
Interval = 300
|
||||
};
|
||||
_ecTimer.Tick += SwitchTimerTick;
|
||||
}
|
||||
|
||||
private void BeginSwitchToPanel()
|
||||
{
|
||||
_ecTimer.Enabled = true;
|
||||
}
|
||||
|
||||
private void SwitchTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
SwitchToMessage();
|
||||
_ecTimer.Enabled = false;
|
||||
await Task
|
||||
.Delay(TimeSpan.FromMilliseconds(300))
|
||||
.ContinueWith(task => SwitchToMessage());
|
||||
}
|
||||
|
||||
private void SwitchToMessage()
|
||||
{
|
||||
if (_messageWindow.InvokeRequired)
|
||||
{
|
||||
_frmMain.Invoke((MethodInvoker)SwitchToMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// do not attempt to focus the notification panel if it is in an inconsistent state
|
||||
if (_messageWindow.DockState == DockState.Unknown)
|
||||
return;
|
||||
|
||||
_messageWindow.PreviousActiveForm = (DockContent)_frmMain.pnlDock.ActiveContent;
|
||||
ShowMcForm();
|
||||
|
||||
// Show the notifications panel solution:
|
||||
// https://stackoverflow.com/questions/13843604/calling-up-dockpanel-suites-autohidden-dockcontent-programmatically
|
||||
if (AutoHideEnabled(_messageWindow))
|
||||
_frmMain.pnlDock.ActiveAutoHideContent = _messageWindow;
|
||||
else
|
||||
_messageWindow.Show(_frmMain.pnlDock);
|
||||
|
||||
_messageWindow.lvErrorCollector.Focus();
|
||||
_messageWindow.lvErrorCollector.SelectedItems.Clear();
|
||||
_messageWindow.lvErrorCollector.Items[0].Selected = true;
|
||||
_messageWindow.lvErrorCollector.FocusedItem = _messageWindow.lvErrorCollector.Items[0];
|
||||
}
|
||||
|
||||
private void ShowMcForm()
|
||||
private bool AutoHideEnabled(DockContent content)
|
||||
{
|
||||
if (_frmMain.pnlDock.InvokeRequired)
|
||||
_frmMain.pnlDock.Invoke((MethodInvoker)ShowMcForm);
|
||||
else
|
||||
_messageWindow.Show(_frmMain.pnlDock);
|
||||
return content.DockState == DockState.DockBottomAutoHide ||
|
||||
content.DockState == DockState.DockTopAutoHide ||
|
||||
content.DockState == DockState.DockLeftAutoHide ||
|
||||
content.DockState == DockState.DockRightAutoHide;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
[assembly: AssemblyVersion("1.76.5.*")]
|
||||
[assembly: AssemblyVersion("1.76.6.*")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
4
mRemoteV1/Properties/Settings.Designer.cs
generated
4
mRemoteV1/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace mRemoteNG {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
@@ -2593,7 +2593,7 @@ namespace mRemoteNG {
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("General")]
|
||||
public string ConDefaultPanel {
|
||||
get {
|
||||
return ((string)(this["ConDefaultPanel"]));
|
||||
|
||||
@@ -645,7 +645,7 @@
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="ConDefaultPanel" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
<Value Profile="(Default)">General</Value>
|
||||
</Setting>
|
||||
<Setting Name="SaveConnectionsAfterEveryEdit" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
@@ -17,6 +17,10 @@
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<PermissionSet Unrestricted="true" ID="Custom" SameSite="site" />
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</asmv1:assembly>
|
||||
</asmv1:assembly>
|
||||
45
mRemoteV1/Resources/Language/Language.Designer.cs
generated
45
mRemoteV1/Resources/Language/Language.Designer.cs
generated
@@ -1711,6 +1711,15 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete....
|
||||
/// </summary>
|
||||
internal static string strDelete {
|
||||
get {
|
||||
return ResourceManager.GetString("strDelete", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detect.
|
||||
/// </summary>
|
||||
@@ -2777,6 +2786,15 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Must Be Between 0 and 255.
|
||||
/// </summary>
|
||||
internal static string strIPRange {
|
||||
get {
|
||||
return ResourceManager.GetString("strIPRange", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CTRL-ALT-DEL.
|
||||
/// </summary>
|
||||
@@ -4308,6 +4326,15 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Out Of Range.
|
||||
/// </summary>
|
||||
internal static string strOutOfRange {
|
||||
get {
|
||||
return ResourceManager.GetString("strOutOfRange", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Panel Name.
|
||||
/// </summary>
|
||||
@@ -6237,6 +6264,15 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Reconnect All Connections.
|
||||
/// </summary>
|
||||
internal static string strReconnectAllConnections {
|
||||
get {
|
||||
return ResourceManager.GetString("strReconnectAllConnections", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Reconnect to previously opened sessions on startup.
|
||||
/// </summary>
|
||||
@@ -7263,6 +7299,15 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to UltraVNC SingleClick.
|
||||
/// </summary>
|
||||
internal static string strUltraVNCSingleClick {
|
||||
get {
|
||||
return ResourceManager.GetString("strUltraVNCSingleClick", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Uncheck the properties you want not to be saved!.
|
||||
/// </summary>
|
||||
|
||||
@@ -2679,4 +2679,19 @@ This page will walk you through the process of upgrading your connections file o
|
||||
<data name="strCreateEmptyPanelOnStartUp" xml:space="preserve">
|
||||
<value>Create an empty panel when mRemoteNG starts</value>
|
||||
</data>
|
||||
<data name="strIPRange" xml:space="preserve">
|
||||
<value>Must Be Between 0 and 255</value>
|
||||
</data>
|
||||
<data name="strOutOfRange" xml:space="preserve">
|
||||
<value>Out Of Range</value>
|
||||
</data>
|
||||
<data name="strDelete" xml:space="preserve">
|
||||
<value>Delete...</value>
|
||||
</data>
|
||||
<data name="strReconnectAllConnections" xml:space="preserve">
|
||||
<value>Reconnect All Connections</value>
|
||||
</data>
|
||||
<data name="strUltraVNCSingleClick" xml:space="preserve">
|
||||
<value>UltraVNC SingleClick</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -9,35 +9,14 @@ namespace mRemoteNG.Themes
|
||||
/// </summary>
|
||||
public class PseudoKeyColor
|
||||
{
|
||||
private string key;
|
||||
private Color value;
|
||||
public PseudoKeyColor(string _key, Color _value)
|
||||
{
|
||||
key = _key;
|
||||
value = _value;
|
||||
}
|
||||
public string Key
|
||||
{
|
||||
get
|
||||
{
|
||||
return key;
|
||||
}
|
||||
set
|
||||
{
|
||||
key = value;
|
||||
}
|
||||
}
|
||||
public Color Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return value;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
Key = _key;
|
||||
Value = _value;
|
||||
}
|
||||
public string Key { get; set; }
|
||||
|
||||
public Color Value { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -48,15 +27,14 @@ namespace mRemoteNG.Themes
|
||||
{
|
||||
#region Private Variables
|
||||
//Collection for color values that are not loaded by dock panels (list, buttons,panel content, etc)
|
||||
private Dictionary<string, Color> _extendedColors;
|
||||
private Dictionary<string, Color> _default;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public ExtendedColorPalette()
|
||||
{
|
||||
_extendedColors = new Dictionary<string, Color>();
|
||||
_default = new Dictionary<string, Color>(); // If this is the default palette, it will not have a default-default palette
|
||||
ExtColorPalette = new Dictionary<string, Color>();
|
||||
DefaultColorPalette = new Dictionary<string, Color>(); // If this is the default palette, it will not have a default-default palette
|
||||
|
||||
}
|
||||
#endregion
|
||||
@@ -65,7 +43,7 @@ namespace mRemoteNG.Themes
|
||||
// Set the default theme, that theme should contain all color values used by the application
|
||||
public void setDefault(ExtendedColorPalette inPalettte)
|
||||
{
|
||||
_default = inPalettte._extendedColors;
|
||||
DefaultColorPalette = inPalettte.ExtColorPalette;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -76,12 +54,12 @@ namespace mRemoteNG.Themes
|
||||
/// <returns></returns>
|
||||
public Color getColor(string colorKey)
|
||||
{
|
||||
var retColor = _extendedColors.ContainsKey(colorKey) ? _extendedColors[colorKey]:Color.Empty;
|
||||
var retColor = ExtColorPalette.ContainsKey(colorKey) ? ExtColorPalette[colorKey]:Color.Empty;
|
||||
//Invisible colors are not good, might indicate missing color from the palette as is represented by 00000000
|
||||
if (retColor != Color.Empty && retColor.A != 0) return retColor;
|
||||
if(_default != null)
|
||||
if(DefaultColorPalette != null)
|
||||
{
|
||||
retColor = _default.ContainsKey(colorKey) ? _default[colorKey] : Color.Empty;
|
||||
retColor = DefaultColorPalette.ContainsKey(colorKey) ? DefaultColorPalette[colorKey] : Color.Empty;
|
||||
}
|
||||
//why are we here?, just avoid a crash
|
||||
if(retColor == Color.Empty)
|
||||
@@ -100,7 +78,7 @@ namespace mRemoteNG.Themes
|
||||
/// <param name="inColor"></param>
|
||||
public void addColor(string colorKey,Color inColor)
|
||||
{
|
||||
_extendedColors.Add(colorKey, inColor);
|
||||
ExtColorPalette.Add(colorKey, inColor);
|
||||
}
|
||||
|
||||
|
||||
@@ -111,33 +89,13 @@ namespace mRemoteNG.Themes
|
||||
/// <param name="inColor"></param>
|
||||
public void replaceColor(string colorKey, Color inColor)
|
||||
{
|
||||
_extendedColors[colorKey]= inColor;
|
||||
ExtColorPalette[colorKey]= inColor;
|
||||
}
|
||||
|
||||
public Dictionary<string, Color> DefaultColorPalette
|
||||
{
|
||||
get
|
||||
{
|
||||
return _default;
|
||||
}
|
||||
set
|
||||
{
|
||||
_default = value;
|
||||
}
|
||||
}
|
||||
public Dictionary<string, Color> DefaultColorPalette { get; set; }
|
||||
|
||||
|
||||
public Dictionary<string, Color> ExtColorPalette
|
||||
{
|
||||
get
|
||||
{
|
||||
return _extendedColors;
|
||||
}
|
||||
set
|
||||
{
|
||||
_extendedColors = value;
|
||||
}
|
||||
}
|
||||
public Dictionary<string, Color> ExtColorPalette { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace mRemoteNG.Themes
|
||||
foreach (DictionaryEntry entry in resourceSet)
|
||||
{
|
||||
var colorName = entry.Key.ToString();
|
||||
var xmlQueryPath = (string)entry.Value;
|
||||
var xmlQueryPath = entry.Value.ToString();
|
||||
if (_xml.DocumentElement == null) continue;
|
||||
var colorNodeList = _xml.DocumentElement.FirstChild.SelectNodes(xmlQueryPath);
|
||||
var color = colorNodeList != null && colorNodeList.Count > 0 ? colorNodeList[0].Value : null;
|
||||
@@ -60,7 +60,7 @@ namespace mRemoteNG.Themes
|
||||
foreach (DictionaryEntry entry in resourceSet)
|
||||
{
|
||||
var colorName = entry.Key.ToString();
|
||||
var xmlQueryPath = (string)entry.Value;
|
||||
var xmlQueryPath = entry.Value.ToString();
|
||||
var colorNodeList = _xml.DocumentElement?.FirstChild.SelectNodes(xmlQueryPath);
|
||||
if (colorNodeList == null || colorNodeList.Count <= 0) continue;
|
||||
var paletteColor = colorPalette.getColor(colorName);
|
||||
|
||||
@@ -7,6 +7,7 @@ using WeifenLuo.WinFormsUI.Docking;
|
||||
namespace mRemoteNG.Themes
|
||||
{
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Container class for all the color and style elements to define a theme
|
||||
/// </summary>
|
||||
@@ -15,34 +16,32 @@ namespace mRemoteNG.Themes
|
||||
#region Private Variables
|
||||
private string _name;
|
||||
private ThemeBase _theme;
|
||||
private String _URI;
|
||||
private string _URI;
|
||||
private VisualStudioToolStripExtender.VsVersion _version;
|
||||
private ExtendedColorPalette _extendedPalette;
|
||||
private bool _isThemeBase;
|
||||
private bool _isExtendable;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public ThemeInfo(string themeName, ThemeBase inTheme, String inURI, VisualStudioToolStripExtender.VsVersion inVersion, ExtendedColorPalette inExtendedPalette)
|
||||
public ThemeInfo(string themeName, ThemeBase inTheme, string inURI, VisualStudioToolStripExtender.VsVersion inVersion, ExtendedColorPalette inExtendedPalette)
|
||||
{
|
||||
_name = themeName;
|
||||
_theme = inTheme;
|
||||
_URI = inURI;
|
||||
_version = inVersion;
|
||||
_extendedPalette = inExtendedPalette;
|
||||
_isThemeBase = false;
|
||||
_isExtendable = false;
|
||||
IsThemeBase = false;
|
||||
IsExtendable = false;
|
||||
}
|
||||
|
||||
public ThemeInfo(string themeName, ThemeBase inTheme, String inURI, VisualStudioToolStripExtender.VsVersion inVersion)
|
||||
public ThemeInfo(string themeName, ThemeBase inTheme, string inURI, VisualStudioToolStripExtender.VsVersion inVersion)
|
||||
{
|
||||
_name = themeName;
|
||||
_theme = inTheme;
|
||||
_URI = inURI;
|
||||
_version = inVersion;
|
||||
_isThemeBase = false;
|
||||
_isExtendable = false;
|
||||
IsThemeBase = false;
|
||||
IsExtendable = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -57,8 +56,8 @@ namespace mRemoteNG.Themes
|
||||
};
|
||||
var clonedObj = new ThemeInfo(_name, _theme, _URI, _version, extPalette)
|
||||
{
|
||||
IsExtendable = _isExtendable,
|
||||
IsThemeBase = _isThemeBase
|
||||
IsExtendable = IsExtendable,
|
||||
IsThemeBase = IsThemeBase
|
||||
};
|
||||
|
||||
return clonedObj;
|
||||
@@ -71,8 +70,8 @@ namespace mRemoteNG.Themes
|
||||
[Browsable(false)]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
if (string.Equals(_name, value, StringComparison.InvariantCulture))
|
||||
{
|
||||
@@ -84,7 +83,7 @@ namespace mRemoteNG.Themes
|
||||
|
||||
public ThemeBase Theme
|
||||
{
|
||||
get { return _theme; }
|
||||
get => _theme;
|
||||
set
|
||||
{
|
||||
if (value != null && _theme == value)
|
||||
@@ -97,7 +96,7 @@ namespace mRemoteNG.Themes
|
||||
|
||||
public string URI
|
||||
{
|
||||
get { return _URI; }
|
||||
get => _URI;
|
||||
set
|
||||
{
|
||||
if (value != null && _URI == value)
|
||||
@@ -110,7 +109,7 @@ namespace mRemoteNG.Themes
|
||||
|
||||
public VisualStudioToolStripExtender.VsVersion Version
|
||||
{
|
||||
get { return _version; }
|
||||
get => _version;
|
||||
set
|
||||
{
|
||||
if (Equals(_version, value))
|
||||
@@ -123,7 +122,7 @@ namespace mRemoteNG.Themes
|
||||
|
||||
public ExtendedColorPalette ExtendedPalette
|
||||
{
|
||||
get { return _extendedPalette; }
|
||||
get => _extendedPalette;
|
||||
set
|
||||
{
|
||||
if (_extendedPalette != null && _extendedPalette == value)
|
||||
@@ -134,23 +133,10 @@ namespace mRemoteNG.Themes
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsThemeBase
|
||||
{
|
||||
get { return _isThemeBase; }
|
||||
set
|
||||
{
|
||||
_isThemeBase = value;
|
||||
}
|
||||
}
|
||||
public bool IsThemeBase { get; set; }
|
||||
|
||||
public bool IsExtendable { get; set; }
|
||||
|
||||
public bool IsExtendable
|
||||
{
|
||||
get { return _isExtendable; }
|
||||
set
|
||||
{
|
||||
_isExtendable = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -46,11 +46,7 @@ namespace mRemoteNG.Themes
|
||||
#region Public Methods
|
||||
public static ThemeManager getInstance()
|
||||
{
|
||||
if(themeInstance == null)
|
||||
{
|
||||
themeInstance = new ThemeManager();
|
||||
}
|
||||
return themeInstance;
|
||||
return themeInstance ?? (themeInstance = new ThemeManager());
|
||||
}
|
||||
|
||||
|
||||
@@ -64,80 +60,74 @@ namespace mRemoteNG.Themes
|
||||
//THe manager precharges all the themes at once
|
||||
public List<ThemeInfo> LoadThemes()
|
||||
{
|
||||
if (themes == null)
|
||||
if (themes != null) return themes.Values.OfType<ThemeInfo>().ToList();
|
||||
themes = new Hashtable();
|
||||
|
||||
//Load the files in theme folder first, to incluide vstheme light as default
|
||||
var themePath = App.Info.SettingsFileInfo.ThemeFolder;
|
||||
if (themePath == null) return themes.Values.OfType<ThemeInfo>().ToList();
|
||||
try
|
||||
{
|
||||
themes = new Hashtable();
|
||||
|
||||
//Load the files in theme folder first, to incluide vstheme light as default
|
||||
string themePath = App.Info.SettingsFileInfo.ThemeFolder;
|
||||
if (themePath != null)
|
||||
//In install mode first time is necesary to copy the themes folder
|
||||
if (!Directory.Exists(themePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
//In install mode first time is necesary to copy the themes folder
|
||||
if (!Directory.Exists(themePath))
|
||||
{
|
||||
Directory.CreateDirectory(themePath);
|
||||
Directory.CreateDirectory(themePath);
|
||||
|
||||
}
|
||||
DirectoryInfo orig = new DirectoryInfo(App.Info.SettingsFileInfo.InstalledThemeFolder);
|
||||
FileInfo[] files = orig.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
}
|
||||
var orig = new DirectoryInfo(App.Info.SettingsFileInfo.InstalledThemeFolder);
|
||||
var files = orig.GetFiles();
|
||||
foreach (var file in files)
|
||||
{
|
||||
|
||||
if (!File.Exists(Path.Combine(themePath, file.Name)))
|
||||
file.CopyTo(Path.Combine(themePath, file.Name), true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Check that theme folder exist before trying to load themes
|
||||
if (Directory.Exists(themePath))
|
||||
{
|
||||
string[] themeFiles = Directory.GetFiles(themePath, "*.vstheme");
|
||||
string defaultThemeURL = Directory.GetFiles(themePath, "vs2015light" + ".vstheme")[0];
|
||||
//First we load the default theme, its vs2015light
|
||||
ThemeInfo defaultTheme = ThemeSerializer.LoadFromXmlFile(defaultThemeURL);
|
||||
themes.Add(defaultTheme.Name, defaultTheme);
|
||||
//Then the rest
|
||||
foreach (string themeFile in themeFiles)
|
||||
{
|
||||
//filter default one
|
||||
ThemeInfo extTheme = ThemeSerializer.LoadFromXmlFile(themeFile, defaultTheme);
|
||||
if (extTheme.Theme != null && !themes.ContainsKey(extTheme.Name))
|
||||
{
|
||||
themes.Add(extTheme.Name, extTheme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Load the embedded themes, extended palettes are taken from the vs2015 themes, trying to match the color theme
|
||||
ThemeInfo vs2003 = new ThemeInfo("Vs2003", new VS2003Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2003, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2003.Name, vs2003);
|
||||
ThemeInfo vs2005 = new ThemeInfo("Vs2005", new VS2005Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2005, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2005.Name, vs2005);
|
||||
ThemeInfo vs2012Light = new ThemeInfo("vs2012Light", new VS2012LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2012Light.Name, vs2012Light);
|
||||
ThemeInfo vs2012Dark = new ThemeInfo("vs2012Dark", new VS2012DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
|
||||
themes.Add(vs2012Dark.Name, vs2012Dark);
|
||||
ThemeInfo vs2012Blue = new ThemeInfo("vs2012Blue", new VS2012BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
|
||||
themes.Add(vs2012Blue.Name, vs2012Blue);
|
||||
ThemeInfo vs2013Light = new ThemeInfo("vs2013Light", new VS2013LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2013Light.Name, vs2013Light);
|
||||
ThemeInfo vs2013Dark = new ThemeInfo("vs2013Dark", new VS2013DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
|
||||
themes.Add(vs2013Dark.Name, vs2013Dark);
|
||||
ThemeInfo vs2013Blue = new ThemeInfo("vs2013Blue", new VS2013BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
|
||||
themes.Add(vs2013Blue.Name, vs2013Blue);
|
||||
}
|
||||
}
|
||||
catch(Exception ex )
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Error loading themes" + Environment.NewLine + ex.Message, true);
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(themePath, file.Name)))
|
||||
file.CopyTo(Path.Combine(themePath, file.Name), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Check that theme folder exist before trying to load themes
|
||||
if (Directory.Exists(themePath))
|
||||
{
|
||||
var themeFiles = Directory.GetFiles(themePath, "*.vstheme");
|
||||
var defaultThemeURL = Directory.GetFiles(themePath, "vs2015light" + ".vstheme")[0];
|
||||
//First we load the default theme, its vs2015light
|
||||
var defaultTheme = ThemeSerializer.LoadFromXmlFile(defaultThemeURL);
|
||||
themes.Add(defaultTheme.Name, defaultTheme);
|
||||
//Then the rest
|
||||
foreach (var themeFile in themeFiles)
|
||||
{
|
||||
//filter default one
|
||||
var extTheme = ThemeSerializer.LoadFromXmlFile(themeFile, defaultTheme);
|
||||
if (extTheme.Theme != null && !themes.ContainsKey(extTheme.Name))
|
||||
{
|
||||
themes.Add(extTheme.Name, extTheme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Load the embedded themes, extended palettes are taken from the vs2015 themes, trying to match the color theme
|
||||
var vs2003 = new ThemeInfo("Vs2003", new VS2003Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2003, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2003.Name, vs2003);
|
||||
var vs2005 = new ThemeInfo("Vs2005", new VS2005Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2005, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2005.Name, vs2005);
|
||||
var vs2012Light = new ThemeInfo("vs2012Light", new VS2012LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2012Light.Name, vs2012Light);
|
||||
var vs2012Dark = new ThemeInfo("vs2012Dark", new VS2012DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
|
||||
themes.Add(vs2012Dark.Name, vs2012Dark);
|
||||
var vs2012Blue = new ThemeInfo("vs2012Blue", new VS2012BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
|
||||
themes.Add(vs2012Blue.Name, vs2012Blue);
|
||||
var vs2013Light = new ThemeInfo("vs2013Light", new VS2013LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
|
||||
themes.Add(vs2013Light.Name, vs2013Light);
|
||||
var vs2013Dark = new ThemeInfo("vs2013Dark", new VS2013DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
|
||||
themes.Add(vs2013Dark.Name, vs2013Dark);
|
||||
var vs2013Blue = new ThemeInfo("vs2013Blue", new VS2013BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
|
||||
themes.Add(vs2013Blue.Name, vs2013Blue);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Error loading themes" + Environment.NewLine + ex.Message, true);
|
||||
}
|
||||
return themes.Values.OfType<ThemeInfo>().ToList();
|
||||
}
|
||||
|
||||
@@ -149,29 +139,24 @@ namespace mRemoteNG.Themes
|
||||
/// <returns></returns>
|
||||
public ThemeInfo addTheme(ThemeInfo baseTheme, string newThemeName)
|
||||
{
|
||||
if (!themes.Contains(newThemeName))
|
||||
{
|
||||
ThemeInfo modifiedTheme = (ThemeInfo)baseTheme.Clone();
|
||||
modifiedTheme.Name = newThemeName;
|
||||
modifiedTheme.IsExtendable = true;
|
||||
modifiedTheme.IsThemeBase = false;
|
||||
ThemeSerializer.SaveToXmlFile(modifiedTheme,baseTheme);
|
||||
themes.Add(newThemeName,modifiedTheme);
|
||||
return modifiedTheme;
|
||||
}
|
||||
return null;
|
||||
if (themes.Contains(newThemeName)) return null;
|
||||
var modifiedTheme = (ThemeInfo)baseTheme.Clone();
|
||||
modifiedTheme.Name = newThemeName;
|
||||
modifiedTheme.IsExtendable = true;
|
||||
modifiedTheme.IsThemeBase = false;
|
||||
ThemeSerializer.SaveToXmlFile(modifiedTheme,baseTheme);
|
||||
themes.Add(newThemeName,modifiedTheme);
|
||||
return modifiedTheme;
|
||||
}
|
||||
|
||||
//Delete a theme from memory and disk
|
||||
public void deleteTheme(ThemeInfo themeToDelete)
|
||||
{
|
||||
if (themes.Contains(themeToDelete.Name))
|
||||
{
|
||||
if(ActiveTheme == themeToDelete)
|
||||
ActiveTheme = DefaultTheme;
|
||||
themes.Remove(themeToDelete.Name);
|
||||
ThemeSerializer.DeleteFile(themeToDelete);
|
||||
}
|
||||
if (!themes.Contains(themeToDelete.Name)) return;
|
||||
if(ActiveTheme == themeToDelete)
|
||||
ActiveTheme = DefaultTheme;
|
||||
themes.Remove(themeToDelete.Name);
|
||||
ThemeSerializer.DeleteFile(themeToDelete);
|
||||
}
|
||||
|
||||
//Sincronize the theme XML values from memory to disk
|
||||
@@ -191,10 +176,8 @@ namespace mRemoteNG.Themes
|
||||
{
|
||||
if (themes.Contains(name))
|
||||
return false;
|
||||
char[] badChars = Path.GetInvalidFileNameChars();
|
||||
if (name.IndexOfAny(badChars) != -1)
|
||||
return false;
|
||||
return true;
|
||||
var badChars = Path.GetInvalidFileNameChars();
|
||||
return name.IndexOfAny(badChars) == -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -206,10 +189,11 @@ namespace mRemoteNG.Themes
|
||||
|
||||
public event ThemeChangedEventHandler ThemeChanged
|
||||
{
|
||||
add { ThemeChangedEvent = (ThemeChangedEventHandler)System.Delegate.Combine(ThemeChangedEvent, value); }
|
||||
remove { ThemeChangedEvent = (ThemeChangedEventHandler)System.Delegate.Remove(ThemeChangedEvent, value); }
|
||||
add => ThemeChangedEvent = (ThemeChangedEventHandler)Delegate.Combine(ThemeChangedEvent, value);
|
||||
remove => ThemeChangedEvent = (ThemeChangedEventHandler)Delegate.Remove(ThemeChangedEvent, value);
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedParameter.Local
|
||||
private void NotifyThemeChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "Name")
|
||||
@@ -223,44 +207,29 @@ namespace mRemoteNG.Themes
|
||||
#region Properties
|
||||
public bool ThemingActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _themeActive;
|
||||
}
|
||||
get => _themeActive;
|
||||
set
|
||||
{
|
||||
if(themes.Count != 0)
|
||||
{
|
||||
_themeActive = value;
|
||||
Settings.Default.ThemingActive = value;
|
||||
NotifyThemeChanged(this, new PropertyChangedEventArgs(""));
|
||||
}
|
||||
if (themes.Count == 0) return;
|
||||
_themeActive = value;
|
||||
Settings.Default.ThemingActive = value;
|
||||
NotifyThemeChanged(this, new PropertyChangedEventArgs(""));
|
||||
}
|
||||
}
|
||||
|
||||
private ThemeInfo DefaultTheme
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ThemeInfo) themes["vs2015light"];
|
||||
}
|
||||
}
|
||||
|
||||
public ThemeInfo DefaultTheme => (ThemeInfo) themes["vs2015light"];
|
||||
|
||||
public ThemeInfo ActiveTheme
|
||||
{
|
||||
get
|
||||
{
|
||||
return _activeTheme;
|
||||
}
|
||||
set
|
||||
// default if themes are not enabled
|
||||
get => ThemingActive == false ? DefaultTheme : _activeTheme;
|
||||
set
|
||||
{
|
||||
//You can only enable theming if there are themes laoded
|
||||
if(value != null)
|
||||
{
|
||||
_activeTheme = value;
|
||||
Settings.Default.ThemeName = value.Name;
|
||||
NotifyThemeChanged(this, new PropertyChangedEventArgs("theme"));
|
||||
}
|
||||
if (value == null) return;
|
||||
_activeTheme = value;
|
||||
Settings.Default.ThemeName = value.Name;
|
||||
NotifyThemeChanged(this, new PropertyChangedEventArgs("theme"));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using System.Linq;
|
||||
|
||||
namespace mRemoteNG.Themes
|
||||
{
|
||||
public class ThemeSerializer
|
||||
public static class ThemeSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Save the theme to file, name property is used as filename
|
||||
/// The baseTheme is used as a template, by copy that file and rewrite the extpalette values
|
||||
/// </summary>
|
||||
/// <param name="themeInfo"></param>
|
||||
public static void SaveToXmlFile(ThemeInfo themeToSave,ThemeInfo baseTheme)
|
||||
/// <summary>
|
||||
/// Save the theme to file, name property is used as filename
|
||||
/// The baseTheme is used as a template, by copy that file and rewrite the extpalette values
|
||||
/// </summary>
|
||||
/// <param name="themeToSave"></param>
|
||||
/// <param name="baseTheme"></param>
|
||||
public static void SaveToXmlFile(ThemeInfo themeToSave,ThemeInfo baseTheme)
|
||||
{
|
||||
string oldURI = baseTheme.URI;
|
||||
String directoryName = Path.GetDirectoryName(oldURI);
|
||||
string toSaveURI = directoryName + Path.DirectorySeparatorChar + themeToSave.Name + ".vstheme";
|
||||
var oldURI = baseTheme.URI;
|
||||
var directoryName = Path.GetDirectoryName(oldURI);
|
||||
var toSaveURI = directoryName + Path.DirectorySeparatorChar + themeToSave.Name + ".vstheme";
|
||||
File.Copy(baseTheme.URI, toSaveURI);
|
||||
themeToSave.URI = toSaveURI;
|
||||
}
|
||||
@@ -35,10 +32,9 @@ namespace mRemoteNG.Themes
|
||||
/// <param name="themeToUpdate"></param>
|
||||
public static void UpdateThemeXMLValues(ThemeInfo themeToUpdate)
|
||||
{
|
||||
byte[] bytesIn = File.ReadAllBytes(themeToUpdate.URI);
|
||||
MremoteNGPaletteManipulator manipulator;
|
||||
manipulator = new MremoteNGPaletteManipulator(bytesIn, themeToUpdate.ExtendedPalette);
|
||||
byte[] bytesOut = manipulator.mergePalette(themeToUpdate.ExtendedPalette);
|
||||
var bytesIn = File.ReadAllBytes(themeToUpdate.URI);
|
||||
var manipulator = new MremoteNGPaletteManipulator(bytesIn, themeToUpdate.ExtendedPalette);
|
||||
var bytesOut = manipulator.mergePalette(themeToUpdate.ExtendedPalette);
|
||||
File.WriteAllBytes(themeToUpdate.URI, bytesOut);
|
||||
}
|
||||
|
||||
@@ -50,22 +46,22 @@ namespace mRemoteNG.Themes
|
||||
/// <returns></returns>
|
||||
public static ThemeInfo LoadFromXmlFile(string filename, ThemeInfo defaultTheme=null)
|
||||
{
|
||||
byte[] bytes = File.ReadAllBytes(filename);
|
||||
var bytes = File.ReadAllBytes(filename);
|
||||
//Load the dockpanel part
|
||||
MremoteNGThemeBase themeBaseLoad= new MremoteNGThemeBase(bytes);
|
||||
var themeBaseLoad= new MremoteNGThemeBase(bytes);
|
||||
//Load the mremote part
|
||||
MremoteNGPaletteManipulator extColorLoader;
|
||||
//Cause we cannot default the theme for the default theme
|
||||
extColorLoader = new MremoteNGPaletteManipulator(bytes, defaultTheme ==null ? null:defaultTheme.ExtendedPalette);
|
||||
ThemeInfo loadedTheme = new ThemeInfo(Path.GetFileNameWithoutExtension(filename), themeBaseLoad, filename, VisualStudioToolStripExtender.VsVersion.Vs2015, extColorLoader.getColors());
|
||||
if((new string[] { "darcula", "vs2015blue", "vs2015dark" , "vs2015light" }).Contains(Path.GetFileNameWithoutExtension(filename)))
|
||||
//Cause we cannot default the theme for the default theme
|
||||
var extColorLoader = new MremoteNGPaletteManipulator(bytes, defaultTheme?.ExtendedPalette);
|
||||
var loadedTheme = new ThemeInfo(Path.GetFileNameWithoutExtension(filename), themeBaseLoad, filename, VisualStudioToolStripExtender.VsVersion.Vs2015, extColorLoader.getColors());
|
||||
if(new[] { "darcula", "vs2015blue", "vs2015dark" , "vs2015light" }.Contains(Path.GetFileNameWithoutExtension(filename)))
|
||||
{
|
||||
loadedTheme.IsThemeBase = true;
|
||||
}
|
||||
loadedTheme.IsExtendable = true;
|
||||
return loadedTheme;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
private static string EncodeColorName(Color color)
|
||||
{
|
||||
// best/simplest answer to converting to hex: http://stackoverflow.com/questions/12078942/how-to-convert-from-argb-to-hex-aarrggbb
|
||||
@@ -77,7 +73,7 @@ namespace mRemoteNG.Themes
|
||||
var regex = new System.Text.RegularExpressions.Regex("^[0-9a-fA-F]{8}$");
|
||||
return regex.Match(name).Success ? Color.FromArgb(Convert.ToInt32(name, 16)) : Color.FromName(name);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
else
|
||||
e.Graphics.FillRectangle(new SolidBrush(_themeManager.ActiveTheme.ExtendedPalette.getColor("ComboBox_Background")), e.Bounds);
|
||||
|
||||
if(DisplayMember == null || DisplayMember == "")
|
||||
if(string.IsNullOrEmpty(DisplayMember))
|
||||
e.Graphics.DrawString(Items[index].ToString(), e.Font, itemBrush, e.Bounds, StringFormat.GenericDefault);
|
||||
else
|
||||
{
|
||||
@@ -129,7 +129,7 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
}
|
||||
|
||||
//Arrow
|
||||
e.Graphics.DrawString("\u25BC", this.Font, new SolidBrush(ButtFore), Width-17, Height/2 -5);
|
||||
e.Graphics.DrawString("\u25BC", Font, new SolidBrush(ButtFore), Width-17, Height/2 -5);
|
||||
|
||||
//Text
|
||||
var textRect = new Rectangle(2, 2, Width - 20, Height - 4);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
{
|
||||
private ThemeManager _themeManager;
|
||||
|
||||
public NGGroupBox() : base()
|
||||
public NGGroupBox()
|
||||
{
|
||||
ThemeManager.getInstance().ThemeChanged += OnCreateControl;
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
if (Enabled)
|
||||
{
|
||||
TextRenderer.DrawText(e.Graphics, this.Text, Font, ClientRectangle, ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
||||
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
||||
}
|
||||
else
|
||||
{
|
||||
var disabledtextLabel = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Disabled_Foreground");
|
||||
TextRenderer.DrawText(e.Graphics, this.Text, Font, ClientRectangle, disabledtextLabel, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
||||
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, disabledtextLabel, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using mRemoteNG.Themes;
|
||||
using System;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Themes;
|
||||
// ReSharper disable LocalizableElement
|
||||
|
||||
namespace mRemoteNG.UI.Controls.Base
|
||||
{
|
||||
@@ -14,7 +15,7 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
private NGButton Up;
|
||||
private NGButton Down;
|
||||
|
||||
public NGNumericUpDown() : base()
|
||||
public NGNumericUpDown()
|
||||
{
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
ThemeManager.getInstance().ThemeChanged += OnCreateControl;
|
||||
@@ -28,7 +29,8 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background");
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
|
||||
//Hide those nonthemable butons
|
||||
Controls[0].Hide();
|
||||
if (Controls.Count > 0)
|
||||
Controls[0].Hide();
|
||||
//Add new themable buttons
|
||||
Up = new NGButton
|
||||
{
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace mRemoteNG.UI.Controls
|
||||
private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler();
|
||||
private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance;
|
||||
private readonly StatusImageList _statusImageList = new StatusImageList();
|
||||
private bool _nodeInEditMode;
|
||||
private readonly ConnectionTreeSearchTextFilter _connectionTreeSearchTextFilter = new ConnectionTreeSearchTextFilter();
|
||||
private bool _nodeInEditMode;
|
||||
private bool _allowEdit;
|
||||
private ConnectionContextMenu _contextMenu;
|
||||
private ConnectionTreeModel _connectionTreeModel;
|
||||
@@ -54,8 +55,6 @@ namespace mRemoteNG.UI.Controls
|
||||
UseOverlays = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
@@ -265,6 +264,9 @@ namespace mRemoteNG.UI.Controls
|
||||
if (SelectedNode?.GetTreeNodeType() == TreeNodeType.PuttyRoot || SelectedNode?.GetTreeNodeType() == TreeNodeType.PuttySession)
|
||||
return;
|
||||
|
||||
// the new node will survive filtering if filtering is active
|
||||
_connectionTreeSearchTextFilter.SpecialInclusionList.Add(newNode);
|
||||
|
||||
// use root node if no node is selected
|
||||
ConnectionInfo parentNode = SelectedNode ?? GetRootConnectionNode();
|
||||
DefaultConnectionInfo.Instance.SaveTo(newNode);
|
||||
@@ -335,10 +337,24 @@ namespace mRemoteNG.UI.Controls
|
||||
AutoResizeColumn(Columns[0]);
|
||||
}
|
||||
|
||||
protected override void UpdateFiltering()
|
||||
/// <summary>
|
||||
/// Filters tree items based on the given <see cref="filterText"/>
|
||||
/// </summary>
|
||||
/// <param name="filterText">The text to filter by</param>
|
||||
public void ApplyFilter(string filterText)
|
||||
{
|
||||
base.UpdateFiltering();
|
||||
AutoResizeColumn(Columns[0]);
|
||||
UseFiltering = true;
|
||||
_connectionTreeSearchTextFilter.FilterText = filterText;
|
||||
ModelFilter = _connectionTreeSearchTextFilter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all item filtering from the connection tree
|
||||
/// </summary>
|
||||
public void RemoveFilter()
|
||||
{
|
||||
UseFiltering = false;
|
||||
ResetColumnFiltering();
|
||||
}
|
||||
|
||||
private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
|
||||
@@ -363,6 +379,12 @@ namespace mRemoteNG.UI.Controls
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateFiltering()
|
||||
{
|
||||
base.UpdateFiltering();
|
||||
AutoResizeColumn(Columns[0]);
|
||||
}
|
||||
|
||||
private void tvConnections_AfterSelect(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -399,6 +421,13 @@ namespace mRemoteNG.UI.Controls
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Settings.Default.ShowDescriptionTooltipsInTree)
|
||||
{
|
||||
// setting text to null prevents the tooltip from being shown
|
||||
e.Text = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var nodeProducingTooltip = (ConnectionInfo)e.Model;
|
||||
e.Text = nodeProducingTooltip.Description;
|
||||
}
|
||||
@@ -434,6 +463,9 @@ namespace mRemoteNG.UI.Controls
|
||||
ConnectionTreeModel.RenameNode(SelectedNode, e.Label);
|
||||
_nodeInEditMode = false;
|
||||
_allowEdit = false;
|
||||
// ensures that if we are filtering and a new item is added that doesn't match the filter, it will be filtered out
|
||||
_connectionTreeSearchTextFilter.SpecialInclusionList.Clear();
|
||||
UpdateFiltering();
|
||||
Windows.ConfigForm.SelectedTreeNode = SelectedNode;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BrightIdeasSoftware;
|
||||
using System.Collections.Generic;
|
||||
using BrightIdeasSoftware;
|
||||
using mRemoteNG.Connection;
|
||||
|
||||
namespace mRemoteNG.UI.Controls
|
||||
@@ -7,12 +8,22 @@ namespace mRemoteNG.UI.Controls
|
||||
{
|
||||
public string FilterText { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// A list of <see cref="ConnectionInfo"/> objects that should
|
||||
/// always be included in the output, regardless of matching
|
||||
/// the desired <see cref="FilterText"/>.
|
||||
/// </summary>
|
||||
public List<ConnectionInfo> SpecialInclusionList { get; } = new List<ConnectionInfo>();
|
||||
|
||||
public bool Filter(object modelObject)
|
||||
{
|
||||
var objectAsConnectionInfo = modelObject as ConnectionInfo;
|
||||
if (objectAsConnectionInfo == null)
|
||||
return false;
|
||||
|
||||
if (SpecialInclusionList.Contains(objectAsConnectionInfo))
|
||||
return true;
|
||||
|
||||
var filterTextLower = FilterText.ToLowerInvariant();
|
||||
|
||||
if (objectAsConnectionInfo.Name.ToLowerInvariant().Contains(filterTextLower) ||
|
||||
|
||||
@@ -1,171 +1,263 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
|
||||
namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// This class overrides the standard PropertyGrid provided by Microsoft.
|
||||
/// It also allows to hide (or filter) the properties of the SelectedObject displayed by the PropertyGrid.
|
||||
/// </summary>
|
||||
public partial class FilteredPropertyGrid : PropertyGrid
|
||||
/// <summary>
|
||||
/// This class overrides the standard PropertyGrid provided by Microsoft.
|
||||
/// It also allows to hide (or filter) the properties of the SelectedObject displayed by the PropertyGrid.
|
||||
/// </summary>
|
||||
public partial class FilteredPropertyGrid : PropertyGrid
|
||||
{
|
||||
/// <summary>Contain a reference to the collection of properties to show in the parent PropertyGrid.</summary>
|
||||
/// <summary>
|
||||
/// Contain a reference to the collection of properties to show in the parent PropertyGrid.
|
||||
/// </summary>
|
||||
/// <remarks>By default, m_PropertyDescriptors contain all the properties of the object. </remarks>
|
||||
readonly List<PropertyDescriptor> m_PropertyDescriptors = new List<PropertyDescriptor>();
|
||||
/// <summary>Contain a reference to the array of properties to display in the PropertyGrid.</summary>
|
||||
private AttributeCollection m_HiddenAttributes, m_BrowsableAttributes;
|
||||
/// <summary>Contain references to the arrays of properties or categories to hide.</summary>
|
||||
private string[] m_BrowsableProperties, m_HiddenProperties;
|
||||
/// <summary>Contain a reference to the wrapper that contains the object to be displayed into the PropertyGrid.</summary>
|
||||
private ObjectWrapper m_Wrapper;
|
||||
readonly List<PropertyDescriptor> _propertyDescriptors = new List<PropertyDescriptor>();
|
||||
|
||||
/// <summary>Public constructor.</summary>
|
||||
public FilteredPropertyGrid() {
|
||||
/// <summary>
|
||||
/// Contain a reference to the array of properties to display in the PropertyGrid.
|
||||
/// </summary>
|
||||
private AttributeCollection _hiddenAttributes;
|
||||
private AttributeCollection _browsableAttributes;
|
||||
|
||||
/// <summary>
|
||||
/// Contain references to the arrays of properties or categories to hide.
|
||||
/// </summary>
|
||||
private string[] _mBrowsableProperties;
|
||||
private string[] _mHiddenProperties;
|
||||
/// <summary>
|
||||
/// Contain a reference to the wrapper that contains the object to be displayed into the PropertyGrid.
|
||||
/// </summary>
|
||||
private ObjectWrapper _mWrapper;
|
||||
|
||||
/// <summary>
|
||||
/// Public constructor.
|
||||
/// </summary>
|
||||
public FilteredPropertyGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.SelectedObject = m_Wrapper;
|
||||
base.SelectedObject = _mWrapper;
|
||||
}
|
||||
|
||||
public new AttributeCollection BrowsableAttributes {
|
||||
get { return m_BrowsableAttributes; }
|
||||
/// <summary>
|
||||
/// A list of all currently properties being shown by the property grid.
|
||||
/// </summary>
|
||||
public IEnumerable<string> VisibleProperties => _propertyDescriptors.Select(p => p.Name);
|
||||
|
||||
public new AttributeCollection BrowsableAttributes {
|
||||
get { return _browsableAttributes; }
|
||||
set {
|
||||
if (m_BrowsableAttributes == value) return;
|
||||
m_HiddenAttributes = null;
|
||||
m_BrowsableAttributes = value;
|
||||
if (_browsableAttributes == value) return;
|
||||
_hiddenAttributes = null;
|
||||
_browsableAttributes = value;
|
||||
RefreshProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get or set the categories to hide.</summary>
|
||||
/// <summary>
|
||||
/// Get or set the categories to hide.
|
||||
/// </summary>
|
||||
public AttributeCollection HiddenAttributes {
|
||||
get { return m_HiddenAttributes; }
|
||||
get { return _hiddenAttributes; }
|
||||
set {
|
||||
if (value == m_HiddenAttributes) return;
|
||||
m_HiddenAttributes = value;
|
||||
m_BrowsableAttributes = null;
|
||||
if (value == _hiddenAttributes) return;
|
||||
_hiddenAttributes = value;
|
||||
_browsableAttributes = null;
|
||||
RefreshProperties();
|
||||
}
|
||||
}
|
||||
/// <summary>Get or set the properties to show.</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the properties to show.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException">if one or several properties don't exist.</exception>
|
||||
public string[] BrowsableProperties {
|
||||
get { return m_BrowsableProperties; }
|
||||
get { return _mBrowsableProperties; }
|
||||
set {
|
||||
if (value == m_BrowsableProperties) return;
|
||||
m_BrowsableProperties = value;
|
||||
//m_HiddenProperties = null;
|
||||
if (value == _mBrowsableProperties) return;
|
||||
_mBrowsableProperties = value;
|
||||
RefreshProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get or set the properties to hide.</summary>
|
||||
public string[] HiddenProperties {
|
||||
get { return m_HiddenProperties; }
|
||||
get { return _mHiddenProperties; }
|
||||
set {
|
||||
if (value == m_HiddenProperties) return;
|
||||
//m_BrowsableProperties = null;
|
||||
m_HiddenProperties = value;
|
||||
if (value == _mHiddenProperties) return;
|
||||
_mHiddenProperties = value;
|
||||
RefreshProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Overwrite the PropertyGrid.SelectedObject property.</summary>
|
||||
/// <summary>
|
||||
/// Overwrite the PropertyGrid.SelectedObject property.
|
||||
/// </summary>
|
||||
/// <remarks>The object passed to the base PropertyGrid is the wrapper.</remarks>
|
||||
public new object SelectedObject {
|
||||
get { return m_Wrapper != null ? ((ObjectWrapper)base.SelectedObject).SelectedObject : null; }
|
||||
get
|
||||
{
|
||||
return _mWrapper != null
|
||||
? ((ObjectWrapper)base.SelectedObject).SelectedObject
|
||||
: null;
|
||||
}
|
||||
set {
|
||||
// Set the new object to the wrapper and create one if necessary.
|
||||
if(m_Wrapper == null) {
|
||||
m_Wrapper = new ObjectWrapper(value);
|
||||
if(_mWrapper == null)
|
||||
{
|
||||
_mWrapper = new ObjectWrapper(value);
|
||||
RefreshProperties();
|
||||
}
|
||||
else if(m_Wrapper.SelectedObject != value) {
|
||||
var needrefresh = value.GetType() != m_Wrapper.SelectedObject.GetType();
|
||||
m_Wrapper.SelectedObject = value;
|
||||
if(needrefresh) RefreshProperties();
|
||||
else if(_mWrapper.SelectedObject != value)
|
||||
{
|
||||
var needrefresh = value.GetType() != _mWrapper.SelectedObject.GetType();
|
||||
_mWrapper.SelectedObject = value;
|
||||
if(needrefresh)
|
||||
RefreshProperties();
|
||||
}
|
||||
// Set the list of properties to the wrapper.
|
||||
m_Wrapper.PropertyDescriptors = m_PropertyDescriptors;
|
||||
_mWrapper.PropertyDescriptors = _propertyDescriptors;
|
||||
// Link the wrapper to the parent PropertyGrid.
|
||||
base.SelectedObject = m_Wrapper;
|
||||
base.SelectedObject = _mWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>Called when the browsable properties have changed.</summary>
|
||||
private void OnBrowsablePropertiesChanged() {
|
||||
if(m_Wrapper == null) return;
|
||||
}
|
||||
*/
|
||||
/// <summary>
|
||||
/// Build the list of the properties to be displayed in the PropertyGrid, following the filters defined the Browsable and Hidden properties.
|
||||
/// </summary>
|
||||
private void RefreshProperties()
|
||||
{
|
||||
if(_mWrapper == null)
|
||||
return;
|
||||
|
||||
/// <summary>Build the list of the properties to be displayed in the PropertyGrid, following the filters defined the Browsable and Hidden properties.</summary>
|
||||
private void RefreshProperties() {
|
||||
if(m_Wrapper == null) return;
|
||||
// Clear the list of properties to be displayed.
|
||||
m_PropertyDescriptors.Clear();
|
||||
_propertyDescriptors.Clear();
|
||||
// Check whether the list is filtered
|
||||
if(m_BrowsableAttributes != null && m_BrowsableAttributes.Count > 0) {
|
||||
if(_browsableAttributes != null && _browsableAttributes.Count > 0)
|
||||
{
|
||||
// Add to the list the attributes that need to be displayed.
|
||||
foreach(Attribute attribute in m_BrowsableAttributes) ShowAttribute(attribute);
|
||||
} else {
|
||||
// Fill the collection with all the properties.
|
||||
var originalpropertydescriptors = TypeDescriptor.GetProperties(m_Wrapper.SelectedObject);
|
||||
foreach(PropertyDescriptor propertydescriptor in originalpropertydescriptors) m_PropertyDescriptors.Add(propertydescriptor);
|
||||
// Remove from the list the attributes that mustn't be displayed.
|
||||
if(m_HiddenAttributes != null) foreach(Attribute attribute in m_HiddenAttributes) HideAttribute(attribute);
|
||||
foreach(Attribute attribute in _browsableAttributes)
|
||||
ShowAttribute(attribute);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fill the collection with all the properties.
|
||||
var originalPropertyDescriptors = TypeDescriptor
|
||||
.GetProperties(_mWrapper.SelectedObject)
|
||||
.OfType<PropertyDescriptor>()
|
||||
.Where(PropertyDoesntHaveBrowsableFalseAttribute);
|
||||
|
||||
foreach(PropertyDescriptor propertyDescriptor in originalPropertyDescriptors)
|
||||
_propertyDescriptors.Add(propertyDescriptor);
|
||||
|
||||
// Remove from the list the attributes that mustn't be displayed.
|
||||
if(_hiddenAttributes != null)
|
||||
foreach (Attribute attribute in _hiddenAttributes)
|
||||
HideAttribute(attribute);
|
||||
}
|
||||
|
||||
// Get all the properties of the SelectedObject
|
||||
var allproperties = TypeDescriptor.GetProperties(m_Wrapper.SelectedObject);
|
||||
// Hide if necessary, some properties
|
||||
if(m_HiddenProperties != null && m_HiddenProperties.Length > 0) {
|
||||
var allproperties = TypeDescriptor.GetProperties(_mWrapper.SelectedObject);
|
||||
|
||||
// Hide if necessary, some properties
|
||||
if(_mHiddenProperties != null && _mHiddenProperties.Length > 0)
|
||||
{
|
||||
// Remove from the list the properties that mustn't be displayed.
|
||||
foreach(var propertyname in m_HiddenProperties) {
|
||||
try {
|
||||
foreach(var propertyname in _mHiddenProperties)
|
||||
{
|
||||
try
|
||||
{
|
||||
var property = allproperties[propertyname];
|
||||
// Remove from the list the property
|
||||
HideProperty(property);
|
||||
} catch(Exception ex) {
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("FilteredPropertyGrid: Could not hide Property.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display if necessary, some properties
|
||||
if(m_BrowsableProperties != null && m_BrowsableProperties.Length > 0) {
|
||||
foreach(var propertyname in m_BrowsableProperties) {
|
||||
try {
|
||||
if(_mBrowsableProperties != null && _mBrowsableProperties.Length > 0)
|
||||
{
|
||||
foreach(var propertyname in _mBrowsableProperties)
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProperty(allproperties[propertyname]);
|
||||
} catch(Exception knfe) {
|
||||
Runtime.MessageCollector.AddExceptionMessage("FilteredPropertyGrid: Property not found", knfe);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("FilteredPropertyGrid: Property not found", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>Allows to hide a set of properties to the parent PropertyGrid.</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Predicate to determine if a property has a Browsable(false) attribute
|
||||
/// attatched to it. If so, it should not be shown.
|
||||
/// </summary>
|
||||
/// <param name="propertyDescriptor"></param>
|
||||
/// <returns></returns>
|
||||
private bool PropertyDoesntHaveBrowsableFalseAttribute(PropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
return !propertyDescriptor.Attributes.Contains(new BrowsableAttribute(false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows to hide a set of properties to the parent PropertyGrid.
|
||||
/// </summary>
|
||||
/// <param name="attribute">A set of attributes that filter the original collection of properties.</param>
|
||||
/// <remarks>For better performance, include the BrowsableAttribute with true value.</remarks>
|
||||
private void HideAttribute(Attribute attribute) {
|
||||
var filteredoriginalpropertydescriptors = TypeDescriptor.GetProperties(m_Wrapper.SelectedObject,new[] { attribute });
|
||||
if(filteredoriginalpropertydescriptors == null || filteredoriginalpropertydescriptors.Count == 0) throw new ArgumentException("Attribute not found",attribute.ToString());
|
||||
foreach(PropertyDescriptor propertydescriptor in filteredoriginalpropertydescriptors) HideProperty(propertydescriptor);
|
||||
private void HideAttribute(Attribute attribute)
|
||||
{
|
||||
var filteredoriginalpropertydescriptors = TypeDescriptor.GetProperties(_mWrapper.SelectedObject,new[] { attribute });
|
||||
if(filteredoriginalpropertydescriptors == null || filteredoriginalpropertydescriptors.Count == 0)
|
||||
throw new ArgumentException("Attribute not found", attribute.ToString());
|
||||
|
||||
foreach(PropertyDescriptor propertydescriptor in filteredoriginalpropertydescriptors)
|
||||
HideProperty(propertydescriptor);
|
||||
}
|
||||
/// <summary>Add all the properties that match an attribute to the list of properties to be displayed in the PropertyGrid.</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Add all the properties that match an attribute to the list of properties to be displayed in the PropertyGrid.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The attribute to be added.</param>
|
||||
private void ShowAttribute(Attribute attribute) {
|
||||
var filteredoriginalpropertydescriptors = TypeDescriptor.GetProperties(m_Wrapper.SelectedObject,new[] { attribute });
|
||||
if(filteredoriginalpropertydescriptors == null || filteredoriginalpropertydescriptors.Count == 0) throw new ArgumentException("Attribute not found",attribute.ToString());
|
||||
foreach(PropertyDescriptor propertydescriptor in filteredoriginalpropertydescriptors) ShowProperty(propertydescriptor);
|
||||
private void ShowAttribute(Attribute attribute)
|
||||
{
|
||||
var filteredoriginalpropertydescriptors = TypeDescriptor.GetProperties(_mWrapper.SelectedObject,new[] { attribute });
|
||||
if(filteredoriginalpropertydescriptors == null || filteredoriginalpropertydescriptors.Count == 0)
|
||||
throw new ArgumentException("Attribute not found", attribute.ToString());
|
||||
|
||||
foreach(PropertyDescriptor propertydescriptor in filteredoriginalpropertydescriptors)
|
||||
ShowProperty(propertydescriptor);
|
||||
}
|
||||
/// <summary>Add a property to the list of properties to be displayed in the PropertyGrid.</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Add a property to the list of properties to be displayed in the PropertyGrid.
|
||||
/// </summary>
|
||||
/// <param name="property">The property to be added.</param>
|
||||
private void ShowProperty(PropertyDescriptor property) {
|
||||
if(!m_PropertyDescriptors.Contains(property)) m_PropertyDescriptors.Add(property);
|
||||
private void ShowProperty(PropertyDescriptor property)
|
||||
{
|
||||
if(!_propertyDescriptors.Contains(property))
|
||||
_propertyDescriptors.Add(property);
|
||||
}
|
||||
/// <summary>Allows to hide a property to the parent PropertyGrid.</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Allows to hide a property to the parent PropertyGrid.
|
||||
/// </summary>
|
||||
/// <param name="property">The name of the property to be hidden.</param>
|
||||
private void HideProperty(PropertyDescriptor property) {
|
||||
if(m_PropertyDescriptors.Contains(property)) m_PropertyDescriptors.Remove(property);
|
||||
private void HideProperty(PropertyDescriptor property)
|
||||
{
|
||||
if(_propertyDescriptors.Contains(property))
|
||||
_propertyDescriptors.Remove(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,96 +4,119 @@ using System.ComponentModel;
|
||||
|
||||
namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
{
|
||||
/// <summary>This class is a wrapper. It contains the object the propertyGrid has to display.</summary>
|
||||
internal class ObjectWrapper : ICustomTypeDescriptor
|
||||
/// <summary>
|
||||
/// This class is a wrapper. It contains the object the PropertyGrid has to display.
|
||||
/// </summary>
|
||||
internal class ObjectWrapper : ICustomTypeDescriptor
|
||||
{
|
||||
/// <summary>Contain a reference to the selected objet that will linked to the parent PropertyGrid.</summary>
|
||||
private object m_SelectedObject;
|
||||
/// <summary>Contain a reference to the collection of properties to show in the parent PropertyGrid.</summary>
|
||||
/// <remarks>By default, m_PropertyDescriptors contain all the properties of the object. </remarks>
|
||||
List<PropertyDescriptor> m_PropertyDescriptors = new List<PropertyDescriptor>();
|
||||
|
||||
/// <summary>Simple constructor.</summary>
|
||||
/// <summary>
|
||||
/// Creates a new instance of an <see cref="ObjectWrapper"/> with the given object to be wrapped.
|
||||
/// </summary>
|
||||
/// <param name="obj">A reference to the selected object that will linked to the parent PropertyGrid.</param>
|
||||
internal ObjectWrapper(object obj) {
|
||||
m_SelectedObject = obj;
|
||||
internal ObjectWrapper(object obj)
|
||||
{
|
||||
SelectedObject = obj;
|
||||
}
|
||||
|
||||
/// <summary>Get or set a reference to the selected objet that will linked to the parent PropertyGrid.</summary>
|
||||
public object SelectedObject {
|
||||
get { return m_SelectedObject; }
|
||||
set { m_SelectedObject = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Get or set a reference to the selected objet that will linked to the parent PropertyGrid.
|
||||
/// </summary>
|
||||
public object SelectedObject { get; set; }
|
||||
|
||||
/// <summary>Get or set a reference to the collection of properties to show in the parent PropertyGrid.</summary>
|
||||
public List<PropertyDescriptor> PropertyDescriptors {
|
||||
get { return m_PropertyDescriptors; }
|
||||
set { m_PropertyDescriptors = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Get or set a reference to the collection of properties to show in the parent PropertyGrid
|
||||
/// </summary>
|
||||
public List<PropertyDescriptor> PropertyDescriptors { get; set; } = new List<PropertyDescriptor>();
|
||||
|
||||
#region ICustomTypeDescriptor Members
|
||||
public PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
|
||||
#region ICustomTypeDescriptor Members
|
||||
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
|
||||
{
|
||||
return GetProperties();
|
||||
}
|
||||
|
||||
public PropertyDescriptorCollection GetProperties() {
|
||||
return new PropertyDescriptorCollection(m_PropertyDescriptors.ToArray(),true);
|
||||
public PropertyDescriptorCollection GetProperties()
|
||||
{
|
||||
return new PropertyDescriptorCollection(PropertyDescriptors.ToArray(), true);
|
||||
}
|
||||
|
||||
/// <summary>GetAttributes.</summary>
|
||||
/// <summary>
|
||||
/// GetAttributes
|
||||
/// </summary>
|
||||
/// <returns>AttributeCollection</returns>
|
||||
public AttributeCollection GetAttributes() {
|
||||
return TypeDescriptor.GetAttributes(m_SelectedObject,true);
|
||||
}
|
||||
/// <summary>Get Class Name.</summary>
|
||||
/// <returns>String</returns>
|
||||
public String GetClassName() {
|
||||
return TypeDescriptor.GetClassName(m_SelectedObject,true);
|
||||
}
|
||||
/// <summary>GetComponentName.</summary>
|
||||
/// <returns>String</returns>
|
||||
public String GetComponentName() {
|
||||
return TypeDescriptor.GetComponentName(m_SelectedObject,true);
|
||||
public AttributeCollection GetAttributes()
|
||||
{
|
||||
return TypeDescriptor.GetAttributes(SelectedObject, true);
|
||||
}
|
||||
|
||||
/// <summary>GetConverter.</summary>
|
||||
/// <summary>
|
||||
/// Get Class Name
|
||||
/// </summary>
|
||||
/// <returns>String</returns>
|
||||
public string GetClassName()
|
||||
{
|
||||
return TypeDescriptor.GetClassName(SelectedObject, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetComponentName
|
||||
/// </summary>
|
||||
/// <returns>String</returns>
|
||||
public string GetComponentName()
|
||||
{
|
||||
return TypeDescriptor.GetComponentName(SelectedObject, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetConverter
|
||||
/// </summary>
|
||||
/// <returns>TypeConverter</returns>
|
||||
public TypeConverter GetConverter() {
|
||||
return TypeDescriptor.GetConverter(m_SelectedObject,true);
|
||||
public TypeConverter GetConverter()
|
||||
{
|
||||
return TypeDescriptor.GetConverter(SelectedObject, true);
|
||||
}
|
||||
|
||||
/// <summary>GetDefaultEvent.</summary>
|
||||
/// <summary>
|
||||
/// GetDefaultEvent
|
||||
/// </summary>
|
||||
/// <returns>EventDescriptor</returns>
|
||||
public EventDescriptor GetDefaultEvent() {
|
||||
return TypeDescriptor.GetDefaultEvent(m_SelectedObject,true);
|
||||
public EventDescriptor GetDefaultEvent()
|
||||
{
|
||||
return TypeDescriptor.GetDefaultEvent(SelectedObject, true);
|
||||
}
|
||||
|
||||
/// <summary>GetDefaultProperty.</summary>
|
||||
/// <summary>
|
||||
/// GetDefaultProperty
|
||||
/// </summary>
|
||||
/// <returns>PropertyDescriptor</returns>
|
||||
public PropertyDescriptor GetDefaultProperty() {
|
||||
return TypeDescriptor.GetDefaultProperty(m_SelectedObject,true);
|
||||
public PropertyDescriptor GetDefaultProperty()
|
||||
{
|
||||
return TypeDescriptor.GetDefaultProperty(SelectedObject, true);
|
||||
}
|
||||
|
||||
/// <summary>GetEditor.</summary>
|
||||
/// <summary>
|
||||
/// GetEditor
|
||||
/// </summary>
|
||||
/// <param name="editorBaseType">editorBaseType</param>
|
||||
/// <returns>object</returns>
|
||||
public object GetEditor(Type editorBaseType) {
|
||||
return TypeDescriptor.GetEditor(this,editorBaseType,true);
|
||||
public object GetEditor(Type editorBaseType)
|
||||
{
|
||||
return TypeDescriptor.GetEditor(this,editorBaseType, true);
|
||||
}
|
||||
|
||||
public EventDescriptorCollection GetEvents(Attribute[] attributes) {
|
||||
return TypeDescriptor.GetEvents(m_SelectedObject,attributes,true);
|
||||
public EventDescriptorCollection GetEvents(Attribute[] attributes)
|
||||
{
|
||||
return TypeDescriptor.GetEvents(SelectedObject, attributes, true);
|
||||
}
|
||||
|
||||
public EventDescriptorCollection GetEvents() {
|
||||
return TypeDescriptor.GetEvents(m_SelectedObject,true);
|
||||
public EventDescriptorCollection GetEvents()
|
||||
{
|
||||
return TypeDescriptor.GetEvents(SelectedObject, true);
|
||||
}
|
||||
|
||||
public object GetPropertyOwner(PropertyDescriptor pd) {
|
||||
return m_SelectedObject;
|
||||
public object GetPropertyOwner(PropertyDescriptor pd)
|
||||
{
|
||||
return SelectedObject;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,8 @@ namespace mRemoteNG.UI.Controls
|
||||
/** Sets and Gets the tooltiptext on toolTip1 */
|
||||
public string ToolTipText
|
||||
{
|
||||
get
|
||||
{ return toolTip1.GetToolTip(Octet1); }
|
||||
set
|
||||
get => toolTip1.GetToolTip(Octet1);
|
||||
set
|
||||
{
|
||||
toolTip1.SetToolTip(Octet1,value);
|
||||
toolTip1.SetToolTip(Octet2,value);
|
||||
@@ -46,12 +45,8 @@ namespace mRemoteNG.UI.Controls
|
||||
/** Set or Get the string that represents the value in the box */
|
||||
public override string Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return Octet1.Text + @"." + Octet2.Text + @"." + Octet3.Text + @"." + Octet4.Text;
|
||||
|
||||
}
|
||||
set
|
||||
get => Octet1.Text + @"." + Octet2.Text + @"." + Octet3.Text + @"." + Octet4.Text;
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
@@ -245,7 +240,7 @@ namespace mRemoteNG.UI.Controls
|
||||
if(theValue >=0 && theValue <= 255)
|
||||
return true;
|
||||
|
||||
MessageBox.Show("Must Be Between 0 and 255","Out Of Range");
|
||||
MessageBox.Show(Language.strIPRange,Language.strOutOfRange);
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -28,13 +28,13 @@ namespace mRemoteNG.UI.Forms.Input
|
||||
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
|
||||
textBox.SetBounds(12, 36, 372, 20);
|
||||
|
||||
buttonOk.Text = "OK";
|
||||
buttonOk.Text = Language.strButtonOK;
|
||||
buttonOk.DialogResult = DialogResult.OK;
|
||||
buttonOk.FlatStyle = FlatStyle.Flat;
|
||||
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
buttonOk.SetBounds(228, 72, 75, 23);
|
||||
|
||||
buttonCancel.Text = "Cancel";
|
||||
buttonCancel.Text = Language.strButtonCancel;
|
||||
buttonCancel.DialogResult = DialogResult.Cancel;
|
||||
buttonCancel.FlatStyle = FlatStyle.Flat;
|
||||
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class AdvancedPage : OptionsPage
|
||||
public sealed partial class AdvancedPage : OptionsPage
|
||||
{
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
[System.Diagnostics.DebuggerNonUserCode()]
|
||||
|
||||
@@ -9,19 +9,19 @@ using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class AdvancedPage
|
||||
public sealed partial class AdvancedPage
|
||||
{
|
||||
public AdvancedPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabAdvanced; }
|
||||
get => Language.strTabAdvanced;
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -108,16 +108,14 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
using (var openFileDialog = new OpenFileDialog())
|
||||
{
|
||||
openFileDialog.Filter = $"{Language.strFilterApplication}|*.exe|{Language.strFilterAll}|*.*";
|
||||
openFileDialog.Filter = $@"{Language.strFilterApplication}|*.exe|{Language.strFilterAll}|*.*";
|
||||
openFileDialog.FileName = Path.GetFileName(GeneralAppInfo.PuttyPath);
|
||||
openFileDialog.CheckFileExists = true;
|
||||
openFileDialog.Multiselect = false;
|
||||
|
||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
txtCustomPuttyPath.Text = openFileDialog.FileName;
|
||||
SetPuttyLaunchButtonEnabled();
|
||||
}
|
||||
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
|
||||
txtCustomPuttyPath.Text = openFileDialog.FileName;
|
||||
SetPuttyLaunchButtonEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class AppearancePage : OptionsPage
|
||||
public sealed partial class AppearancePage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -5,17 +5,17 @@ using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class AppearancePage
|
||||
public sealed partial class AppearancePage
|
||||
{
|
||||
public AppearancePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabAppearance; }
|
||||
get => Language.strTabAppearance;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class ConnectionsPage : OptionsPage
|
||||
public sealed partial class ConnectionsPage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -3,19 +3,19 @@ using mRemoteNG.Config;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class ConnectionsPage
|
||||
public sealed partial class ConnectionsPage
|
||||
{
|
||||
private FrmMain _frmMain = FrmMain.Default;
|
||||
private readonly FrmMain _frmMain = FrmMain.Default;
|
||||
|
||||
public ConnectionsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strConnections; }
|
||||
get => Language.strConnections;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
partial class CredentialsPage
|
||||
sealed partial class CredentialsPage
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
|
||||
@@ -4,16 +4,16 @@ using mRemoteNG.Security.SymmetricEncryption;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class CredentialsPage : OptionsPage
|
||||
public sealed partial class CredentialsPage : OptionsPage
|
||||
{
|
||||
public CredentialsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName {
|
||||
get { return Language.Credentials; }
|
||||
get => Language.Credentials;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class NotificationsPage : OptionsPage
|
||||
public sealed partial class NotificationsPage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -5,17 +5,17 @@ using mRemoteNG.App;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class NotificationsPage
|
||||
public sealed partial class NotificationsPage
|
||||
{
|
||||
public NotificationsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strMenuNotifications; }
|
||||
get => Language.strMenuNotifications;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -9,24 +9,17 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
protected OptionsPage()
|
||||
{
|
||||
//InitializeComponent();
|
||||
Themes.ThemeManager.getInstance().ThemeChanged += ApplyTheme;
|
||||
|
||||
Themes.ThemeManager.getInstance().ThemeChanged += ApplyTheme;
|
||||
}
|
||||
|
||||
#region Public Properties
|
||||
[Browsable(false)]public virtual string PageName {get; set;}
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Global
|
||||
[Browsable(false)]public virtual string PageName {get; set;}
|
||||
|
||||
public virtual Icon PageIcon {get; set;}
|
||||
public virtual Image IconImage{
|
||||
get
|
||||
{
|
||||
if (PageIcon != null)
|
||||
return PageIcon.ToBitmap();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public virtual Icon PageIcon {get; protected set;}
|
||||
public virtual Image IconImage => PageIcon?.ToBitmap();
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
public virtual void ApplyLanguage()
|
||||
@@ -50,26 +43,26 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
}
|
||||
#endregion
|
||||
|
||||
/*
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// OptionsPage
|
||||
//
|
||||
this.Name = "OptionsPage";
|
||||
this.Size = new System.Drawing.Size(610, 489);
|
||||
this.ResumeLayout(false);
|
||||
Name = "OptionsPage";
|
||||
Size = new Size(610, 489);
|
||||
ResumeLayout(false);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
public virtual void ApplyTheme()
|
||||
protected virtual void ApplyTheme()
|
||||
{
|
||||
if (Themes.ThemeManager.getInstance().ThemingActive)
|
||||
{
|
||||
BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
Invalidate();
|
||||
}
|
||||
if (!Themes.ThemeManager.getInstance().ThemingActive) return;
|
||||
BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
partial class SecurityPage
|
||||
sealed partial class SecurityPage
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
|
||||
@@ -4,20 +4,20 @@ using mRemoteNG.Security;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class SecurityPage : OptionsPage
|
||||
public sealed partial class SecurityPage : OptionsPage
|
||||
{
|
||||
public SecurityPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
PopulateEncryptionEngineDropDown();
|
||||
PopulateBlockCipherDropDown();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabSecurity; }
|
||||
get => Language.strTabSecurity;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class SqlServerPage : OptionsPage
|
||||
public sealed partial class SqlServerPage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -7,20 +7,20 @@ using mRemoteNG.Security.SymmetricEncryption;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class SqlServerPage
|
||||
public sealed partial class SqlServerPage
|
||||
{
|
||||
private readonly SqlDatabaseConnectionTester _databaseConnectionTester;
|
||||
|
||||
public SqlServerPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
_databaseConnectionTester = new SqlDatabaseConnectionTester();
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strSQLServer.TrimEnd(':'); }
|
||||
get => Language.strSQLServer.TrimEnd(':');
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class StartupExitPage : OptionsPage
|
||||
public sealed partial class StartupExitPage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -2,17 +2,17 @@ using System;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class StartupExitPage
|
||||
public sealed partial class StartupExitPage
|
||||
{
|
||||
public StartupExitPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strStartupExit; }
|
||||
get => Language.strStartupExit;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class TabsPanelsPage : OptionsPage
|
||||
public sealed partial class TabsPanelsPage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class TabsPanelsPage
|
||||
public sealed partial class TabsPanelsPage
|
||||
{
|
||||
public TabsPanelsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabsAndPanels.Replace("&&", "&"); }
|
||||
get => Language.strTabsAndPanels.Replace("&&", "&");
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
chkDoubleClickClosesTab.Text = Language.strDoubleClickTabClosesIt;
|
||||
chkAlwaysShowPanelSelectionDlg.Text = Language.strAlwaysShowPanelSelection;
|
||||
chkCreateEmptyPanelOnStart.Text = Language.strCreateEmptyPanelOnStartUp;
|
||||
lblPanelName.Text = $"{Language.strPanelName}:";
|
||||
lblPanelName.Text = $@"{Language.strPanelName}:";
|
||||
}
|
||||
|
||||
public override void LoadSettings()
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Themes;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using System.Collections.Generic;
|
||||
using BrightIdeasSoftware;
|
||||
|
||||
@@ -25,18 +23,16 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
InitializeComponent();
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
if (_themeManager.ThemingActive)
|
||||
{
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
_themeManager.ThemeChanged += ApplyTheme;
|
||||
_oriTheme = _themeManager.ActiveTheme;
|
||||
_oriActiveTheming = _themeManager.ThemingActive;
|
||||
}
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
_themeManager.ThemeChanged += ApplyTheme;
|
||||
_oriTheme = _themeManager.ActiveTheme;
|
||||
_oriActiveTheming = _themeManager.ThemingActive;
|
||||
}
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strOptionsTabTheme; }
|
||||
get => Language.strOptionsTabTheme;
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -65,6 +61,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
btnThemeDelete.Enabled = false;
|
||||
//Load the list of themes
|
||||
cboTheme.Items.Clear();
|
||||
// ReSharper disable once CoVariantArrayConversion
|
||||
cboTheme.Items.AddRange(_themeManager.LoadThemes().OrderBy(x => x.Name).ToArray());
|
||||
cboTheme.SelectedItem = _themeManager.ActiveTheme;
|
||||
cboTheme_SelectionChangeCommitted(this, new EventArgs());
|
||||
@@ -80,23 +77,23 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
themeEnableCombo.Checked = false;
|
||||
cboTheme.Enabled = false;
|
||||
// reset to the default theme when disabling theme support
|
||||
_themeManager.ActiveTheme = _themeManager.DefaultTheme;
|
||||
}
|
||||
}
|
||||
|
||||
private void ListPalette_FormatCell(object sender, FormatCellEventArgs e)
|
||||
{
|
||||
if (e.ColumnIndex == this.ColorCol.Index)
|
||||
{
|
||||
PseudoKeyColor colorElem = (PseudoKeyColor)e.Model;
|
||||
e.SubItem.BackColor = colorElem.Value;
|
||||
}
|
||||
if (e.ColumnIndex != ColorCol.Index) return;
|
||||
var colorElem = (PseudoKeyColor)e.Model;
|
||||
e.SubItem.BackColor = colorElem.Value;
|
||||
}
|
||||
|
||||
|
||||
public override void SaveSettings()
|
||||
{
|
||||
base.SaveSettings();
|
||||
foreach(ThemeInfo updatedTheme in modifiedThemes)
|
||||
foreach(var updatedTheme in modifiedThemes)
|
||||
{
|
||||
_themeManager.updateTheme(updatedTheme);
|
||||
}
|
||||
@@ -120,26 +117,18 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
btnThemeNew.Enabled = false;
|
||||
btnThemeDelete.Enabled = false;
|
||||
if (_themeManager.ThemingActive)
|
||||
{
|
||||
_themeManager.ActiveTheme = (ThemeInfo)cboTheme.SelectedItem;
|
||||
listPalette.ClearObjects();
|
||||
if (_themeManager.ActiveTheme.IsExtendable && _themeManager.ThemingActive)
|
||||
{
|
||||
btnThemeNew.Enabled = true;
|
||||
listPalette.ClearObjects();
|
||||
listPalette.Enabled = false;
|
||||
ColorMeList();
|
||||
if (!_themeManager.ActiveTheme.IsThemeBase)
|
||||
{
|
||||
listPalette.Enabled = true;
|
||||
btnThemeDelete.Enabled = true;
|
||||
listPalette.CellClick += ListPalette_CellClick;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
_themeManager.ActiveTheme = (ThemeInfo)cboTheme.SelectedItem;
|
||||
listPalette.ClearObjects();
|
||||
if (!_themeManager.ActiveTheme.IsExtendable || !_themeManager.ThemingActive) return;
|
||||
btnThemeNew.Enabled = true;
|
||||
listPalette.ClearObjects();
|
||||
listPalette.Enabled = false;
|
||||
ColorMeList();
|
||||
if (_themeManager.ActiveTheme.IsThemeBase) return;
|
||||
listPalette.Enabled = true;
|
||||
btnThemeDelete.Enabled = true;
|
||||
listPalette.CellClick += ListPalette_CellClick;
|
||||
}
|
||||
|
||||
|
||||
@@ -153,63 +142,59 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
private void ListPalette_CellClick(object sender, CellClickEventArgs e)
|
||||
{
|
||||
|
||||
PseudoKeyColor colorElem = (PseudoKeyColor)e.Model;
|
||||
var colorElem = (PseudoKeyColor)e.Model;
|
||||
|
||||
ColorDialog colorDlg = new ColorDialog();
|
||||
colorDlg.AllowFullOpen = true;
|
||||
colorDlg.FullOpen = true;
|
||||
colorDlg.AnyColor = true;
|
||||
colorDlg.SolidColorOnly = false;
|
||||
colorDlg.Color = colorElem.Value;
|
||||
|
||||
if (colorDlg.ShowDialog() == DialogResult.OK)
|
||||
var colorDlg = new ColorDialog
|
||||
{
|
||||
modifiedThemes.Add(_themeManager.ActiveTheme);
|
||||
_themeManager.ActiveTheme.ExtendedPalette.replaceColor(colorElem.Key, colorDlg.Color);
|
||||
colorElem.Value = colorDlg.Color;
|
||||
listPalette.RefreshObject(e.Model);
|
||||
_themeManager.refreshUI();
|
||||
}
|
||||
AllowFullOpen = true,
|
||||
FullOpen = true,
|
||||
AnyColor = true,
|
||||
SolidColorOnly = false,
|
||||
Color = colorElem.Value
|
||||
};
|
||||
|
||||
if (colorDlg.ShowDialog() != DialogResult.OK) return;
|
||||
modifiedThemes.Add(_themeManager.ActiveTheme);
|
||||
_themeManager.ActiveTheme.ExtendedPalette.replaceColor(colorElem.Key, colorDlg.Color);
|
||||
colorElem.Value = colorDlg.Color;
|
||||
listPalette.RefreshObject(e.Model);
|
||||
_themeManager.refreshUI();
|
||||
|
||||
}
|
||||
|
||||
private void ColorMeList()
|
||||
{
|
||||
foreach (KeyValuePair<string, Color> colorElem in _themeManager.ActiveTheme.ExtendedPalette.ExtColorPalette)
|
||||
foreach (var colorElem in _themeManager.ActiveTheme.ExtendedPalette.ExtColorPalette)
|
||||
listPalette.AddObject(new PseudoKeyColor(colorElem.Key, colorElem.Value));
|
||||
}
|
||||
|
||||
private void btnThemeNew_Click(object sender, EventArgs e)
|
||||
{
|
||||
String name = _themeManager.ActiveTheme.Name;
|
||||
DialogResult res = Input.input.InputBox(Language.strOptionsThemeNewThemeCaption, Language.strOptionsThemeNewThemeText, ref name);
|
||||
if (res == DialogResult.OK)
|
||||
var name = _themeManager.ActiveTheme.Name;
|
||||
var res = Input.input.InputBox(Language.strOptionsThemeNewThemeCaption, Language.strOptionsThemeNewThemeText, ref name);
|
||||
if (res != DialogResult.OK) return;
|
||||
if (_themeManager.isThemeNameOk(name))
|
||||
{
|
||||
if (_themeManager.isThemeNameOk(name))
|
||||
{
|
||||
ThemeInfo addedTheme = _themeManager.addTheme(_themeManager.ActiveTheme, name);
|
||||
_themeManager.ActiveTheme = addedTheme;
|
||||
LoadSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskDialog.CTaskDialog.ShowTaskDialogBox(this, Language.strErrors, Language.strOptionsThemeNewThemeError, "", "", "", "", "", "", TaskDialog.ETaskDialogButtons.Ok, TaskDialog.ESysIcons.Error, TaskDialog.ESysIcons.Information, 0);
|
||||
}
|
||||
var addedTheme = _themeManager.addTheme(_themeManager.ActiveTheme, name);
|
||||
_themeManager.ActiveTheme = addedTheme;
|
||||
LoadSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskDialog.CTaskDialog.ShowTaskDialogBox(this, Language.strErrors, Language.strOptionsThemeNewThemeError, "", "", "", "", "", "", TaskDialog.ETaskDialogButtons.Ok, TaskDialog.ESysIcons.Error, TaskDialog.ESysIcons.Information, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnThemeDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
DialogResult res = TaskDialog.CTaskDialog.ShowTaskDialogBox(this, Language.strWarnings , Language.strOptionsThemeDeleteConfirmation, "", "", "", "", "", "", TaskDialog.ETaskDialogButtons.YesNo, TaskDialog.ESysIcons.Question, TaskDialog.ESysIcons.Information, 0);
|
||||
var res = TaskDialog.CTaskDialog.ShowTaskDialogBox(this, Language.strWarnings , Language.strOptionsThemeDeleteConfirmation, "", "", "", "", "", "", TaskDialog.ETaskDialogButtons.YesNo, TaskDialog.ESysIcons.Question, TaskDialog.ESysIcons.Information, 0);
|
||||
|
||||
if (res == DialogResult.Yes)
|
||||
{
|
||||
if (modifiedThemes.Contains(_themeManager.ActiveTheme))
|
||||
modifiedThemes.Remove(_themeManager.ActiveTheme);
|
||||
_themeManager.deleteTheme(_themeManager.ActiveTheme);
|
||||
LoadSettings();
|
||||
}
|
||||
if (res != DialogResult.Yes) return;
|
||||
if (modifiedThemes.Contains(_themeManager.ActiveTheme))
|
||||
modifiedThemes.Remove(_themeManager.ActiveTheme);
|
||||
_themeManager.deleteTheme(_themeManager.ActiveTheme);
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
|
||||
public partial class UpdatesPage : OptionsPage
|
||||
public sealed partial class UpdatesPage : OptionsPage
|
||||
{
|
||||
|
||||
//UserControl overrides dispose to clean up the component list.
|
||||
|
||||
@@ -10,7 +10,7 @@ using mRemoteNG.UI.TaskDialog;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class UpdatesPage
|
||||
public sealed partial class UpdatesPage
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
@@ -21,14 +21,14 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
public UpdatesPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabUpdates; }
|
||||
get => Language.strTabUpdates;
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -11,15 +11,34 @@ namespace mRemoteNG.UI.Forms
|
||||
private readonly string _passwordName;
|
||||
private SecureString _password = new SecureString();
|
||||
|
||||
private bool Verify { get; }
|
||||
/// <summary>
|
||||
/// Puts the dialog into the New Password mode. An extra
|
||||
/// password box is shown which must match the first password
|
||||
/// to continue.
|
||||
/// </summary>
|
||||
private bool NewPasswordMode { get; }
|
||||
|
||||
public PasswordForm(string passwordName = null, bool verify = true)
|
||||
/// <summary>
|
||||
/// Creates a new password form for entering or setting a password.
|
||||
/// </summary>
|
||||
/// <param name="passwordName"></param>
|
||||
/// <param name="newPasswordMode">
|
||||
/// Puts the dialog into the New Password mode. An extra
|
||||
/// password box is shown which must match the first password
|
||||
/// to continue.
|
||||
/// </param>
|
||||
public PasswordForm(string passwordName = null, bool newPasswordMode = true)
|
||||
{
|
||||
InitializeComponent();
|
||||
_passwordName = passwordName;
|
||||
Verify = verify;
|
||||
NewPasswordMode = newPasswordMode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispaly a dialog box requesting that the user
|
||||
/// enter their password.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Optional<SecureString> GetKey()
|
||||
{
|
||||
var dialog = ShowDialog();
|
||||
@@ -33,7 +52,7 @@ namespace mRemoteNG.UI.Forms
|
||||
{
|
||||
ApplyLanguage();
|
||||
|
||||
if (Verify) return;
|
||||
if (NewPasswordMode) return;
|
||||
Height = Height - (txtVerify.Top - txtPassword.Top);
|
||||
lblVerify.Visible = false;
|
||||
txtVerify.Visible = false;
|
||||
@@ -44,7 +63,7 @@ namespace mRemoteNG.UI.Forms
|
||||
_password = txtPassword.Text.ConvertToSecureString();
|
||||
txtPassword.Text = "";
|
||||
txtVerify.Text = "";
|
||||
if (Verify) return;
|
||||
if (NewPasswordMode) return;
|
||||
Height = Height + (txtVerify.Top - txtPassword.Top);
|
||||
}
|
||||
|
||||
@@ -55,12 +74,12 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Verify && VerifyPassword())
|
||||
DialogResult = DialogResult.OK;
|
||||
else
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
{
|
||||
if (NewPasswordMode)
|
||||
VerifyNewPassword();
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void txtPassword_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
@@ -79,7 +98,7 @@ namespace mRemoteNG.UI.Forms
|
||||
btnOK.Text = Language.strButtonOK;
|
||||
}
|
||||
|
||||
private bool VerifyPassword()
|
||||
private bool VerifyNewPassword()
|
||||
{
|
||||
if (txtPassword.Text.Length >= 3)
|
||||
{
|
||||
|
||||
34
mRemoteV1/UI/Forms/frmChoosePanel.Designer.cs
generated
34
mRemoteV1/UI/Forms/frmChoosePanel.Designer.cs
generated
@@ -29,25 +29,26 @@ namespace mRemoteNG.UI.Forms
|
||||
//Do not modify it using the code editor.
|
||||
[System.Diagnostics.DebuggerStepThrough()]private void InitializeComponent()
|
||||
{
|
||||
this.cbPanels = new Controls.Base.NGComboBox();
|
||||
this.btnOK = new Controls.Base.NGButton();
|
||||
this.lblDescription = new Controls.Base.NGLabel();
|
||||
this.btnNew = new Controls.Base.NGButton();
|
||||
this.btnCancel = new Controls.Base.NGButton();
|
||||
this.cbPanels = new mRemoteNG.UI.Controls.Base.NGComboBox();
|
||||
this.btnOK = new mRemoteNG.UI.Controls.Base.NGButton();
|
||||
this.lblDescription = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.btnNew = new mRemoteNG.UI.Controls.Base.NGButton();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// cbPanels
|
||||
//
|
||||
this.cbPanels._mice = mRemoteNG.UI.Controls.Base.NGComboBox.MouseState.HOVER;
|
||||
this.cbPanels.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbPanels.FormattingEnabled = true;
|
||||
this.cbPanels.Location = new System.Drawing.Point(79, 42);
|
||||
this.cbPanels.Location = new System.Drawing.Point(12, 42);
|
||||
this.cbPanels.Name = "cbPanels";
|
||||
this.cbPanels.Size = new System.Drawing.Size(157, 21);
|
||||
this.cbPanels.Size = new System.Drawing.Size(224, 21);
|
||||
this.cbPanels.TabIndex = 10;
|
||||
//
|
||||
// btnOK
|
||||
//
|
||||
this.btnOK.Location = new System.Drawing.Point(92, 73);
|
||||
this.btnOK._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
|
||||
this.btnOK.Location = new System.Drawing.Point(167, 72);
|
||||
this.btnOK.Name = "btnOK";
|
||||
this.btnOK.Size = new System.Drawing.Size(69, 23);
|
||||
this.btnOK.TabIndex = 20;
|
||||
@@ -66,9 +67,10 @@ namespace mRemoteNG.UI.Forms
|
||||
//
|
||||
// btnNew
|
||||
//
|
||||
this.btnNew._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
|
||||
this.btnNew.Image = global::mRemoteNG.Resources.Panel_Add;
|
||||
this.btnNew.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.btnNew.Location = new System.Drawing.Point(10, 38);
|
||||
this.btnNew.Location = new System.Drawing.Point(101, 70);
|
||||
this.btnNew.Name = "btnNew";
|
||||
this.btnNew.Size = new System.Drawing.Size(60, 27);
|
||||
this.btnNew.TabIndex = 40;
|
||||
@@ -77,27 +79,14 @@ namespace mRemoteNG.UI.Forms
|
||||
this.btnNew.UseVisualStyleBackColor = true;
|
||||
this.btnNew.Click += new System.EventHandler(this.btnNew_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(167, 73);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(69, 23);
|
||||
this.btnCancel.TabIndex = 30;
|
||||
this.btnCancel.Text = global::mRemoteNG.Language.strButtonCancel;
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// frmChoosePanel
|
||||
//
|
||||
this.AcceptButton = this.btnOK;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(245, 107);
|
||||
this.Controls.Add(this.lblDescription);
|
||||
this.Controls.Add(this.btnNew);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.btnOK);
|
||||
this.Controls.Add(this.cbPanels);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
@@ -116,6 +105,5 @@ namespace mRemoteNG.UI.Forms
|
||||
internal Controls.Base.NGButton btnOK;
|
||||
internal Controls.Base.NGLabel lblDescription;
|
||||
internal Controls.Base.NGButton btnNew;
|
||||
internal Controls.Base.NGButton btnCancel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,21 +16,15 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
public string Panel
|
||||
{
|
||||
get
|
||||
{
|
||||
return cbPanels.SelectedItem.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
cbPanels.SelectedItem = value;
|
||||
}
|
||||
}
|
||||
get => cbPanels.SelectedItem.ToString();
|
||||
set => cbPanels.SelectedItem = value;
|
||||
}
|
||||
|
||||
private void frmChoosePanel_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
ApplyLanguage();
|
||||
|
||||
AddAvailablePanels();
|
||||
ApplyTheme();
|
||||
AddAvailablePanels();
|
||||
}
|
||||
|
||||
private void ApplyLanguage()
|
||||
@@ -38,15 +32,23 @@ namespace mRemoteNG.UI.Forms
|
||||
btnOK.Text = Language.strButtonOK;
|
||||
lblDescription.Text = Language.strLabelSelectPanel;
|
||||
btnNew.Text = Language.strButtonNew;
|
||||
btnCancel.Text = Language.strButtonCancel;
|
||||
Text = Language.strTitleSelectPanel;
|
||||
}
|
||||
|
||||
private void AddAvailablePanels()
|
||||
|
||||
private void ApplyTheme()
|
||||
{
|
||||
if (!Themes.ThemeManager.getInstance().ThemingActive) return;
|
||||
BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
lblDescription.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
lblDescription.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
|
||||
private void AddAvailablePanels()
|
||||
{
|
||||
cbPanels.Items.Clear();
|
||||
|
||||
for (int i = 0; i <= Runtime.WindowList.Count - 1; i++)
|
||||
for (var i = 0; i <= Runtime.WindowList.Count - 1; i++)
|
||||
{
|
||||
cbPanels.Items.Add(Runtime.WindowList[i].Text.Replace("&&", "&"));
|
||||
}
|
||||
@@ -67,24 +69,17 @@ namespace mRemoteNG.UI.Forms
|
||||
private void btnNew_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
var pnlName = Language.strNewPanel;
|
||||
|
||||
if (input.InputBox(Language.strNewPanel, Language.strPanelName + ":", ref pnlName) == DialogResult.OK && !string.IsNullOrEmpty(pnlName))
|
||||
{
|
||||
_panelAdder.AddPanel(pnlName);
|
||||
AddAvailablePanels();
|
||||
cbPanels.SelectedItem = pnlName;
|
||||
cbPanels.Focus();
|
||||
}
|
||||
|
||||
if (input.InputBox(Language.strNewPanel, Language.strPanelName + ":", ref pnlName) != DialogResult.OK || string.IsNullOrEmpty(pnlName)) return;
|
||||
_panelAdder.AddPanel(pnlName);
|
||||
AddAvailablePanels();
|
||||
cbPanels.SelectedItem = pnlName;
|
||||
cbPanels.Focus();
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
mRemoteV1/UI/Forms/frmMain.Designer.cs
generated
8
mRemoteV1/UI/Forms/frmMain.Designer.cs
generated
@@ -84,7 +84,7 @@ namespace mRemoteNG.UI.Forms
|
||||
this.fileMenu.ConnectionInitiator = null;
|
||||
this.fileMenu.Name = "mMenFile";
|
||||
this.fileMenu.Size = new System.Drawing.Size(37, 20);
|
||||
this.fileMenu.Text = "&File";
|
||||
this.fileMenu.Text = Language.strMenuFile;
|
||||
this.fileMenu.TreeWindow = null;
|
||||
this.fileMenu.DropDownOpening += new System.EventHandler(this.mainFileMenu1_DropDownOpening);
|
||||
//
|
||||
@@ -94,7 +94,7 @@ namespace mRemoteNG.UI.Forms
|
||||
this.viewMenu.MainForm = null;
|
||||
this.viewMenu.Name = "mMenView";
|
||||
this.viewMenu.Size = new System.Drawing.Size(44, 20);
|
||||
this.viewMenu.Text = "&View";
|
||||
this.viewMenu.Text = Language.strMenuView;
|
||||
this.viewMenu.TsExternalTools = null;
|
||||
this.viewMenu.TsMultiSsh = null;
|
||||
this.viewMenu.TsQuickConnect = null;
|
||||
@@ -106,13 +106,13 @@ namespace mRemoteNG.UI.Forms
|
||||
this.toolsMenu.MainForm = null;
|
||||
this.toolsMenu.Name = "mMenTools";
|
||||
this.toolsMenu.Size = new System.Drawing.Size(47, 20);
|
||||
this.toolsMenu.Text = "&Tools";
|
||||
this.toolsMenu.Text = Language.strMenuTools;
|
||||
//
|
||||
// helpMenu
|
||||
//
|
||||
this.helpMenu.Name = "mMenInfo";
|
||||
this.helpMenu.Size = new System.Drawing.Size(44, 20);
|
||||
this.helpMenu.Text = "&Help";
|
||||
this.helpMenu.Text = Language.strMenuHelp;
|
||||
this.helpMenu.TextDirection = System.Windows.Forms.ToolStripTextDirection.Horizontal;
|
||||
//
|
||||
// mMenSep3
|
||||
|
||||
@@ -75,8 +75,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public bool AreWeUsingSqlServerForSavingConnections
|
||||
{
|
||||
get { return _usingSqlServer; }
|
||||
set
|
||||
get => _usingSqlServer;
|
||||
set
|
||||
{
|
||||
if (_usingSqlServer == value)
|
||||
{
|
||||
@@ -89,8 +89,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public string ConnectionsFileName
|
||||
{
|
||||
get { return _connectionsFileName; }
|
||||
set
|
||||
get => _connectionsFileName;
|
||||
set
|
||||
{
|
||||
if (_connectionsFileName == value)
|
||||
{
|
||||
@@ -103,8 +103,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public bool ShowFullPathInTitle
|
||||
{
|
||||
get { return _showFullPathInTitle; }
|
||||
set
|
||||
get => _showFullPathInTitle;
|
||||
set
|
||||
{
|
||||
if (_showFullPathInTitle == value)
|
||||
{
|
||||
@@ -117,8 +117,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public ConnectionInfo SelectedConnection
|
||||
{
|
||||
get { return _selectedConnection; }
|
||||
set
|
||||
get => _selectedConnection;
|
||||
set
|
||||
{
|
||||
if (_selectedConnection == value)
|
||||
{
|
||||
@@ -139,12 +139,12 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
Startup.Instance.InitializeProgram(messageCollector);
|
||||
|
||||
SetMenuDependencies();
|
||||
|
||||
msMain.Location = Point.Empty;
|
||||
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip);
|
||||
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, msMain);
|
||||
settingsLoader.LoadSettings();
|
||||
|
||||
SetMenuDependencies();
|
||||
|
||||
var uiLoader = new DockPanelLayoutLoader(this, messageCollector);
|
||||
uiLoader.LoadPanelsFromXml();
|
||||
|
||||
@@ -249,24 +249,20 @@ namespace mRemoteNG.UI.Forms
|
||||
//Theming support
|
||||
private void SetSchema()
|
||||
{
|
||||
if (_themeManager.ThemingActive)
|
||||
{
|
||||
// Persist settings when rebuilding UI
|
||||
this.pnlDock.Theme = _themeManager.ActiveTheme.Theme;
|
||||
ApplyTheme();
|
||||
}
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
// Persist settings when rebuilding UI
|
||||
pnlDock.Theme = _themeManager.ActiveTheme.Theme;
|
||||
ApplyTheme();
|
||||
}
|
||||
private void ApplyTheme()
|
||||
{
|
||||
if(_themeManager.ThemingActive)
|
||||
{
|
||||
vsToolStripExtender.SetStyle(msMain, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_quickConnectToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_externalToolsToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_multiSshToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
tsContainer.TopToolStripPanel.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("CommandBarMenuDefault_Background");
|
||||
}
|
||||
}
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
vsToolStripExtender.SetStyle(msMain, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_quickConnectToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_externalToolsToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_multiSshToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
tsContainer.TopToolStripPanel.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("CommandBarMenuDefault_Background");
|
||||
}
|
||||
|
||||
private void frmMain_Shown(object sender, EventArgs e)
|
||||
{
|
||||
@@ -625,14 +621,8 @@ namespace mRemoteNG.UI.Forms
|
||||
public delegate void ClipboardchangeEventHandler();
|
||||
public static event ClipboardchangeEventHandler ClipboardChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
_clipboardChangedEvent = (ClipboardchangeEventHandler)Delegate.Combine(_clipboardChangedEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
_clipboardChangedEvent = (ClipboardchangeEventHandler)Delegate.Remove(_clipboardChangedEvent, value);
|
||||
}
|
||||
add => _clipboardChangedEvent = (ClipboardchangeEventHandler)Delegate.Combine(_clipboardChangedEvent, value);
|
||||
remove => _clipboardChangedEvent = (ClipboardchangeEventHandler)Delegate.Remove(_clipboardChangedEvent, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -40,16 +40,14 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
private void ApplyTheme()
|
||||
{
|
||||
if(Themes.ThemeManager.getInstance().ThemingActive)
|
||||
{
|
||||
BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
if (!Themes.ThemeManager.getInstance().ThemingActive) return;
|
||||
BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
|
||||
private void ApplyLanguage()
|
||||
{
|
||||
this.Text = Language.strOptionsPageTitle;
|
||||
Text = Language.strOptionsPageTitle;
|
||||
foreach (var optionPage in _pages.Values)
|
||||
{
|
||||
optionPage.ApplyLanguage();
|
||||
@@ -93,8 +91,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
private void SetInitiallyActivatedPage()
|
||||
{
|
||||
bool isSet = false;
|
||||
for (int i = 0; i < lstOptionPages.Items.Count; i++)
|
||||
var isSet = false;
|
||||
for (var i = 0; i < lstOptionPages.Items.Count; i++)
|
||||
{
|
||||
if (!lstOptionPages.Items[i].Text.Equals(_pageName)) continue;
|
||||
lstOptionPages.Items[i].Selected = true;
|
||||
@@ -118,7 +116,7 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
|
||||
|
||||
private void LstOptionPages_SelectedIndexChanged(object sender, System.EventArgs e)
|
||||
private void LstOptionPages_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
pnlMain.Controls.Clear();
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace mRemoteNG.UI.Menu
|
||||
_mMenFileDelete.Image = Resources.Delete;
|
||||
_mMenFileDelete.Name = "mMenFileDelete";
|
||||
_mMenFileDelete.Size = new System.Drawing.Size(281, 22);
|
||||
_mMenFileDelete.Text = "Delete...";
|
||||
_mMenFileDelete.Text = Language.strDelete;
|
||||
_mMenFileDelete.Click += mMenFileDelete_Click;
|
||||
//
|
||||
// mMenFileRename
|
||||
@@ -175,7 +175,7 @@ namespace mRemoteNG.UI.Menu
|
||||
_mMenFileRename.Image = Resources.Rename;
|
||||
_mMenFileRename.Name = "mMenFileRename";
|
||||
_mMenFileRename.Size = new System.Drawing.Size(281, 22);
|
||||
_mMenFileRename.Text = "Rename";
|
||||
_mMenFileRename.Text = Language.strRename;
|
||||
_mMenFileRename.Click += mMenFileRename_Click;
|
||||
//
|
||||
// mMenFileDuplicate
|
||||
@@ -183,7 +183,7 @@ namespace mRemoteNG.UI.Menu
|
||||
_mMenFileDuplicate.Image = Resources.page_copy;
|
||||
_mMenFileDuplicate.Name = "mMenFileDuplicate";
|
||||
_mMenFileDuplicate.Size = new System.Drawing.Size(281, 22);
|
||||
_mMenFileDuplicate.Text = "Duplicate";
|
||||
_mMenFileDuplicate.Text = Language.strDuplicate;
|
||||
_mMenFileDuplicate.Click += mMenFileDuplicate_Click;
|
||||
//
|
||||
// mMenFileSep4
|
||||
@@ -196,7 +196,7 @@ namespace mRemoteNG.UI.Menu
|
||||
_mMenReconnectAll.Image = Resources.Refresh;
|
||||
_mMenReconnectAll.Name = "mMenReconnectAll";
|
||||
_mMenReconnectAll.Size = new System.Drawing.Size(281, 22);
|
||||
_mMenReconnectAll.Text = "Reconnect All Connections";
|
||||
_mMenReconnectAll.Text = Language.strReconnectAllConnections;
|
||||
_mMenReconnectAll.Click += mMenReconnectAll_Click;
|
||||
//
|
||||
// mMenFileSep3
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace mRemoteNG.UI.Menu
|
||||
_mMenToolsUvncsc.Image = Resources.UVNC_SC;
|
||||
_mMenToolsUvncsc.Name = "mMenToolsUVNCSC";
|
||||
_mMenToolsUvncsc.Size = new System.Drawing.Size(184, 22);
|
||||
_mMenToolsUvncsc.Text = "UltraVNC SingleClick";
|
||||
_mMenToolsUvncsc.Text = Language.strUltraVNCSingleClick;
|
||||
_mMenToolsUvncsc.Visible = false;
|
||||
_mMenToolsUvncsc.Click += mMenToolsUVNCSC_Click;
|
||||
//
|
||||
|
||||
@@ -265,6 +265,11 @@ namespace mRemoteNG.UI.Window
|
||||
_btnShowInheritance.Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A list of properties being shown for the current object.
|
||||
/// </summary>
|
||||
public IEnumerable<string> VisibleObjectProperties => _pGrid.VisibleProperties;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@@ -1176,7 +1181,8 @@ namespace mRemoteNG.UI.Window
|
||||
strHide.Add("SoundQuality");
|
||||
break;
|
||||
case ProtocolType.HTTP:
|
||||
strHide.Add("CacheBitmaps");
|
||||
case ProtocolType.HTTPS:
|
||||
strHide.Add("CacheBitmaps");
|
||||
strHide.Add("Colors");
|
||||
strHide.Add("DisplayThemes");
|
||||
strHide.Add("DisplayWallpaper");
|
||||
@@ -1218,49 +1224,6 @@ namespace mRemoteNG.UI.Window
|
||||
strHide.Add("VNCSmartSizeMode");
|
||||
strHide.Add("VNCViewOnly");
|
||||
strHide.Add("SoundQuality");
|
||||
break;
|
||||
case ProtocolType.HTTPS:
|
||||
strHide.Add("CacheBitmaps");
|
||||
strHide.Add("Colors");
|
||||
strHide.Add("DisplayThemes");
|
||||
strHide.Add("DisplayWallpaper");
|
||||
strHide.Add("EnableFontSmoothing");
|
||||
strHide.Add("EnableDesktopComposition");
|
||||
strHide.Add("Domain");
|
||||
strHide.Add("ExtApp");
|
||||
strHide.Add("ICAEncryptionStrength");
|
||||
strHide.Add("PuttySession");
|
||||
strHide.Add("RDGatewayDomain");
|
||||
strHide.Add("RDGatewayHostname");
|
||||
strHide.Add("RDGatewayPassword");
|
||||
strHide.Add("RDGatewayUsageMethod");
|
||||
strHide.Add("RDGatewayUseConnectionCredentials");
|
||||
strHide.Add("RDGatewayUsername");
|
||||
strHide.Add("RDPAuthenticationLevel");
|
||||
strHide.Add("RDPMinutesToIdleTimeout");
|
||||
strHide.Add("RDPAlertIdleTimeout");
|
||||
strHide.Add("LoadBalanceInfo");
|
||||
strHide.Add("RedirectDiskDrives");
|
||||
strHide.Add("RedirectKeys");
|
||||
strHide.Add("RedirectPorts");
|
||||
strHide.Add("RedirectPrinters");
|
||||
strHide.Add("RedirectSmartCards");
|
||||
strHide.Add("RedirectSound;Resolution");
|
||||
strHide.Add("AutomaticResize");
|
||||
strHide.Add("UseConsoleSession");
|
||||
strHide.Add("UseCredSsp");
|
||||
strHide.Add("VNCAuthMode");
|
||||
strHide.Add("VNCColors");
|
||||
strHide.Add("VNCCompression");
|
||||
strHide.Add("VNCEncoding");
|
||||
strHide.Add("VNCProxyIP");
|
||||
strHide.Add("VNCProxyPassword");
|
||||
strHide.Add("VNCProxyPort");
|
||||
strHide.Add("VNCProxyType");
|
||||
strHide.Add("VNCProxyUsername");
|
||||
strHide.Add("VNCSmartSizeMode");
|
||||
strHide.Add("VNCViewOnly");
|
||||
strHide.Add("SoundQuality");
|
||||
break;
|
||||
case ProtocolType.ICA:
|
||||
strHide.Add("DisplayThemes");
|
||||
|
||||
@@ -2,12 +2,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Themes;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
// ReSharper disable ArrangeAccessorOwnerBody
|
||||
@@ -19,7 +21,6 @@ namespace mRemoteNG.UI.Window
|
||||
private readonly ConnectionContextMenu _contextMenu;
|
||||
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
|
||||
private ThemeManager _themeManager;
|
||||
private readonly ConnectionTreeSearchTextFilter _connectionTreeSearchTextFilter = new ConnectionTreeSearchTextFilter();
|
||||
|
||||
public ConnectionInfo SelectedNode => olvConnections.SelectedNode;
|
||||
|
||||
@@ -43,7 +44,6 @@ namespace mRemoteNG.UI.Window
|
||||
SetMenuEventHandlers();
|
||||
SetConnectionTreeEventHandlers();
|
||||
Settings.Default.PropertyChanged += OnAppSettingsChanged;
|
||||
olvConnections.ModelFilter = _connectionTreeSearchTextFilter;
|
||||
}
|
||||
|
||||
private void OnAppSettingsChanged(object o, PropertyChangedEventArgs propertyChangedEventArgs)
|
||||
@@ -159,6 +159,8 @@ namespace mRemoteNG.UI.Window
|
||||
private void ConnectionsServiceOnConnectionsLoaded(object o, ConnectionsLoadedEventArgs connectionsLoadedEventArgs)
|
||||
{
|
||||
olvConnections.ConnectionTreeModel = connectionsLoadedEventArgs.NewConnectionTreeModel;
|
||||
olvConnections.SelectedObject = connectionsLoadedEventArgs.NewConnectionTreeModel.RootNodes
|
||||
.OfType<RootNodeInfo>().FirstOrDefault();
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -243,13 +245,10 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
if (txtSearch.Text == "" || txtSearch.Text == Language.strSearchPrompt)
|
||||
{
|
||||
olvConnections.UseFiltering = false;
|
||||
olvConnections.ResetColumnFiltering();
|
||||
olvConnections.RemoveFilter();
|
||||
return;
|
||||
}
|
||||
olvConnections.UseFiltering = true;
|
||||
_connectionTreeSearchTextFilter.FilterText = txtSearch.Text;
|
||||
olvConnections.ModelFilter = _connectionTreeSearchTextFilter;
|
||||
olvConnections.ApplyFilter(txtSearch.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
using System.Text;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
@@ -14,7 +15,7 @@ namespace mRemoteNG.UI.Window
|
||||
public partial class ErrorAndInfoWindow : BaseWindow
|
||||
{
|
||||
private ControlLayout _layout = ControlLayout.Vertical;
|
||||
private ThemeManager _themeManager;
|
||||
private readonly ThemeManager _themeManager;
|
||||
|
||||
public DockContent PreviousActiveForm { get; set; }
|
||||
|
||||
@@ -53,11 +54,9 @@ namespace mRemoteNG.UI.Window
|
||||
#region Private Methods
|
||||
private new void ApplyTheme()
|
||||
{
|
||||
if(_themeManager.ThemingActive)
|
||||
{
|
||||
lvErrorCollector.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background");
|
||||
lvErrorCollector.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground");
|
||||
}
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
lvErrorCollector.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background");
|
||||
lvErrorCollector.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground");
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +223,7 @@ namespace mRemoteNG.UI.Window
|
||||
break;
|
||||
}
|
||||
|
||||
lblMsgDate.Text = eMsg.Date.ToString();
|
||||
lblMsgDate.Text = eMsg.Date.ToString(CultureInfo.InvariantCulture);
|
||||
txtMsgText.Text = eMsg.Text;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -291,7 +290,7 @@ namespace mRemoteNG.UI.Window
|
||||
}
|
||||
|
||||
stringBuilder.AppendLine(message.Class.ToString());
|
||||
stringBuilder.AppendLine(message.Date.ToString());
|
||||
stringBuilder.AppendLine(message.Date.ToString(CultureInfo.InvariantCulture));
|
||||
stringBuilder.AppendLine(message.Text);
|
||||
stringBuilder.AppendLine("----------");
|
||||
}
|
||||
@@ -339,8 +338,8 @@ namespace mRemoteNG.UI.Window
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public enum ControlLayout
|
||||
|
||||
private enum ControlLayout
|
||||
{
|
||||
Vertical = 0,
|
||||
Horizontal = 1
|
||||
|
||||
28
mRemoteV1/UI/Window/UpdateWindow.Designer.cs
generated
28
mRemoteV1/UI/Window/UpdateWindow.Designer.cs
generated
@@ -20,17 +20,17 @@ namespace mRemoteNG.UI.Window
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.btnCheckForUpdate = new Controls.Base.NGButton();
|
||||
this.btnCheckForUpdate = new mRemoteNG.UI.Controls.Base.NGButton();
|
||||
this.pnlUpdate = new System.Windows.Forms.Panel();
|
||||
this.lblChangeLogLabel = new Controls.Base.NGLabel();
|
||||
this.btnDownload = new Controls.Base.NGButton();
|
||||
this.prgbDownload = new Controls.Base.NGProgressBar();
|
||||
this.txtChangeLog = new Controls.Base.NGTextBox();
|
||||
this.lblStatus = new Controls.Base.NGLabel();
|
||||
this.lblLatestVersionLabel = new Controls.Base.NGLabel();
|
||||
this.lblInstalledVersionLabel = new Controls.Base.NGLabel();
|
||||
this.lblLatestVersion = new Controls.Base.NGLabel();
|
||||
this.lblInstalledVersion = new Controls.Base.NGLabel();
|
||||
this.lblChangeLogLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.btnDownload = new mRemoteNG.UI.Controls.Base.NGButton();
|
||||
this.prgbDownload = new mRemoteNG.UI.Controls.Base.NGProgressBar();
|
||||
this.txtChangeLog = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
this.lblStatus = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblLatestVersionLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblInstalledVersionLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblLatestVersion = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblInstalledVersion = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.pbUpdateImage = new System.Windows.Forms.PictureBox();
|
||||
this.pnlUpdate.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pbUpdateImage)).BeginInit();
|
||||
@@ -38,6 +38,7 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// btnCheckForUpdate
|
||||
//
|
||||
this.btnCheckForUpdate._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
|
||||
this.btnCheckForUpdate.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnCheckForUpdate.Location = new System.Drawing.Point(16, 104);
|
||||
this.btnCheckForUpdate.Name = "btnCheckForUpdate";
|
||||
@@ -74,11 +75,12 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// btnDownload
|
||||
//
|
||||
this.btnDownload._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
|
||||
this.btnDownload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnDownload.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnDownload.Location = new System.Drawing.Point(0, 216);
|
||||
this.btnDownload.Name = "btnDownload";
|
||||
this.btnDownload.Size = new System.Drawing.Size(144, 32);
|
||||
this.btnDownload.Size = new System.Drawing.Size(224, 32);
|
||||
this.btnDownload.TabIndex = 2;
|
||||
this.btnDownload.Text = "Download and Install";
|
||||
this.btnDownload.UseVisualStyleBackColor = true;
|
||||
@@ -88,9 +90,9 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
this.prgbDownload.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.prgbDownload.Location = new System.Drawing.Point(160, 224);
|
||||
this.prgbDownload.Location = new System.Drawing.Point(230, 224);
|
||||
this.prgbDownload.Name = "prgbDownload";
|
||||
this.prgbDownload.Size = new System.Drawing.Size(542, 23);
|
||||
this.prgbDownload.Size = new System.Drawing.Size(472, 23);
|
||||
this.prgbDownload.TabIndex = 3;
|
||||
this.prgbDownload.Visible = false;
|
||||
//
|
||||
|
||||
@@ -666,7 +666,7 @@
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="ConDefaultPanel" serializeAs="String">
|
||||
<value />
|
||||
<value>General</value>
|
||||
</setting>
|
||||
<setting name="SaveConnectionsAfterEveryEdit" serializeAs="String">
|
||||
<value>True</value>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<OptionStrict>Off</OptionStrict>
|
||||
<ManifestCertificateThumbprint>B249710A6BB08171F8E75082CF2355AE2890911A</ManifestCertificateThumbprint>
|
||||
<ManifestKeyFile>mRemoteV1_TemporaryKey.pfx</ManifestKeyFile>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
<SignManifests>false</SignManifests>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
@@ -41,7 +41,7 @@
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>1</ApplicationRevision>
|
||||
<ApplicationVersion>1.64.0.%2a</ApplicationVersion>
|
||||
<ApplicationVersion>1.64.0.1</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
@@ -1561,24 +1561,26 @@ powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_mremo
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<NoWarn>1591,660,661</NoWarn>
|
||||
<DebugType>none</DebugType>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>1</WarningLevel>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release Portable|x86'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>bin\Release Portable\</OutputPath>
|
||||
<DefineConstants>PORTABLE</DefineConstants>
|
||||
<NoWarn>1591,660,661</NoWarn>
|
||||
<DebugType>none</DebugType>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
@@ -1597,6 +1599,9 @@ powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_mremo
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
Reference in New Issue
Block a user