mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Merge branch 'develop' into remove_statics
# Conflicts: # mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs # mRemoteV1/App/Windows.cs # mRemoteV1/Config/Settings/SettingsLoader.cs # mRemoteV1/Messages/WriterDecorators/MessageFocusDecorator.cs # mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs # mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.cs # mRemoteV1/UI/Forms/OptionsPages/CredentialsPage.cs # mRemoteV1/UI/Forms/OptionsPages/TabsPanelsPage.cs # mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs # mRemoteV1/UI/Forms/frmChoosePanel.cs # mRemoteV1/UI/Forms/frmMain.cs # mRemoteV1/UI/Window/ConfigWindow.cs # mRemoteV1/UI/Window/ConnectionTreeWindow.cs # mRemoteV1/UI/Window/ErrorAndInfoWindow.cs
This commit is contained in:
@@ -1,7 +1,39 @@
|
||||
1.76.5 (2018-xx-xx):
|
||||
1.76.8 (2018-xx-xx):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1088: Delete and Launch buttons are not disabled when last external tool deleted
|
||||
#1087: 'Save connections after every edit' setting not honored
|
||||
|
||||
|
||||
1.76.7 (2018-08-22):
|
||||
|
||||
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
|
||||
@@ -10,7 +42,11 @@ Fixes:
|
||||
#999: Some hotkeys stop working if File menu was called when PuTTy Saved Sessions was selected
|
||||
#998: Can sometimes add connection under PuTTY Sessions node
|
||||
#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 ""
|
||||
@@ -46,6 +46,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()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Config.Putty;
|
||||
@@ -40,7 +41,6 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
public void Teardown()
|
||||
{
|
||||
_serializer = null;
|
||||
_deserializer = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -92,6 +92,20 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GuidCreatedIfNonExistedInXml()
|
||||
{
|
||||
var originalConnectionInfo = new ConnectionInfo { Name = "con1" };
|
||||
var serializedContent = _serializer.Serialize(originalConnectionInfo);
|
||||
|
||||
// remove GUID from connection xml
|
||||
serializedContent = serializedContent.Replace(originalConnectionInfo.ConstantID, "");
|
||||
|
||||
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
||||
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
|
||||
Assert.That(Guid.TryParse(deserializedConnectionInfo.ConstantID, out var guid));
|
||||
}
|
||||
|
||||
|
||||
private ConnectionTreeModel SetupConnectionTreeModel()
|
||||
{
|
||||
@@ -128,4 +142,4 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
return connectionTreeModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
50
mRemoteNGTests/Tools/Registry/WindowsRegistryTests.cs
Normal file
50
mRemoteNGTests/Tools/Registry/WindowsRegistryTests.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry
|
||||
{
|
||||
public class WindowsRegistryTests
|
||||
{
|
||||
private WindowsRegistry _registry;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_registry = new WindowsRegistry();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetSubkeyNames()
|
||||
{
|
||||
var subKeyNames = _registry.GetSubKeyNames(RegistryHive.CurrentUser, "Software");
|
||||
Assert.That(subKeyNames, Does.Contain("Microsoft"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSubkeyNamesThrowsIfGivenNullKeyPath()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _registry.GetSubKeyNames(RegistryHive.CurrentUser, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetKeyValue()
|
||||
{
|
||||
var keyValue = _registry.GetKeyValue(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
|
||||
Assert.That(keyValue.FirstOrDefault(), Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetKeyValueThrowsIfGivenNullKeyPath()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _registry.GetKeyValue(RegistryHive.CurrentUser, null, ""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetKeyValueThrowsIfGivenNullPropertyName()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _registry.GetKeyValue(RegistryHive.CurrentUser, "", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,226 @@
|
||||
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 NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public class ConfigWindowGeneralTests
|
||||
{
|
||||
private ConfigWindow _configWindow;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_configWindow = new ConfigWindow(new DockContent(), Substitute.For<IConnectionsService>())
|
||||
{
|
||||
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,39 @@
|
||||
using System.Collections.Generic;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.UI.Window;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
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(new DockContent(), Substitute.For<IConnectionsService>())
|
||||
{
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,6 +179,7 @@
|
||||
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
|
||||
<Compile Include="Tools\FullyObservableCollectionTests.cs" />
|
||||
<Compile Include="Tools\OptionalTests.cs" />
|
||||
<Compile Include="Tools\Registry\WindowsRegistryTests.cs" />
|
||||
<Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" />
|
||||
<Compile Include="Tree\ConnectionTreeModelTests.cs" />
|
||||
@@ -235,6 +236,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>
|
||||
|
||||
@@ -82,12 +82,12 @@ namespace mRemoteNG.App
|
||||
case WindowType.About:
|
||||
if (_aboutForm == null || _aboutForm.IsDisposed)
|
||||
_aboutForm = new AboutWindow();
|
||||
_aboutForm.Show(_frmMain);
|
||||
_aboutForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.ActiveDirectoryImport:
|
||||
if (_adimportForm == null || _adimportForm.IsDisposed)
|
||||
_adimportForm = _activeDirectoryImportWindowBuilder();
|
||||
_adimportForm.Show(_frmMain);
|
||||
_adimportForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.Options:
|
||||
using (var optionsForm = new frmOptions(_connectionInitiator, Show, _notificationAreaIconBuilder, _connectionsService, _appUpdater, _databaseConnectorFactory, _frmMain))
|
||||
@@ -98,37 +98,37 @@ namespace mRemoteNG.App
|
||||
case WindowType.SSHTransfer:
|
||||
if (SshtransferForm == null || SshtransferForm.IsDisposed)
|
||||
SshtransferForm = new SSHTransferWindow(_frmMain);
|
||||
SshtransferForm.Show(_frmMain);
|
||||
SshtransferForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.Update:
|
||||
if (_updateForm == null || _updateForm.IsDisposed)
|
||||
_updateForm = _updateWindowBuilder();
|
||||
_updateForm.Show(_frmMain);
|
||||
_updateForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.Help:
|
||||
if (_helpForm == null || _helpForm.IsDisposed)
|
||||
_helpForm = new HelpWindow();
|
||||
_helpForm.Show(_frmMain);
|
||||
_helpForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.ExternalApps:
|
||||
if (_externalappsForm == null || _externalappsForm.IsDisposed)
|
||||
_externalappsForm = _externalToolsWindowBuilder();
|
||||
_externalappsForm.Show(_frmMain);
|
||||
_externalappsForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.PortScan:
|
||||
_portscanForm = _portScanWindowBuilder();
|
||||
_portscanForm.Show(_frmMain);
|
||||
_portscanForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.UltraVNCSC:
|
||||
if (_ultravncscForm == null || _ultravncscForm.IsDisposed)
|
||||
_ultravncscForm = new UltraVNCWindow(Show);
|
||||
_ultravncscForm.Show(_frmMain);
|
||||
_ultravncscForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
case WindowType.ComponentsCheck:
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Showing ComponentsCheck window", true);
|
||||
if (_componentscheckForm == null || _componentscheckForm.IsDisposed)
|
||||
_componentscheckForm = new ComponentsCheckWindow();
|
||||
_componentscheckForm.Show(_frmMain);
|
||||
_componentscheckForm.Show(_frmMain.pnlDock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -138,4 +138,4 @@ namespace mRemoteNG.App
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -209,7 +209,9 @@ namespace mRemoteNG.Config.Serializers.Xml
|
||||
{
|
||||
if (xmlnode.Attributes == null) return null;
|
||||
|
||||
var connectionId = xmlnode.Attributes["Id"]?.Value ?? Guid.NewGuid().ToString();
|
||||
var connectionId = xmlnode.Attributes["Id"]?.Value;
|
||||
if (string.IsNullOrWhiteSpace(connectionId))
|
||||
connectionId = Guid.NewGuid().ToString();
|
||||
var connectionInfo = new ConnectionInfo(connectionId);
|
||||
|
||||
try
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Configuration;
|
||||
#if !PORTABLE
|
||||
using System.Configuration;
|
||||
#endif
|
||||
|
||||
namespace mRemoteNG.Config.Settings.Providers
|
||||
{
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
/// The MIT License (MIT)
|
||||
///
|
||||
/// Copyright(c) crdx
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining
|
||||
/// a copy of this software and associated documentation files (the
|
||||
/// "Software"), to deal in the Software without restriction, including
|
||||
/// without limitation the rights to use, copy, modify, merge, publish,
|
||||
/// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
/// permit persons to whom the Software is furnished to do so, subject to
|
||||
/// the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be
|
||||
/// included in all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
/// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
/// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
/// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
/// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///
|
||||
/// https://raw.githubusercontent.com/crdx/PortableSettingsProvider
|
||||
///
|
||||
using System.Linq;
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright(c) crdx
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// https://raw.githubusercontent.com/crdx/PortableSettingsProvider
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Windows.Forms;
|
||||
using System.Collections.Specialized;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
//using mRemoteNG.App;
|
||||
|
||||
namespace mRemoteNG.Config.Settings.Providers
|
||||
{
|
||||
@@ -43,63 +43,34 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
private const string _className = "PortableSettingsProvider";
|
||||
private XmlDocument _xmlDocument;
|
||||
|
||||
private string _filePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),
|
||||
string.Format("{0}.settings", ApplicationName));
|
||||
}
|
||||
}
|
||||
private string _filePath => Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? throw new InvalidOperationException(), $"{ApplicationName}.settings");
|
||||
|
||||
private XmlNode _localSettingsNode
|
||||
{
|
||||
get
|
||||
{
|
||||
XmlNode settingsNode = GetSettingsNode(_localSettingsNodeName);
|
||||
XmlNode machineNode = settingsNode.SelectSingleNode(Environment.MachineName.ToLowerInvariant());
|
||||
private XmlNode _localSettingsNode => GetSettingsNode(_localSettingsNodeName);
|
||||
|
||||
if (machineNode == null)
|
||||
{
|
||||
machineNode = _rootDocument.CreateElement(Environment.MachineName.ToLowerInvariant());
|
||||
settingsNode.AppendChild(machineNode);
|
||||
}
|
||||
private XmlNode _globalSettingsNode => GetSettingsNode(_globalSettingsNodeName);
|
||||
|
||||
return machineNode;
|
||||
}
|
||||
}
|
||||
|
||||
private XmlNode _globalSettingsNode
|
||||
{
|
||||
get { return GetSettingsNode(_globalSettingsNodeName); }
|
||||
}
|
||||
|
||||
private XmlNode _rootNode
|
||||
{
|
||||
get { return _rootDocument.SelectSingleNode(_rootNodeName); }
|
||||
}
|
||||
private XmlNode _rootNode => _rootDocument.SelectSingleNode(_rootNodeName);
|
||||
|
||||
private XmlDocument _rootDocument
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_xmlDocument == null)
|
||||
if (_xmlDocument != null) return _xmlDocument;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
_xmlDocument = new XmlDocument();
|
||||
_xmlDocument.Load(_filePath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (_xmlDocument.SelectSingleNode(_rootNodeName) != null)
|
||||
return _xmlDocument;
|
||||
|
||||
_xmlDocument = GetBlankXmlDocument();
|
||||
_xmlDocument = new XmlDocument();
|
||||
_xmlDocument.Load(_filePath);
|
||||
}
|
||||
catch (Exception /*ex*/)
|
||||
{
|
||||
// This casues hundreds of unit tests to fail for some reason...
|
||||
//Runtime.MessageCollector.AddExceptionStackTrace("PortableSettingsProvider: Error getting XML", ex);
|
||||
}
|
||||
|
||||
if (_xmlDocument?.SelectSingleNode(_rootNodeName) != null)
|
||||
return _xmlDocument;
|
||||
|
||||
_xmlDocument = GetBlankXmlDocument();
|
||||
|
||||
return _xmlDocument;
|
||||
}
|
||||
@@ -107,14 +78,11 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
|
||||
public override string ApplicationName
|
||||
{
|
||||
get { return Path.GetFileNameWithoutExtension(Application.ExecutablePath); }
|
||||
get => Path.GetFileNameWithoutExtension(Application.ExecutablePath);
|
||||
set { }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return _className; }
|
||||
}
|
||||
public override string Name => _className;
|
||||
|
||||
public override void Initialize(string name, NameValueCollection config)
|
||||
{
|
||||
@@ -143,7 +111,7 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
|
||||
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
|
||||
{
|
||||
SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
|
||||
var values = new SettingsPropertyValueCollection();
|
||||
|
||||
foreach (SettingsProperty property in collection)
|
||||
{
|
||||
@@ -158,11 +126,9 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
|
||||
private void SetValue(SettingsPropertyValue propertyValue)
|
||||
{
|
||||
XmlNode targetNode = IsGlobal(propertyValue.Property)
|
||||
? _globalSettingsNode
|
||||
: _localSettingsNode;
|
||||
var targetNode = IsGlobal(propertyValue.Property) ? _globalSettingsNode : _localSettingsNode;
|
||||
|
||||
XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", propertyValue.Name));
|
||||
var settingNode = targetNode.SelectSingleNode($"setting[@name='{propertyValue.Name}']");
|
||||
|
||||
if (settingNode != null)
|
||||
settingNode.InnerText = propertyValue.SerializedValue.ToString();
|
||||
@@ -170,10 +136,10 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
{
|
||||
settingNode = _rootDocument.CreateElement("setting");
|
||||
|
||||
XmlAttribute nameAttribute = _rootDocument.CreateAttribute("name");
|
||||
var nameAttribute = _rootDocument.CreateAttribute("name");
|
||||
nameAttribute.Value = propertyValue.Name;
|
||||
|
||||
settingNode.Attributes.Append(nameAttribute);
|
||||
settingNode.Attributes?.Append(nameAttribute);
|
||||
settingNode.InnerText = propertyValue.SerializedValue.ToString();
|
||||
|
||||
targetNode.AppendChild(settingNode);
|
||||
@@ -182,8 +148,8 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
|
||||
private string GetValue(SettingsProperty property)
|
||||
{
|
||||
XmlNode targetNode = IsGlobal(property) ? _globalSettingsNode : _localSettingsNode;
|
||||
XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", property.Name));
|
||||
var targetNode = IsGlobal(property) ? _globalSettingsNode : _localSettingsNode;
|
||||
var settingNode = targetNode.SelectSingleNode($"setting[@name='{property.Name}']");
|
||||
|
||||
if (settingNode == null)
|
||||
return property.DefaultValue != null ? property.DefaultValue.ToString() : string.Empty;
|
||||
@@ -191,7 +157,7 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
return settingNode.InnerText;
|
||||
}
|
||||
|
||||
private bool IsGlobal(SettingsProperty property)
|
||||
private static bool IsGlobal(SettingsProperty property)
|
||||
{
|
||||
foreach (DictionaryEntry attribute in property.Attributes)
|
||||
{
|
||||
@@ -204,20 +170,18 @@ namespace mRemoteNG.Config.Settings.Providers
|
||||
|
||||
private XmlNode GetSettingsNode(string name)
|
||||
{
|
||||
XmlNode settingsNode = _rootNode.SelectSingleNode(name);
|
||||
var settingsNode = _rootNode.SelectSingleNode(name);
|
||||
|
||||
if (settingsNode == null)
|
||||
{
|
||||
settingsNode = _rootDocument.CreateElement(name);
|
||||
_rootNode.AppendChild(settingsNode);
|
||||
}
|
||||
if (settingsNode != null) return settingsNode;
|
||||
settingsNode = _rootDocument.CreateElement(name);
|
||||
_rootNode.AppendChild(settingsNode);
|
||||
|
||||
return settingsNode;
|
||||
}
|
||||
|
||||
public XmlDocument GetBlankXmlDocument()
|
||||
private static XmlDocument GetBlankXmlDocument()
|
||||
{
|
||||
XmlDocument blankXmlDocument = new XmlDocument();
|
||||
var blankXmlDocument = new XmlDocument();
|
||||
blankXmlDocument.AppendChild(blankXmlDocument.CreateXmlDeclaration("1.0", "utf-8", string.Empty));
|
||||
blankXmlDocument.AppendChild(blankXmlDocument.CreateElement(_rootNodeName));
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Threading;
|
||||
using System.Globalization;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI.Controls;
|
||||
@@ -20,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;
|
||||
@@ -34,7 +34,8 @@ namespace mRemoteNG.Config.Settings
|
||||
ExternalToolsToolStrip externalToolsToolStrip,
|
||||
MultiSshToolStrip multiSshToolStrip,
|
||||
ExternalAppsLoader externalAppsLoader,
|
||||
Func<NotificationAreaIcon> notificationAreaIconBuilder)
|
||||
Func<NotificationAreaIcon> notificationAreaIconBuilder,
|
||||
MenuStrip mainMenu)
|
||||
{
|
||||
_frmMain = mainForm.ThrowIfNull(nameof(mainForm));
|
||||
_messageCollector = messageCollector.ThrowIfNull(nameof(messageCollector));
|
||||
@@ -42,7 +43,8 @@ namespace mRemoteNG.Config.Settings
|
||||
_externalToolsToolStrip = externalToolsToolStrip.ThrowIfNull(nameof(externalToolsToolStrip));
|
||||
_multiSshToolStrip = multiSshToolStrip.ThrowIfNull(nameof(multiSshToolStrip));
|
||||
_externalAppsLoader = externalAppsLoader.ThrowIfNull(nameof(externalAppsLoader));
|
||||
_notificationAreaIconBuilder = notificationAreaIconBuilder;
|
||||
_notificationAreaIconBuilder = notificationAreaIconBuilder.ThrowIfNull(nameof(notificationAreaIconBuilder));
|
||||
_mainMenu = mainMenu.ThrowIfNull(nameof(mainMenu));
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
@@ -190,6 +192,7 @@ namespace mRemoteNG.Config.Settings
|
||||
private void LoadToolbarsFromSettings()
|
||||
{
|
||||
ResetAllToolbarLocations();
|
||||
AddMainMenuPanel();
|
||||
AddExternalAppsPanel();
|
||||
AddQuickConnectPanel();
|
||||
AddMultiSshPanel();
|
||||
@@ -203,31 +206,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)
|
||||
{
|
||||
@@ -252,4 +273,4 @@ namespace mRemoteNG.Config.Settings
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -114,6 +114,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);
|
||||
@@ -181,6 +182,10 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
connectionPanel = frmPnl.Panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -40,11 +40,6 @@ namespace mRemoteNG.Connection
|
||||
// TODO - this is only a property to break up a circular dependency. move to ctor when able
|
||||
public DatabaseConnectorFactory DatabaseConnectorFactory { 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, Import import, IWin32Window dialogWindowParent)
|
||||
{
|
||||
@@ -57,6 +52,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);
|
||||
@@ -90,6 +86,10 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
newConnectionInfo.Port = uri.Port;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newConnectionInfo.Panel))
|
||||
newConnectionInfo.Panel = Language.strGeneral;
|
||||
|
||||
newConnectionInfo.IsQuickConnect = true;
|
||||
|
||||
return newConnectionInfo;
|
||||
@@ -138,11 +138,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;
|
||||
@@ -229,9 +240,10 @@ namespace mRemoteNG.Connection
|
||||
|
||||
private void SaveConnectionsBGd()
|
||||
{
|
||||
Monitor.Enter(SaveLock);
|
||||
SaveConnections();
|
||||
Monitor.Exit(SaveLock);
|
||||
lock (SaveLock)
|
||||
{
|
||||
SaveConnections();
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadConnectionsAsync()
|
||||
|
||||
@@ -21,6 +21,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;
|
||||
_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.Tools;
|
||||
@@ -13,7 +14,6 @@ namespace mRemoteNG.Messages.WriterDecorators
|
||||
private readonly IMessageTypeFilteringOptions _filter;
|
||||
private readonly IMessageWriter _decoratedWriter;
|
||||
private readonly ErrorAndInfoWindow _messageWindow;
|
||||
private Timer _ecTimer;
|
||||
private readonly FrmMain _frmMain;
|
||||
|
||||
public MessageFocusDecorator(FrmMain frmMain, ErrorAndInfoWindow messageWindow, IMessageTypeFilteringOptions filter, IMessageWriter decoratedWriter)
|
||||
@@ -22,14 +22,14 @@ namespace mRemoteNG.Messages.WriterDecorators
|
||||
_filter = filter.ThrowIfNull(nameof(filter));
|
||||
_messageWindow = messageWindow.ThrowIfNull(nameof(messageWindow));
|
||||
_decoratedWriter = decoratedWriter.ThrowIfNull(nameof(decoratedWriter));
|
||||
CreateTimer();
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -38,7 +38,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;
|
||||
@@ -50,43 +51,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.7.*")]
|
||||
[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>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@@ -59,7 +59,7 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
@@ -105,17 +105,17 @@
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="strAbout" xml:space="preserve">
|
||||
<value>关于</value>
|
||||
@@ -123,6 +123,9 @@
|
||||
<data name="strActive" xml:space="preserve">
|
||||
<value>活动连接</value>
|
||||
</data>
|
||||
<data name="strActiveDirectory" xml:space="preserve">
|
||||
<value>活动目录</value>
|
||||
</data>
|
||||
<data name="strActivity" xml:space="preserve">
|
||||
<value>活动</value>
|
||||
</data>
|
||||
@@ -216,6 +219,9 @@
|
||||
<data name="strButtonInheritance" xml:space="preserve">
|
||||
<value>继承</value>
|
||||
</data>
|
||||
<data name="strButtonLaunch" xml:space="preserve">
|
||||
<value>启动(&L)</value>
|
||||
</data>
|
||||
<data name="strButtonLaunchPutty" xml:space="preserve">
|
||||
<value>启动PuTTY</value>
|
||||
</data>
|
||||
@@ -409,9 +415,18 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strColumnWaitForExit" xml:space="preserve">
|
||||
<value>等待退出</value>
|
||||
</data>
|
||||
<data name="strCommandExitProgram" xml:space="preserve">
|
||||
<value>退出{0}(&X)</value>
|
||||
</data>
|
||||
<data name="strCommandLineArgsCouldNotBeParsed" xml:space="preserve">
|
||||
<value>无法解析命令行参数!</value>
|
||||
</data>
|
||||
<data name="strCommandOpenConnectionFile" xml:space="preserve">
|
||||
<value>打开一个连接文件(&O)</value>
|
||||
</data>
|
||||
<data name="strCommandTryAgain" xml:space="preserve">
|
||||
<value>再试一次(&T)</value>
|
||||
</data>
|
||||
<data name="strCompatibilityLenovoAutoScrollUtilityDetected" xml:space="preserve">
|
||||
<value>{0} 检测到联想Auto Scroll程序在本机上运行。该程序程序明确会导致问题 {0} 的出现。建议您禁用或卸载该程序。</value>
|
||||
</data>
|
||||
@@ -559,6 +574,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strDetect" xml:space="preserve">
|
||||
<value>检测</value>
|
||||
</data>
|
||||
<data name="strDontConnectToConsoleSessionMenuItem" xml:space="preserve">
|
||||
<value>不要连接到控制台会话</value>
|
||||
</data>
|
||||
<data name="strDontConnectWhenAuthFails" xml:space="preserve">
|
||||
<value>身份验证失败时取消连接</value>
|
||||
</data>
|
||||
@@ -583,6 +601,12 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strEnc128BitLogonOnly" xml:space="preserve">
|
||||
<value>128位(仅用于登录)</value>
|
||||
</data>
|
||||
<data name="strEnc40Bit" xml:space="preserve">
|
||||
<value>40位</value>
|
||||
</data>
|
||||
<data name="strEnc56Bit" xml:space="preserve">
|
||||
<value>56位</value>
|
||||
</data>
|
||||
<data name="strEncBasic" xml:space="preserve">
|
||||
<value>基本</value>
|
||||
</data>
|
||||
@@ -613,6 +637,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strErrorConnectionListSaveFailed" xml:space="preserve">
|
||||
<value>无法保存连接列表。</value>
|
||||
</data>
|
||||
<data name="strErrorCouldNotLaunchPutty" xml:space="preserve">
|
||||
<value>PuTTY无法启动。</value>
|
||||
</data>
|
||||
<data name="strErrorDecryptionFailed" xml:space="preserve">
|
||||
<value>解密失败。{0}</value>
|
||||
</data>
|
||||
@@ -642,18 +669,48 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strExport" xml:space="preserve">
|
||||
<value>导出</value>
|
||||
</data>
|
||||
<data name="strExportEverything" xml:space="preserve">
|
||||
<value>导出所有内容</value>
|
||||
</data>
|
||||
<data name="strExportFile" xml:space="preserve">
|
||||
<value>导出文件</value>
|
||||
</data>
|
||||
<data name="strExportItems" xml:space="preserve">
|
||||
<value>导出项目</value>
|
||||
</data>
|
||||
<data name="strExportmRemoteXML" xml:space="preserve">
|
||||
<value>导出mRemote/mRemoteNG XML</value>
|
||||
</data>
|
||||
<data name="strExportProperties" xml:space="preserve">
|
||||
<value>导出属性</value>
|
||||
</data>
|
||||
<data name="strExportSelectedConnection" xml:space="preserve">
|
||||
<value>导出当前选定的连接</value>
|
||||
</data>
|
||||
<data name="strExportSelectedFolder" xml:space="preserve">
|
||||
<value>导出当前选定的文件夹</value>
|
||||
</data>
|
||||
<data name="strExportToFileMenuItem" xml:space="preserve">
|
||||
<value>导出到文件(&E)...</value>
|
||||
</data>
|
||||
<data name="strExtApp" xml:space="preserve">
|
||||
<value>外部应用</value>
|
||||
</data>
|
||||
<data name="strExternalToolDefaultName" xml:space="preserve">
|
||||
<value>新建外部工具</value>
|
||||
</data>
|
||||
<data name="strFAMFAMFAMAttribution" xml:space="preserve">
|
||||
<value>内置图标由[FAMFAMFAM]制作</value>
|
||||
</data>
|
||||
<data name="strFileFormatLabel" xml:space="preserve">
|
||||
<value>文件格式(&F):</value>
|
||||
</data>
|
||||
<data name="strFilterAll" xml:space="preserve">
|
||||
<value>所有文件(*.*)</value>
|
||||
</data>
|
||||
<data name="strFilterAllImportable" xml:space="preserve">
|
||||
<value>所有可导入的文件</value>
|
||||
</data>
|
||||
<data name="strFilterApplication" xml:space="preserve">
|
||||
<value>应用程序(*.exe)</value>
|
||||
</data>
|
||||
@@ -663,11 +720,17 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strFiltermRemoteXML" xml:space="preserve">
|
||||
<value>mRemote XML(*.xml)</value>
|
||||
</data>
|
||||
<data name="strFilterPuttyConnectionManager" xml:space="preserve">
|
||||
<value>PuTTY连接管理器文件</value>
|
||||
</data>
|
||||
<data name="strFilterRdgFiles" xml:space="preserve">
|
||||
<value>远程桌面连接管理器文件(*.rdg)</value>
|
||||
</data>
|
||||
<data name="strFilterRDP" xml:space="preserve">
|
||||
<value>RDP文件(*.rdp)</value>
|
||||
</data>
|
||||
<data name="strFiltervRD2008CSV" xml:space="preserve">
|
||||
<value>visionapp Remote Desktop 2008 CSV Files (*.csv)</value>
|
||||
<value>visionapp远程桌面2008 CSV文件(* .csv)</value>
|
||||
</data>
|
||||
<data name="strFormatInherit" xml:space="preserve">
|
||||
<value>继承 {0}</value>
|
||||
@@ -735,12 +798,36 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strIcaSetResolutionFailed" xml:space="preserve">
|
||||
<value>ICA 分辨率设置失败!</value>
|
||||
</data>
|
||||
<data name="strIdentifyQuickConnectTabs" xml:space="preserve">
|
||||
<value>通过添加前缀“快速:”来识别快速连接选项卡</value>
|
||||
</data>
|
||||
<data name="strImportAD" xml:space="preserve">
|
||||
<value>导入 Active Directory</value>
|
||||
</data>
|
||||
<data name="strImportExport" xml:space="preserve">
|
||||
<value>导入/导出</value>
|
||||
</data>
|
||||
<data name="strImportFileFailedContent" xml:space="preserve">
|
||||
<value>导入文件“{0}”时发生错误。</value>
|
||||
</data>
|
||||
<data name="strImportFileFailedMainInstruction" xml:space="preserve">
|
||||
<value>导入失败</value>
|
||||
</data>
|
||||
<data name="strImportFromFileMenuItem" xml:space="preserve">
|
||||
<value>从文件导入(&F)...</value>
|
||||
</data>
|
||||
<data name="strImportLocationCommandButtons" xml:space="preserve">
|
||||
<value>在根目录{0}{1}下|在所选文件夹{0}{2}下</value>
|
||||
</data>
|
||||
<data name="strImportLocationContent" xml:space="preserve">
|
||||
<value>您希望将导入的项目放在哪里?</value>
|
||||
</data>
|
||||
<data name="strImportLocationMainInstruction" xml:space="preserve">
|
||||
<value>导入位置</value>
|
||||
</data>
|
||||
<data name="strImportMenuItem" xml:space="preserve">
|
||||
<value>导入(&I)</value>
|
||||
</data>
|
||||
<data name="strImportmRemoteXML" xml:space="preserve">
|
||||
<value>导入mRemote/mRemoteNG XML</value>
|
||||
</data>
|
||||
@@ -876,6 +963,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strLoadFromSqlFailed" xml:space="preserve">
|
||||
<value>从SQL加载配置失败!</value>
|
||||
</data>
|
||||
<data name="strLoadFromSqlFailedContent" xml:space="preserve">
|
||||
<value>连接信息无法从SQL服务器加载。</value>
|
||||
</data>
|
||||
<data name="strLoadFromXmlFailed" xml:space="preserve">
|
||||
<value>从XML加载配置失败!</value>
|
||||
</data>
|
||||
@@ -1062,6 +1152,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strMenuSendSpecialKeys" xml:space="preserve">
|
||||
<value>发送特殊键(VNC)</value>
|
||||
</data>
|
||||
<data name="strMenuSessionRetrieve" xml:space="preserve">
|
||||
<value>取回</value>
|
||||
</data>
|
||||
<data name="strMenuSessions" xml:space="preserve">
|
||||
<value>会话</value>
|
||||
</data>
|
||||
@@ -1164,6 +1257,39 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strOpenPorts" xml:space="preserve">
|
||||
<value>打开端口</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardButtonDelete" xml:space="preserve">
|
||||
<value>删除(&D)</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardButtonNew" xml:space="preserve">
|
||||
<value>新建(&N)</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardButtonReset" xml:space="preserve">
|
||||
<value>重置为默认值(&R)</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardButtonResetAll" xml:space="preserve">
|
||||
<value>全部重置为默认值(&A)</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardCommandsGroupTabs" xml:space="preserve">
|
||||
<value>标签</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardCommandsNextTab" xml:space="preserve">
|
||||
<value>下一个标签</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardCommandsPreviousTab" xml:space="preserve">
|
||||
<value>上一个标签</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardGroupModifyShortcut" xml:space="preserve">
|
||||
<value>修改快捷方式</value>
|
||||
</data>
|
||||
<data name="strOptionsKeyboardLabelKeyboardShortcuts" xml:space="preserve">
|
||||
<value>键盘快捷键</value>
|
||||
</data>
|
||||
<data name="strOptionsProxyTesting" xml:space="preserve">
|
||||
<value>测试...</value>
|
||||
</data>
|
||||
<data name="strOptionsTabKeyboard" xml:space="preserve">
|
||||
<value>键盘</value>
|
||||
</data>
|
||||
<data name="strOptionsTabTheme" xml:space="preserve">
|
||||
<value>主题</value>
|
||||
</data>
|
||||
@@ -1179,9 +1305,18 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPasswordProtect" xml:space="preserve">
|
||||
<value>密码保护</value>
|
||||
</data>
|
||||
<data name="strPasswordStatusMustMatch" xml:space="preserve">
|
||||
<value>两个密码必须匹配。</value>
|
||||
</data>
|
||||
<data name="strPasswordStatusTooShort" xml:space="preserve">
|
||||
<value>密码必须至少有3个字符。</value>
|
||||
</data>
|
||||
<data name="strPleaseFillAllFields" xml:space="preserve">
|
||||
<value>请填写所有字段</value>
|
||||
</data>
|
||||
<data name="strPortScanComplete" xml:space="preserve">
|
||||
<value>端口扫描完成。</value>
|
||||
</data>
|
||||
<data name="strPortScanCouldNotLoadPanel" xml:space="preserve">
|
||||
<value>无法载入端口扫描面板!</value>
|
||||
</data>
|
||||
@@ -1200,6 +1335,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPropertyDescriptionAuthenticationMode" xml:space="preserve">
|
||||
<value>请选择VNC服务器的身份验证方式。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionAutomaticResize" xml:space="preserve">
|
||||
<value>在调整窗口大小时或在切换全屏模式时选择是否自动调整连接大小。需要RDC 8.0或更高版本。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionCacheBitmaps" xml:space="preserve">
|
||||
<value>请选择是否启用位图缓存功能。</value>
|
||||
</data>
|
||||
@@ -1245,6 +1383,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPropertyDescriptionIcon" xml:space="preserve">
|
||||
<value>请选择连接到主机时所要显示的图标。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionLoadBalanceInfo" xml:space="preserve">
|
||||
<value>指定负载均衡信息,供负载均衡路由器使用以选择最佳服务器。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionMACAddress" xml:space="preserve">
|
||||
<value>请输入远程主机的MAC地址(如果您需要在外部工具中使用此项)。</value>
|
||||
</data>
|
||||
@@ -1311,6 +1452,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPropertyDescriptionUseConsoleSession" xml:space="preserve">
|
||||
<value>连接到远程主机的控制台会话。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionUseCredSsp" xml:space="preserve">
|
||||
<value>如果可用,请使用凭证安全支持提供程序(CredSSP)进行身份验证。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionUser1" xml:space="preserve">
|
||||
<value>请在此随意输入任何你所需的信息。</value>
|
||||
</data>
|
||||
@@ -1347,6 +1491,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPropertyNameAuthenticationMode" xml:space="preserve">
|
||||
<value>身份验证模式</value>
|
||||
</data>
|
||||
<data name="strPropertyNameAutomaticResize" xml:space="preserve">
|
||||
<value>自动调整大小</value>
|
||||
</data>
|
||||
<data name="strPropertyNameCacheBitmaps" xml:space="preserve">
|
||||
<value>位图缓存</value>
|
||||
</data>
|
||||
@@ -1392,6 +1539,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPropertyNameIcon" xml:space="preserve">
|
||||
<value>图标</value>
|
||||
</data>
|
||||
<data name="strPropertyNameLoadBalanceInfo" xml:space="preserve">
|
||||
<value>负载均衡信息</value>
|
||||
</data>
|
||||
<data name="strPropertyNameMACAddress" xml:space="preserve">
|
||||
<value>MAC地址</value>
|
||||
</data>
|
||||
@@ -1533,6 +1683,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strPuttySavedSessionsRootName" xml:space="preserve">
|
||||
<value>PuTTY 会话已保存</value>
|
||||
</data>
|
||||
<data name="strPuttySessionSettings" xml:space="preserve">
|
||||
<value>PuTTY会话设置</value>
|
||||
</data>
|
||||
<data name="strPuttySettings" xml:space="preserve">
|
||||
<value>PuTTY 设置</value>
|
||||
</data>
|
||||
@@ -1572,12 +1725,6 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strRadioCloseWarnNever" xml:space="preserve">
|
||||
<value>关闭连接时不需确认</value>
|
||||
</data>
|
||||
<data name="strRAW" xml:space="preserve">
|
||||
<value>RAW</value>
|
||||
</data>
|
||||
<data name="strRDP" xml:space="preserve">
|
||||
<value>RDP</value>
|
||||
</data>
|
||||
<data name="strRDP16777216Colors" xml:space="preserve">
|
||||
<value>24位色</value>
|
||||
</data>
|
||||
@@ -1755,9 +1902,6 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strRename" xml:space="preserve">
|
||||
<value>重命名</value>
|
||||
</data>
|
||||
<data name="strRlogin" xml:space="preserve">
|
||||
<value>Rlogin</value>
|
||||
</data>
|
||||
<data name="strSave" xml:space="preserve">
|
||||
<value>保存</value>
|
||||
</data>
|
||||
@@ -1830,9 +1974,6 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strSmartSizeModeNone" xml:space="preserve">
|
||||
<value>禁用窗口自适应</value>
|
||||
</data>
|
||||
<data name="strSocks5" xml:space="preserve">
|
||||
<value>Socks 5</value>
|
||||
</data>
|
||||
<data name="strSort" xml:space="preserve">
|
||||
<value>排序</value>
|
||||
</data>
|
||||
@@ -1899,9 +2040,6 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strTabUpdates" xml:space="preserve">
|
||||
<value>升级</value>
|
||||
</data>
|
||||
<data name="strTelnet" xml:space="preserve">
|
||||
<value>Telnet</value>
|
||||
</data>
|
||||
<data name="strTheFollowing" xml:space="preserve">
|
||||
<value>以下:</value>
|
||||
</data>
|
||||
@@ -1914,6 +2052,57 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strThemeCategoryGeneral" xml:space="preserve">
|
||||
<value>常规</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConfigPanelBackgroundColor" xml:space="preserve">
|
||||
<value>配置面板的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConfigPanelCategoryTextColor" xml:space="preserve">
|
||||
<value>配置面板中类别文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConfigPanelGridLineColor" xml:space="preserve">
|
||||
<value>配置面板中网格线的颜色</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConfigPanelHelpBackgroundColor" xml:space="preserve">
|
||||
<value>配置面板的帮助区域的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConfigPanelHelpTextColor" xml:space="preserve">
|
||||
<value>配置面板帮助区域中文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConfigPanelTextColor" xml:space="preserve">
|
||||
<value>配置面板中文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConnectionsPanelBackgroundColor" xml:space="preserve">
|
||||
<value>连接面板的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConnectionsPanelTextColor" xml:space="preserve">
|
||||
<value>连接面板中文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionConnectionsPanelTreeLineColor" xml:space="preserve">
|
||||
<value>连接面板中树形线的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionMenuBackgroundColor" xml:space="preserve">
|
||||
<value>菜单的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionMenuTextColor" xml:space="preserve">
|
||||
<value>菜单中文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionSearchBoxBackgroundColor" xml:space="preserve">
|
||||
<value>搜索框的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionSearchBoxTextColor" xml:space="preserve">
|
||||
<value>搜索框中文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionSearchBoxTextPromptColor" xml:space="preserve">
|
||||
<value>搜索框中提示文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionToolbarBackgroundColor" xml:space="preserve">
|
||||
<value>工具栏的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionToolbarTextColor" xml:space="preserve">
|
||||
<value>工具栏中文本的颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeDescriptionWindowBackgroundColor" xml:space="preserve">
|
||||
<value>主窗口的背景颜色。</value>
|
||||
</data>
|
||||
<data name="strThemeNameConfigPanelBackgroundColor" xml:space="preserve">
|
||||
<value>配置面板背景色</value>
|
||||
</data>
|
||||
@@ -1974,6 +2163,9 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strTitlePassword" xml:space="preserve">
|
||||
<value>密码</value>
|
||||
</data>
|
||||
<data name="strTitlePasswordWithName" xml:space="preserve">
|
||||
<value>{0}的密码</value>
|
||||
</data>
|
||||
<data name="strTitleSelectPanel" xml:space="preserve">
|
||||
<value>选择面板</value>
|
||||
</data>
|
||||
@@ -1989,12 +2181,12 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strTryIntegrate" xml:space="preserve">
|
||||
<value>尝试进行集成</value>
|
||||
</data>
|
||||
<data name="strShowOnToolbar" xml:space="preserve">
|
||||
<value>在工具栏上显示</value>
|
||||
</data>
|
||||
<data name="strType" xml:space="preserve">
|
||||
<value>类型</value>
|
||||
</data>
|
||||
<data name="strUltraVncRepeater" xml:space="preserve">
|
||||
<value>Ultra VNC Repeater</value>
|
||||
</data>
|
||||
<data name="strUltraVNCSCListeningPort" xml:space="preserve">
|
||||
<value>UltraVNC SingleClick端口:</value>
|
||||
</data>
|
||||
@@ -2013,15 +2205,15 @@ VncSharp 版本 {0}</value>
|
||||
<data name="strUpdateCheckCompleteFailed" xml:space="preserve">
|
||||
<value>升级检查未完成!</value>
|
||||
</data>
|
||||
<data name="strUpdateCheckFailed" xml:space="preserve">
|
||||
<value>升级检查失败!</value>
|
||||
<data name="strUpdateCheckFailedLabel" xml:space="preserve">
|
||||
<value>检查失败</value>
|
||||
</data>
|
||||
<data name="strUpdateCheckingLabel" xml:space="preserve">
|
||||
<value>检查更新...</value>
|
||||
</data>
|
||||
<data name="strUpdateCheckPortableEdition" xml:space="preserve">
|
||||
<value>mRemoteNG便携版目前不支持自动更新。</value>
|
||||
</data>
|
||||
<data name="strUpdateDeleteFailed" xml:space="preserve">
|
||||
<value>升级文件删除失败!</value>
|
||||
</data>
|
||||
<data name="strUpdateDownloadComplete" xml:space="preserve">
|
||||
<value>下载完成!
|
||||
mRemoteNG 将退出并安装更新。</value>
|
||||
@@ -2044,15 +2236,12 @@ mRemoteNG 将退出并安装更新。</value>
|
||||
<data name="strUpdateFrequencyWeekly" xml:space="preserve">
|
||||
<value>每周</value>
|
||||
</data>
|
||||
<data name="strUpdateStartFailed" xml:space="preserve">
|
||||
<value>升级启动失败!</value>
|
||||
<data name="strUpdateGetChangeLogFailed" xml:space="preserve">
|
||||
<value>更改日志无法下载。</value>
|
||||
</data>
|
||||
<data name="strUseDifferentUsernameAndPassword" xml:space="preserve">
|
||||
<value>使用不同的用户名和密码</value>
|
||||
</data>
|
||||
<data name="strUseOnlyErrorsAndInfosPanel" xml:space="preserve">
|
||||
<value>仅适用通知面板(不弹出消息窗口)</value>
|
||||
</data>
|
||||
<data name="strUser" xml:space="preserve">
|
||||
<value>用户</value>
|
||||
</data>
|
||||
@@ -2068,9 +2257,6 @@ mRemoteNG 将退出并安装更新。</value>
|
||||
<data name="strVersion" xml:space="preserve">
|
||||
<value>版本</value>
|
||||
</data>
|
||||
<data name="strVnc" xml:space="preserve">
|
||||
<value>VNC</value>
|
||||
</data>
|
||||
<data name="strVncConnectionDisconnectFailed" xml:space="preserve">
|
||||
<value>VNC 连接断开失败!</value>
|
||||
</data>
|
||||
@@ -2104,13 +2290,324 @@ mRemoteNG 将退出并安装更新。</value>
|
||||
<data name="strWeifenLuoAttribution" xml:space="preserve">
|
||||
<value>使用DockPanel Suite[Weifen Luo]</value>
|
||||
</data>
|
||||
<data name="strWriteLogFile" xml:space="preserve">
|
||||
<value>记录日志(mRemoteNG.log)</value>
|
||||
</data>
|
||||
<data name="strXULrunnerPath" xml:space="preserve">
|
||||
<value>XULrunner路径:</value>
|
||||
</data>
|
||||
<data name="strYes" xml:space="preserve">
|
||||
<value>确定</value>
|
||||
</data>
|
||||
<data name="strMenuReconnectAll" xml:space="preserve">
|
||||
<value>重新连接所有打开的连接</value>
|
||||
</data>
|
||||
<data name="strRDPOverallConnectionTimeout" xml:space="preserve">
|
||||
<value>RDP连接超时</value>
|
||||
</data>
|
||||
<data name="strNodeAlreadyInFolder" xml:space="preserve">
|
||||
<value>此节点已在此文件夹中。</value>
|
||||
</data>
|
||||
<data name="strNodeCannotDragOnSelf" xml:space="preserve">
|
||||
<value>无法将节点拖到自身上。</value>
|
||||
</data>
|
||||
<data name="strNodeCannotDragParentOnChild" xml:space="preserve">
|
||||
<value>无法将父节点拖放到子节点上。</value>
|
||||
</data>
|
||||
<data name="strNodeNotDraggable" xml:space="preserve">
|
||||
<value>该节点不可拖动。</value>
|
||||
</data>
|
||||
<data name="strEncryptionBlockCipherMode" xml:space="preserve">
|
||||
<value>分组密码模式</value>
|
||||
</data>
|
||||
<data name="strEncryptionEngine" xml:space="preserve">
|
||||
<value>加密引擎</value>
|
||||
</data>
|
||||
<data name="strTabSecurity" xml:space="preserve">
|
||||
<value>安全</value>
|
||||
</data>
|
||||
<data name="strEncryptionKeyDerivationIterations" xml:space="preserve">
|
||||
<value>关键推导函数迭代</value>
|
||||
</data>
|
||||
<data name="strRDPSoundQualityDynamic" xml:space="preserve">
|
||||
<value>动态</value>
|
||||
</data>
|
||||
<data name="strRDPSoundQualityHigh" xml:space="preserve">
|
||||
<value>高</value>
|
||||
</data>
|
||||
<data name="strRDPSoundQualityMedium" xml:space="preserve">
|
||||
<value>中</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionSoundQuality" xml:space="preserve">
|
||||
<value>选择由协议提供的声音质量:动态,中,高</value>
|
||||
</data>
|
||||
<data name="strPropertyNameSoundQuality" xml:space="preserve">
|
||||
<value>音质</value>
|
||||
</data>
|
||||
<data name="strUpdatePortableDownloadComplete" xml:space="preserve">
|
||||
<value>下载完成!</value>
|
||||
</data>
|
||||
<data name="strDownloadPortable" xml:space="preserve">
|
||||
<value>下载</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionRDPMinutesToIdleTimeout" xml:space="preserve">
|
||||
<value>RDP会话在自动断开连接之前闲置的分钟数(无限制使用0)</value>
|
||||
</data>
|
||||
<data name="strPropertyNameRDPMinutesToIdleTimeout" xml:space="preserve">
|
||||
<value>空闲等待分钟数</value>
|
||||
</data>
|
||||
<data name="strAccept" xml:space="preserve">
|
||||
<value>接受</value>
|
||||
</data>
|
||||
<data name="strAdd" xml:space="preserve">
|
||||
<value>添加</value>
|
||||
</data>
|
||||
<data name="strCredentialEditor" xml:space="preserve">
|
||||
<value>凭据编辑器</value>
|
||||
</data>
|
||||
<data name="strCredentialManager" xml:space="preserve">
|
||||
<value>凭证管理器</value>
|
||||
</data>
|
||||
<data name="strRemove" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name="strTitle" xml:space="preserve">
|
||||
<value>标题</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionCredential" xml:space="preserve">
|
||||
<value>选择用于此连接的凭证。</value>
|
||||
</data>
|
||||
<data name="strConfirmDeleteCredentialRecord" xml:space="preserve">
|
||||
<value>您确定要删除凭据记录{0}吗?</value>
|
||||
</data>
|
||||
<data name="strFindMatchingCredentialFailed" xml:space="preserve">
|
||||
<value>找不到名为“{1}”的连接记录的ID为“{0}”的凭证记录。</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionRDPAlertIdleTimeout" xml:space="preserve">
|
||||
<value>选择是否在RDP会话由于不活动而断开连接后收到警报</value>
|
||||
</data>
|
||||
<data name="strPropertyNameRDPAlertIdleTimeout" xml:space="preserve">
|
||||
<value>空闲断开警报</value>
|
||||
</data>
|
||||
<data name="strPasswordConstainsSpecialCharactersConstraintHint" xml:space="preserve">
|
||||
<value>密码必须至少包含{0}个以下所示字符:{1}</value>
|
||||
</data>
|
||||
<data name="strPasswordContainsLowerCaseConstraintHint" xml:space="preserve">
|
||||
<value>密码必须至少包含{0}个小写字符</value>
|
||||
</data>
|
||||
<data name="strPasswordContainsNumbersConstraint" xml:space="preserve">
|
||||
<value>密码必须至少包含{0}个数字</value>
|
||||
</data>
|
||||
<data name="strPasswordContainsUpperCaseConstraintHint" xml:space="preserve">
|
||||
<value>密码必须至少包含{0}大写字符</value>
|
||||
</data>
|
||||
<data name="strPasswordLengthConstraintHint" xml:space="preserve">
|
||||
<value>密码长度必须介于{0}和{1}之间</value>
|
||||
</data>
|
||||
<data name="strChooseLogPath" xml:space="preserve">
|
||||
<value>为mRemoteNG日志文件选择一个路径</value>
|
||||
</data>
|
||||
<data name="strDebug" xml:space="preserve">
|
||||
<value>调试</value>
|
||||
</data>
|
||||
<data name="strShowTheseMessageTypes" xml:space="preserve">
|
||||
<value>显示这些消息类型</value>
|
||||
</data>
|
||||
<data name="strLogFilePath" xml:space="preserve">
|
||||
<value>日志文件路径</value>
|
||||
</data>
|
||||
<data name="strLogTheseMessageTypes" xml:space="preserve">
|
||||
<value>记录这些消息类型</value>
|
||||
</data>
|
||||
<data name="strChoosePath" xml:space="preserve">
|
||||
<value>选择路径</value>
|
||||
</data>
|
||||
<data name="strOpenFile" xml:space="preserve">
|
||||
<value>打开文件</value>
|
||||
</data>
|
||||
<data name="strUseDefault" xml:space="preserve">
|
||||
<value>使用默认</value>
|
||||
</data>
|
||||
<data name="strLogging" xml:space="preserve">
|
||||
<value>记录</value>
|
||||
</data>
|
||||
<data name="strPopups" xml:space="preserve">
|
||||
<value>弹出窗口</value>
|
||||
</data>
|
||||
<data name="strLogToAppDir" xml:space="preserve">
|
||||
<value>登录到应用程序目录</value>
|
||||
</data>
|
||||
<data name="strAssignedCredential" xml:space="preserve">
|
||||
<value>分配凭据</value>
|
||||
</data>
|
||||
<data name="strHttpsInsecureAllowAlways" xml:space="preserve">
|
||||
<value>始终允许</value>
|
||||
</data>
|
||||
<data name="strHttpsInsecureAllowOnce" xml:space="preserve">
|
||||
<value>允许一次</value>
|
||||
</data>
|
||||
<data name="strHttpsInsecureDontAllow" xml:space="preserve">
|
||||
<value>不允许</value>
|
||||
</data>
|
||||
<data name="strHttpsInsecurePrompt" xml:space="preserve">
|
||||
<value>允许网址{0}的不安全证书?</value>
|
||||
</data>
|
||||
<data name="strHttpsInsecurePromptTitle" xml:space="preserve">
|
||||
<value>允许不安全的证书?</value>
|
||||
</data>
|
||||
<data name="RepositoryIsUnlocked" xml:space="preserve">
|
||||
<value>选定的存储库已解锁</value>
|
||||
</data>
|
||||
<data name="IncorrectPassword" xml:space="preserve">
|
||||
<value>密码错误</value>
|
||||
</data>
|
||||
<data name="Source" xml:space="preserve">
|
||||
<value>资源</value>
|
||||
</data>
|
||||
<data name="Unlocking" xml:space="preserve">
|
||||
<value>解锁</value>
|
||||
</data>
|
||||
<data name="UnlockCredentialRepository" xml:space="preserve">
|
||||
<value>解锁凭据存储库</value>
|
||||
</data>
|
||||
<data name="Unlock" xml:space="preserve">
|
||||
<value>解锁</value>
|
||||
</data>
|
||||
<data name="PromptUnlockCredReposOnStartup" xml:space="preserve">
|
||||
<value>提示在启动时解锁凭据存储库</value>
|
||||
</data>
|
||||
<data name="Credentials" xml:space="preserve">
|
||||
<value>凭据</value>
|
||||
</data>
|
||||
<data name="strUpgrade" xml:space="preserve">
|
||||
<value>升级</value>
|
||||
</data>
|
||||
<data name="strBack" xml:space="preserve">
|
||||
<value>后退</value>
|
||||
</data>
|
||||
<data name="strConnectionFilePath" xml:space="preserve">
|
||||
<value>连接文件路径</value>
|
||||
</data>
|
||||
<data name="strCreateAndOpenNewFile" xml:space="preserve">
|
||||
<value>创建并打开新文件</value>
|
||||
</data>
|
||||
<data name="strOpenADifferentFile" xml:space="preserve">
|
||||
<value>打开一个不同的文件</value>
|
||||
</data>
|
||||
<data name="strCredentialManagerUpgradeDescription" xml:space="preserve">
|
||||
<value>在v1.76中,我们引入了凭证管理系统。此功能要求我们在mRemoteNG中存储和交互凭据的方式发生重大变化。您将需要执行mRemoteNG连接文件的单向升级。
|
||||
|
||||
如果您不想执行升级,此页面将引导您完成升级连接文件的过程,或者让您有机会打开不同的连接文件。</value>
|
||||
</data>
|
||||
<data name="CredentialUnavailable" xml:space="preserve">
|
||||
<value>凭据不可用</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeDeleteConfirmation" xml:space="preserve">
|
||||
<value>你真的想删除主题吗?</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeEnableTheming" xml:space="preserve">
|
||||
<value>启用主题</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeNewThemeCaption" xml:space="preserve">
|
||||
<value>新主题名称</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeNewThemeError" xml:space="preserve">
|
||||
<value>无法创建主题,名称已存在或名称中有特殊字符</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeNewThemeText" xml:space="preserve">
|
||||
<value>输入新的主题名称</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeThemeChaangeWarning" xml:space="preserve">
|
||||
<value>警告:需要重新启动才能禁用主题或完全应用新主题</value>
|
||||
</data>
|
||||
<data name="strOptionsThemeErrorNoThemes" xml:space="preserve">
|
||||
<value>未加载任何主题,请检查默认的mremoteNG主题是否存在于“主题”文件夹中</value>
|
||||
</data>
|
||||
<data name="CouldNotFindExternalTool" xml:space="preserve">
|
||||
<value>无法找到名称为“{0}”的外部工具</value>
|
||||
</data>
|
||||
<data name="ConfigurationCreateNew" xml:space="preserve">
|
||||
<value>创建一个新的连接文件</value>
|
||||
</data>
|
||||
<data name="ConnectionFileNotFound" xml:space="preserve">
|
||||
<value>无法找到连接文件。</value>
|
||||
</data>
|
||||
<data name="ConfigurationImportFile" xml:space="preserve">
|
||||
<value>导入现有文件</value>
|
||||
</data>
|
||||
<data name="ConfigurationCustomPath" xml:space="preserve">
|
||||
<value>使用自定义文件路径</value>
|
||||
</data>
|
||||
<data name="TestingConnection" xml:space="preserve">
|
||||
<value>测试连接</value>
|
||||
</data>
|
||||
<data name="ServerNotAccessible" xml:space="preserve">
|
||||
<value>服务器“{0}”无法访问。</value>
|
||||
</data>
|
||||
<data name="ConnectionSuccessful" xml:space="preserve">
|
||||
<value>连接成功</value>
|
||||
</data>
|
||||
<data name="LoginFailedForUser" xml:space="preserve">
|
||||
<value>用户“{0}”登录失败。</value>
|
||||
</data>
|
||||
<data name="DatabaseNotAvailable" xml:space="preserve">
|
||||
<value>数据库“{0}”不可用。</value>
|
||||
</data>
|
||||
<data name="SaveConnectionsAfterEveryEdit" xml:space="preserve">
|
||||
<value>每次编辑后保存连接</value>
|
||||
</data>
|
||||
<data name="FilterSearchMatchesInConnectionTree" xml:space="preserve">
|
||||
<value>在连接树中过滤搜索匹配</value>
|
||||
</data>
|
||||
<data name="TestConnection" xml:space="preserve">
|
||||
<value>测试连接</value>
|
||||
</data>
|
||||
<data name="strLabelReadOnly" xml:space="preserve">
|
||||
<value>只读:</value>
|
||||
</data>
|
||||
<data name="LoadBalanceInfoUseUtf8" xml:space="preserve">
|
||||
<value>对RDP“负载均衡信息”属性使用UTF8编码</value>
|
||||
</data>
|
||||
<data name="strTimeoutInSeconds" xml:space="preserve">
|
||||
<value>超时(秒)</value>
|
||||
</data>
|
||||
<data name="srtWorkingDirectory" xml:space="preserve">
|
||||
<value>工作目录:</value>
|
||||
</data>
|
||||
<data name="strRunElevated" xml:space="preserve">
|
||||
<value>运行已提升</value>
|
||||
</data>
|
||||
<data name="strRunElevateHeader" xml:space="preserve">
|
||||
<value>运行提升</value>
|
||||
</data>
|
||||
<data name="strShowOnToolbarColumnHeader" xml:space="preserve">
|
||||
<value>显示在工具栏上</value>
|
||||
</data>
|
||||
<data name="strTryToIntegrateColumnHeader" xml:space="preserve">
|
||||
<value>尝试整合</value>
|
||||
</data>
|
||||
<data name="strWorkingDirColumnHeader" xml:space="preserve">
|
||||
<value>工作目录</value>
|
||||
</data>
|
||||
<data name="strLockToolbars" xml:space="preserve">
|
||||
<value>锁定工具栏位置</value>
|
||||
</data>
|
||||
<data name="strMultiSshToolbar" xml:space="preserve">
|
||||
<value>多SSH工具栏</value>
|
||||
</data>
|
||||
<data name="strImportSubOUs" xml:space="preserve">
|
||||
<value>导入子OU</value>
|
||||
</data>
|
||||
<data name="strMenuLockToolbars" xml:space="preserve">
|
||||
<value>锁定工具栏位置</value>
|
||||
</data>
|
||||
<data name="strMenuMultiSshToolbar" xml:space="preserve">
|
||||
<value>多SSH工具栏</value>
|
||||
</data>
|
||||
<data name="strAdvancedSecurityOptions" xml:space="preserve">
|
||||
<value>高级安全选项</value>
|
||||
</data>
|
||||
<data name="strOptionsPageTitle" xml:space="preserve">
|
||||
<value>mRemoteNG选项</value>
|
||||
</data>
|
||||
<data name="strLoadBalanceInfoUseUtf8" xml:space="preserve">
|
||||
<value>对RDP“负载均衡信息”属性使用UTF8编码</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);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
33
mRemoteV1/Tools/DisposableOptional.cs
Normal file
33
mRemoteV1/Tools/DisposableOptional.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace mRemoteNG.Tools
|
||||
{
|
||||
public class DisposableOptional<T> : Optional<T>, IDisposable
|
||||
where T : IDisposable
|
||||
{
|
||||
public DisposableOptional()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public DisposableOptional(T value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposing || !this.Any())
|
||||
return;
|
||||
|
||||
this.First().Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.AccessControl;
|
||||
using Microsoft.Win32;
|
||||
using mRemoteNG.App;
|
||||
@@ -38,14 +39,16 @@ namespace mRemoteNG.Tools
|
||||
{
|
||||
using (var key = Registry.CurrentUser.OpenSubKey(string.Concat("Software\\Wow6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\", feature), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
{
|
||||
key?.DeleteValue(appName);
|
||||
if (key?.GetValueNames().Contains(appName) ?? false)
|
||||
key.DeleteValue(appName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using (var key = Registry.CurrentUser.CreateSubKey(string.Concat("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\", feature), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
{
|
||||
key?.DeleteValue(appName);
|
||||
if (key?.GetValueNames().Contains(appName) ?? false)
|
||||
key.DeleteValue(appName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
8
mRemoteV1/Tools/WindowsRegistry/IRegistry.cs
Normal file
8
mRemoteV1/Tools/WindowsRegistry/IRegistry.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
public interface IRegistry
|
||||
{
|
||||
Optional<string> GetKeyValue(RegistryHive hive, string keyPath, string propertyName);
|
||||
string[] GetSubKeyNames(RegistryHive hive, string keyPath);
|
||||
}
|
||||
}
|
||||
11
mRemoteV1/Tools/WindowsRegistry/RegistryHive.cs
Normal file
11
mRemoteV1/Tools/WindowsRegistry/RegistryHive.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
public enum RegistryHive
|
||||
{
|
||||
ClassesRoot,
|
||||
CurrentConfig,
|
||||
CurrentUser,
|
||||
Users,
|
||||
LocalMachine
|
||||
}
|
||||
}
|
||||
54
mRemoteV1/Tools/WindowsRegistry/WindowsRegistry.cs
Normal file
54
mRemoteV1/Tools/WindowsRegistry/WindowsRegistry.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
public class WindowsRegistry : IRegistry
|
||||
{
|
||||
public string[] GetSubKeyNames(RegistryHive hive, string keyPath)
|
||||
{
|
||||
keyPath.ThrowIfNull(nameof(keyPath));
|
||||
|
||||
using (var key = OpenSubKey(hive, keyPath))
|
||||
{
|
||||
return key.Any()
|
||||
? key.First().GetSubKeyNames()
|
||||
: new string[0];
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<string> GetKeyValue(RegistryHive hive, string keyPath, string propertyName)
|
||||
{
|
||||
keyPath.ThrowIfNull(nameof(keyPath));
|
||||
propertyName.ThrowIfNull(nameof(propertyName));
|
||||
|
||||
using (var key = OpenSubKey(hive, keyPath))
|
||||
{
|
||||
if (!key.Any())
|
||||
return Optional<string>.Empty;
|
||||
|
||||
return key.First().GetValue(propertyName) as string;
|
||||
}
|
||||
}
|
||||
|
||||
private DisposableOptional<RegistryKey> OpenSubKey(RegistryHive hive, string keyPath)
|
||||
{
|
||||
switch (hive)
|
||||
{
|
||||
case RegistryHive.ClassesRoot:
|
||||
return new DisposableOptional<RegistryKey>(Registry.ClassesRoot.OpenSubKey(keyPath));
|
||||
case RegistryHive.CurrentConfig:
|
||||
return new DisposableOptional<RegistryKey>(Registry.CurrentConfig.OpenSubKey(keyPath));
|
||||
case RegistryHive.CurrentUser:
|
||||
return new DisposableOptional<RegistryKey>(Registry.CurrentUser.OpenSubKey(keyPath));
|
||||
case RegistryHive.Users:
|
||||
return new DisposableOptional<RegistryKey>(Registry.Users.OpenSubKey(keyPath));
|
||||
case RegistryHive.LocalMachine:
|
||||
return new DisposableOptional<RegistryKey>(Registry.LocalMachine.OpenSubKey(keyPath));
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(hive), hive, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -21,7 +21,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 ConnectionTreeModel _connectionTreeModel;
|
||||
|
||||
@@ -56,7 +57,6 @@ namespace mRemoteNG.UI.Controls
|
||||
SetupConnectionTreeView();
|
||||
UseOverlays = false;
|
||||
}
|
||||
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
@@ -267,6 +267,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);
|
||||
@@ -297,8 +300,11 @@ namespace mRemoteNG.UI.Controls
|
||||
|
||||
public void RenameSelectedNode()
|
||||
{
|
||||
_allowEdit = true;
|
||||
SelectedItem.BeginEdit();
|
||||
if (SelectedItem != null)
|
||||
{
|
||||
_allowEdit = true;
|
||||
SelectedItem.BeginEdit();
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteSelectedNode()
|
||||
@@ -334,10 +340,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)
|
||||
@@ -362,11 +382,16 @@ namespace mRemoteNG.UI.Controls
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateFiltering()
|
||||
{
|
||||
base.UpdateFiltering();
|
||||
AutoResizeColumn(Columns[0]);
|
||||
}
|
||||
|
||||
private void OnMouse_DoubleClick(object sender, MouseEventArgs mouseEventArgs)
|
||||
{
|
||||
if (mouseEventArgs.Clicks < 2) return;
|
||||
OLVColumn column;
|
||||
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column);
|
||||
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out _);
|
||||
var clickedNode = listItem?.RowObject as ConnectionInfo;
|
||||
if (clickedNode == null) return;
|
||||
DoubleClickHandler.Execute(clickedNode);
|
||||
@@ -375,8 +400,7 @@ namespace mRemoteNG.UI.Controls
|
||||
private void OnMouse_SingleClick(object sender, MouseEventArgs mouseEventArgs)
|
||||
{
|
||||
if (mouseEventArgs.Clicks > 1) return;
|
||||
OLVColumn column;
|
||||
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column);
|
||||
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out _);
|
||||
var clickedNode = listItem?.RowObject as ConnectionInfo;
|
||||
if (clickedNode == null) return;
|
||||
SingleClickHandler.Execute(clickedNode);
|
||||
@@ -386,6 +410,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;
|
||||
}
|
||||
@@ -421,6 +452,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();
|
||||
RaiseSelectedNodeChangedEvent(SelectedNode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -442,4 +476,4 @@ namespace mRemoteNG.UI.Controls
|
||||
SelectedNodeChanged?.Invoke(this, selectedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -6,7 +6,7 @@ using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class AppearancePage
|
||||
public sealed partial class AppearancePage
|
||||
{
|
||||
private readonly IConnectionInitiator _connectionInitiator;
|
||||
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
|
||||
@@ -18,12 +18,12 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
_notificationAreaIconBuilder = notificationAreaIconBuilder;
|
||||
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
|
||||
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.
|
||||
|
||||
@@ -4,7 +4,7 @@ using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class ConnectionsPage
|
||||
public sealed partial class ConnectionsPage
|
||||
{
|
||||
private readonly FrmMain _frmMain;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strConnections; }
|
||||
get => Language.strConnections;
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -114,4 +114,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
partial class CredentialsPage
|
||||
sealed partial class CredentialsPage
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class CredentialsPage : OptionsPage
|
||||
public sealed partial class CredentialsPage : OptionsPage
|
||||
{
|
||||
private readonly IConnectionsService _connectionsService;
|
||||
|
||||
@@ -13,11 +12,11 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
_connectionsService = connectionsService;
|
||||
InitializeComponent();
|
||||
base.ApplyTheme();
|
||||
ApplyTheme();
|
||||
}
|
||||
|
||||
public override string PageName {
|
||||
get { return Language.Credentials; }
|
||||
get => Language.Credentials;
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -90,4 +89,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
txtCredentialsDomain.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -9,7 +9,7 @@ using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class SqlServerPage
|
||||
public sealed partial class SqlServerPage
|
||||
{
|
||||
private readonly SqlDatabaseConnectionTester _databaseConnectionTester;
|
||||
private readonly IConnectionsService _connectionsService;
|
||||
@@ -20,13 +20,13 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
|
||||
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
|
||||
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.
|
||||
|
||||
@@ -2,7 +2,7 @@ using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class TabsPanelsPage
|
||||
public sealed partial class TabsPanelsPage
|
||||
{
|
||||
private readonly FrmMain _frmMain;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabsAndPanels.Replace("&&", "&"); }
|
||||
get => Language.strTabsAndPanels.Replace("&&", "&");
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -31,7 +31,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()
|
||||
@@ -79,4 +79,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
UpdatePanelNameTextBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -11,7 +11,7 @@ using mRemoteNG.UI.TaskDialog;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
public partial class UpdatesPage
|
||||
public sealed partial class UpdatesPage
|
||||
{
|
||||
private readonly AppUpdater _appUpdate;
|
||||
private readonly Action<WindowType> _showWindowAction;
|
||||
@@ -30,7 +30,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
public override string PageName
|
||||
{
|
||||
get { return Language.strTabUpdates; }
|
||||
get => Language.strTabUpdates;
|
||||
set { }
|
||||
}
|
||||
|
||||
@@ -257,4 +257,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,21 +18,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()
|
||||
@@ -40,11 +34,19 @@ 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();
|
||||
|
||||
@@ -69,24 +71,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
@@ -83,7 +83,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);
|
||||
//
|
||||
@@ -93,7 +93,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;
|
||||
@@ -105,13 +105,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
|
||||
|
||||
@@ -101,7 +101,8 @@ namespace mRemoteNG.UI.Forms
|
||||
var connectionTreeWindow = new ConnectionTreeWindow(new DockContent(), _connectionInitiator, _connectionsService);
|
||||
var connectionTree = connectionTreeWindow.ConnectionTree;
|
||||
connectionTree.SelectedNodeChanged += configWindow.HandleConnectionTreeSelectionChanged;
|
||||
var connectionTreeContextMenu = new ConnectionContextMenu(connectionTree, _connectionInitiator, sshTransferWindow, _export, externalToolsService, _import, _connectionsService);
|
||||
var connectionTreeContextMenu = new ConnectionContextMenu(connectionTree, _connectionInitiator,
|
||||
sshTransferWindow, _export, externalToolsService, _import, _connectionsService);
|
||||
connectionTree.ConnectionContextMenu = connectionTreeContextMenu;
|
||||
connectionTreeWindow.ConnectionTreeContextMenu = connectionTreeContextMenu;
|
||||
var errorAndInfoWindow = new ErrorAndInfoWindow(new DockContent(), pnlDock, connectionTreeWindow);
|
||||
@@ -110,14 +111,17 @@ namespace mRemoteNG.UI.Forms
|
||||
_shutdown = new Shutdown(_settingsSaver, _connectionsService, this);
|
||||
Func<UpdateWindow> updateWindowBuilder = () => new UpdateWindow(new DockContent(), _shutdown, _appUpdater);
|
||||
_notificationAreaIconBuilder = () => new NotificationAreaIcon(this, _connectionInitiator, _shutdown, _connectionsService);
|
||||
Func<ExternalToolsWindow> externalToolsWindowBuilder = () => new ExternalToolsWindow(_connectionInitiator, externalToolsService, () => connectionTree.SelectedNode, this, _connectionsService);
|
||||
Func<ExternalToolsWindow> externalToolsWindowBuilder = () =>
|
||||
new ExternalToolsWindow(_connectionInitiator, externalToolsService, () => connectionTree.SelectedNode, this, _connectionsService);
|
||||
Func<PortScanWindow> portScanWindowBuilder = () => new PortScanWindow(connectionTreeWindow, _import);
|
||||
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder = () => new ActiveDirectoryImportWindow(() => connectionTreeWindow.SelectedNode, _import, _connectionsService);
|
||||
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder = () =>
|
||||
new ActiveDirectoryImportWindow(() => connectionTreeWindow.SelectedNode, _import, _connectionsService);
|
||||
_databaseConnectorFactory = new DatabaseConnectorFactory(encryptionKeySelectionFunc);
|
||||
_windows = new Windows(_connectionInitiator, connectionTreeWindow, configWindow, errorAndInfoWindow, screenshotManagerWindow,
|
||||
sshTransferWindow, updateWindowBuilder, _notificationAreaIconBuilder, externalToolsWindowBuilder, _connectionsService,
|
||||
portScanWindowBuilder, activeDirectoryImportWindowBuilder, _appUpdater, _databaseConnectorFactory, this);
|
||||
Func<ConnectionWindow> connectionWindowBuilder = () => new ConnectionWindow(new DockContent(), _connectionInitiator, _windows, externalToolsService, this);
|
||||
Func<ConnectionWindow> connectionWindowBuilder = () =>
|
||||
new ConnectionWindow(new DockContent(), _connectionInitiator, _windows, externalToolsService, this);
|
||||
_screens = new Screens(this);
|
||||
_panelAdder = new PanelAdder(_windowList, connectionWindowBuilder, _screens, pnlDock);
|
||||
_showFullPathInTitle = Settings.Default.ShowCompleteConsPathInTitle;
|
||||
@@ -127,8 +131,10 @@ namespace mRemoteNG.UI.Forms
|
||||
_startup = new Startup(this, _windows, _connectionsService, _appUpdater, _databaseConnectorFactory, compatibilityChecker);
|
||||
connectionTreeContextMenu.ShowWindowAction = _windows.Show;
|
||||
|
||||
var externalAppsLoader = new ExternalAppsLoader(Runtime.MessageCollector, _externalToolsToolStrip, _connectionInitiator, externalToolsService, _connectionsService);
|
||||
_settingsLoader = new SettingsLoader(this, Runtime.MessageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, externalAppsLoader, _notificationAreaIconBuilder);
|
||||
var externalAppsLoader = new ExternalAppsLoader(Runtime.MessageCollector, _externalToolsToolStrip,
|
||||
_connectionInitiator, externalToolsService, _connectionsService);
|
||||
_settingsLoader = new SettingsLoader(this, Runtime.MessageCollector, _quickConnectToolStrip, _externalToolsToolStrip,
|
||||
_multiSshToolStrip, externalAppsLoader, _notificationAreaIconBuilder, msMain);
|
||||
_externalToolsToolStrip.ExternalToolsService = externalToolsService;
|
||||
_externalToolsToolStrip.GetSelectedConnectionFunc = () => SelectedConnection;
|
||||
_quickConnectToolStrip.ConnectionInitiator = _connectionInitiator;
|
||||
@@ -153,8 +159,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public bool AreWeUsingSqlServerForSavingConnections
|
||||
{
|
||||
get { return _usingSqlServer; }
|
||||
set
|
||||
get => _usingSqlServer;
|
||||
set
|
||||
{
|
||||
if (_usingSqlServer == value)
|
||||
{
|
||||
@@ -167,8 +173,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public string ConnectionsFileName
|
||||
{
|
||||
get { return _connectionsFileName; }
|
||||
set
|
||||
get => _connectionsFileName;
|
||||
set
|
||||
{
|
||||
if (_connectionsFileName == value)
|
||||
{
|
||||
@@ -181,8 +187,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public bool ShowFullPathInTitle
|
||||
{
|
||||
get { return _showFullPathInTitle; }
|
||||
set
|
||||
get => _showFullPathInTitle;
|
||||
set
|
||||
{
|
||||
if (_showFullPathInTitle == value)
|
||||
{
|
||||
@@ -195,8 +201,8 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
public ConnectionInfo SelectedConnection
|
||||
{
|
||||
get { return _selectedConnection; }
|
||||
set
|
||||
get => _selectedConnection;
|
||||
set
|
||||
{
|
||||
if (_selectedConnection == value)
|
||||
{
|
||||
@@ -334,25 +340,20 @@ namespace mRemoteNG.UI.Forms
|
||||
//Theming support
|
||||
private void SetSchema()
|
||||
{
|
||||
if (_themeManager.ThemingActive)
|
||||
{
|
||||
// Persist settings when rebuilding UI
|
||||
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)
|
||||
{
|
||||
@@ -711,14 +712,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
|
||||
|
||||
@@ -732,4 +727,4 @@ namespace mRemoteNG.UI.Forms
|
||||
fileMenu.mMenFile_DropDownOpening(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +60,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();
|
||||
@@ -113,8 +111,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;
|
||||
@@ -138,7 +136,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();
|
||||
|
||||
|
||||
@@ -173,7 +173,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
|
||||
@@ -181,7 +181,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
|
||||
@@ -189,7 +189,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
|
||||
@@ -202,7 +202,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
|
||||
|
||||
@@ -62,7 +62,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;
|
||||
//
|
||||
|
||||
@@ -266,6 +266,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
|
||||
|
||||
public ConfigWindow(DockContent panel, IConnectionsService connectionsService)
|
||||
@@ -696,7 +701,6 @@ namespace mRemoteNG.UI.Window
|
||||
UpdateRootInfoNode(e);
|
||||
UpdateInheritanceNode();
|
||||
ShowHideGridItems();
|
||||
_connectionsService.SaveConnectionsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -1171,7 +1175,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");
|
||||
@@ -1213,49 +1218,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");
|
||||
@@ -1725,4 +1687,4 @@ namespace mRemoteNG.UI.Window
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ 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;
|
||||
@@ -9,6 +10,7 @@ using mRemoteNG.Connection;
|
||||
using mRemoteNG.Themes;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
// ReSharper disable ArrangeAccessorOwnerBody
|
||||
@@ -22,7 +24,8 @@ namespace mRemoteNG.UI.Window
|
||||
private ThemeManager _themeManager;
|
||||
private readonly ConnectionTreeSearchTextFilter _connectionTreeSearchTextFilter = new ConnectionTreeSearchTextFilter();
|
||||
|
||||
public ConnectionContextMenu ConnectionTreeContextMenu
|
||||
|
||||
public ConnectionContextMenu ConnectionTreeContextMenu
|
||||
{
|
||||
get { return olvConnections.ContextMenuStrip as ConnectionContextMenu;}
|
||||
set { olvConnections.ContextMenuStrip = value; }
|
||||
@@ -162,6 +165,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
|
||||
|
||||
@@ -246,13 +251,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
|
||||
{
|
||||
@@ -322,4 +324,4 @@ namespace mRemoteNG.UI.Window
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Themes;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
namespace mRemoteNG.UI.Window
|
||||
@@ -17,7 +17,7 @@ namespace mRemoteNG.UI.Window
|
||||
private ControlLayout _layout = ControlLayout.Vertical;
|
||||
private readonly ThemeManager _themeManager;
|
||||
private readonly ConnectionTreeWindow _connectionTreeWindow;
|
||||
private DockPanel _dockPanel;
|
||||
private readonly DockPanel _dockPanel;
|
||||
|
||||
public DockContent PreviousActiveForm { get; set; }
|
||||
|
||||
@@ -54,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");
|
||||
}
|
||||
|
||||
|
||||
@@ -225,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)
|
||||
@@ -292,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("----------");
|
||||
}
|
||||
@@ -340,8 +338,8 @@ namespace mRemoteNG.UI.Window
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public enum ControlLayout
|
||||
|
||||
private enum ControlLayout
|
||||
{
|
||||
Vertical = 0,
|
||||
Horizontal = 1
|
||||
|
||||
@@ -148,6 +148,19 @@ namespace mRemoteNG.UI.Window
|
||||
RunElevatedCheckBox.Checked = selectedTool?.RunElevated ?? false;
|
||||
WaitForExitCheckBox.Enabled = !TryToIntegrateCheckBox.Checked;
|
||||
}
|
||||
|
||||
private void UpdateToolstipControls()
|
||||
{
|
||||
_currentlySelectedExternalTools.Clear();
|
||||
_currentlySelectedExternalTools.AddRange(ToolsListObjView.SelectedObjects.OfType<ExternalTool>());
|
||||
PropertiesGroupBox.Enabled = _currentlySelectedExternalTools.Count == 1;
|
||||
|
||||
var atleastOneToolSelected = _currentlySelectedExternalTools.Count > 0;
|
||||
DeleteToolMenuItem.Enabled = atleastOneToolSelected;
|
||||
DeleteToolToolstripButton.Enabled = atleastOneToolSelected;
|
||||
LaunchToolMenuItem.Enabled = atleastOneToolSelected;
|
||||
LaunchToolToolstripButton.Enabled = atleastOneToolSelected;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
@@ -207,6 +220,8 @@ namespace mRemoteNG.UI.Window
|
||||
ToolsListObjView.SelectedIndex = oldSelectedIndex <= maxIndex
|
||||
? oldSelectedIndex
|
||||
: maxIndex;
|
||||
|
||||
UpdateToolstipControls();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -223,15 +238,7 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
try
|
||||
{
|
||||
_currentlySelectedExternalTools.Clear();
|
||||
_currentlySelectedExternalTools.AddRange(ToolsListObjView.SelectedObjects.OfType<ExternalTool>());
|
||||
PropertiesGroupBox.Enabled = _currentlySelectedExternalTools.Count == 1;
|
||||
|
||||
var atleastOneToolSelected = _currentlySelectedExternalTools.Count > 0;
|
||||
DeleteToolMenuItem.Enabled = atleastOneToolSelected;
|
||||
DeleteToolToolstripButton.Enabled = atleastOneToolSelected;
|
||||
LaunchToolMenuItem.Enabled = atleastOneToolSelected;
|
||||
LaunchToolToolstripButton.Enabled = atleastOneToolSelected;
|
||||
UpdateToolstipControls();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
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>
|
||||
@@ -316,6 +316,7 @@
|
||||
<Compile Include="Tools\Cmdline\StartupArgumentsInterpreter.cs" />
|
||||
<Compile Include="Tools\CustomCollections\CollectionUpdatedEventArgs.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Tools\DisposableOptional.cs" />
|
||||
<Compile Include="Tools\Extensions.cs" />
|
||||
<Compile Include="Tools\ExternalToolArgumentParser.cs" />
|
||||
<Compile Include="Tools\Cmdline\CmdArgumentsInterpreter.cs" />
|
||||
@@ -327,6 +328,9 @@
|
||||
<Compile Include="Tools\MultiSSHController.cs" />
|
||||
<Compile Include="Tools\MouseClickSimulator.cs" />
|
||||
<Compile Include="Tools\NotificationAreaIcon.cs" />
|
||||
<Compile Include="Tools\WindowsRegistry\IRegistry.cs" />
|
||||
<Compile Include="Tools\WindowsRegistry\RegistryHive.cs" />
|
||||
<Compile Include="Tools\WindowsRegistry\WindowsRegistry.cs" />
|
||||
<Compile Include="Tools\ScanHost.cs" />
|
||||
<Compile Include="Tools\SecureTransfer.cs" />
|
||||
<Compile Include="Config\Serializers\Versioning\SqlDatabaseVersionVerifier.cs" />
|
||||
@@ -1559,24 +1563,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>
|
||||
@@ -1595,6 +1601,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