mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ab221e5a8 | ||
|
|
21e51c8455 | ||
|
|
3234896caf | ||
|
|
b00dd1c5f5 | ||
|
|
992a3f9d1c | ||
|
|
d1a7a37909 | ||
|
|
1c12b52ada | ||
|
|
722fe40899 | ||
|
|
b2e7ebf43d | ||
|
|
3ed8e768aa | ||
|
|
d362691389 | ||
|
|
4b7c54d5b5 | ||
|
|
ec80a5aa70 | ||
|
|
0c95f178ca | ||
|
|
e0405b15df | ||
|
|
e029f30acf | ||
|
|
44ed836b7c | ||
|
|
00401201d1 | ||
|
|
20f46bea61 | ||
|
|
a5d22d287c | ||
|
|
793095900b | ||
|
|
f10e54e47b | ||
|
|
704e0c1dc1 | ||
|
|
0c79a9acde | ||
|
|
ebfc2715e7 | ||
|
|
b0dbc9dc18 | ||
|
|
507cdf75a5 | ||
|
|
8f8492b0be | ||
|
|
457e715188 | ||
|
|
1724521ebf | ||
|
|
b0fb3596aa | ||
|
|
fb228d72b1 | ||
|
|
916361a3be | ||
|
|
408c40f699 | ||
|
|
4173f6d775 |
@@ -1,3 +1,48 @@
|
||||
1.76.11 (2018-10-18):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1139: Feature "Reconnect to previously opened sessions" not working
|
||||
#1136: Putty window not maximized
|
||||
|
||||
|
||||
1.76.10 (2018-10-07):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1124: Enabling themes causes an exception
|
||||
|
||||
|
||||
1.76.9 (2018-10-07):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1117: Duplicate panel created when "Reconnect on Startup" and "Create Empty Panel" settings enabled
|
||||
#1115: Exception when changing from xml data storage to SQL
|
||||
#1110: Pressing Delete button during connection rename attempts to delete the connection instead of the text
|
||||
#1106: Inheritance does not work when parent has C# default type set
|
||||
#1092: Invalid Cast Exceptions loading default connectioninfo
|
||||
#1091: Minor themeing issues
|
||||
#853: Added some additional safety checks and logging to help address RDP crashes
|
||||
|
||||
|
||||
1.76.8 (2018-08-25):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#1088: Delete and Launch buttons are not disabled when last external tool deleted
|
||||
#1087: 'Save connections after every edit' setting not honored
|
||||
#1082: Connections not given GUID if Id is empty in connection xml
|
||||
|
||||
|
||||
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:
|
||||
|
||||
@@ -24,6 +24,7 @@ github.com/pfjason
|
||||
github.com/sirLoaf
|
||||
github.com/Fyers
|
||||
Vladimir Semenov (github.com/sli-pro)
|
||||
Stephan (github.com/st-schuler)
|
||||
|
||||
|
||||
Past Contributors
|
||||
|
||||
@@ -62,11 +62,10 @@ node('windows') {
|
||||
|
||||
stage ('Publish to GitHub') {
|
||||
withCredentials([string(credentialsId: '5443a369-dbe8-42d3-b4e8-04d0b4e9039a', variable: 'GH_AUTH_TOKEN')]) {
|
||||
def zipPath = "${jobDir}\\Release\\*.zip"
|
||||
def msiPath = "${jobDir}\\Release\\*.msi"
|
||||
def releaseFolder = "${jobDir}\\Release"
|
||||
// because batch files suck at handling newline characters, we have to convert to base64 in groovy and back to text in powershell
|
||||
def base64Description = env.ReleaseDescription.bytes.encodeBase64().toString()
|
||||
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\publish_to_github.ps1\" -Owner \"mRemoteNG\" -Repository \"mRemoteNG\" -ReleaseTitle \"${env.ReleaseTitle}\" -TagName \"${env.TagName}\" -TargetCommitish \"${env.TargetBranch}\" -Description \"${base64Description}\" -IsDraft ${env.IsDraft} -IsPrerelease ${env.IsPreRelease} -ZipFilePath \"${zipPath}\" -MsiFilePath \"${msiPath}\" -AuthToken \"${env.GH_AUTH_TOKEN}\" -DescriptionIsBase64Encoded"
|
||||
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\publish_to_github.ps1\" -Owner \"mRemoteNG\" -Repository \"mRemoteNG\" -ReleaseTitle \"${env.ReleaseTitle}\" -TagName \"${env.TagName}\" -TargetCommitish \"${env.TargetBranch}\" -Description \"${base64Description}\" -IsDraft ${env.IsDraft} -IsPrerelease ${env.IsPreRelease} -ReleaseFolderPath \"${releaseFolder}\" -AuthToken \"${env.GH_AUTH_TOKEN}\" -DescriptionIsBase64Encoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,17 +171,26 @@ function Upload-GitHubReleaseAsset {
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# The OAuth2 token to use for authentication.
|
||||
$AuthToken
|
||||
$AuthToken,
|
||||
|
||||
[string]
|
||||
# A short description label for the asset
|
||||
$Label = ""
|
||||
)
|
||||
|
||||
$UploadUri = $UploadUri -replace "(\{[\w,\?]*\})$"
|
||||
$files = Get-Item -Path $FilePath
|
||||
|
||||
$labelParam = ""
|
||||
if ($Label -ne "") {
|
||||
$labelParam = "&label=$Label"
|
||||
}
|
||||
|
||||
# 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
|
||||
$req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)$labelParam" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,13 +43,8 @@ param (
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# Path to the zip file to upload with the release
|
||||
$ZipFilePath,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#Path to the msi file to upload with the release
|
||||
$MsiFilePath,
|
||||
# Path to the folder which contains release assets to upload
|
||||
$ReleaseFolderPath,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
@@ -70,7 +65,17 @@ if ($DescriptionIsBase64Encoded) {
|
||||
. "$PSScriptRoot\github_functions.ps1"
|
||||
|
||||
|
||||
$releaseFolderItems = Get-ChildItem -Path $ReleaseFolderPath
|
||||
$mrngPortablePath = ($releaseFolderItems | ?{$_.Name -match "portable-[\d\.]+\.zip"}).FullName
|
||||
$mrngNormalPath = ($releaseFolderItems | ?{$_.Name -match "installer-[\d\.]+\.msi"}).FullName
|
||||
$mrngPortableSymbolsPath = ($releaseFolderItems | ?{$_.Name -match "mremoteng-portable-symbols-[\d\.]+\.zip"}).FullName
|
||||
$mrngNormalSymbolsPath = ($releaseFolderItems | ?{$_.Name -match "mremoteng-symbols-[\d\.]+\.zip"}).FullName
|
||||
|
||||
|
||||
$release = Publish-GitHubRelease -Owner $Owner -Repository $Repository -ReleaseTitle $ReleaseTitle -TagName $TagName -TargetCommitish $TargetCommitish -Description $Description -IsDraft ([bool]::Parse($IsDraft)) -IsPrerelease ([bool]::Parse($IsPrerelease)) -AuthToken $AuthToken
|
||||
$zipUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $ZipFilePath -ContentType "application/zip" -AuthToken $AuthToken
|
||||
$msiUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $MsiFilePath -ContentType "application/octet-stream" -AuthToken $AuthToken
|
||||
$zipUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngPortablePath -ContentType "application/zip" -AuthToken $AuthToken -Label "Portable Edition (zip)"
|
||||
$msiUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngNormalPath -ContentType "application/octet-stream" -AuthToken $AuthToken -Label "Normal Edition (msi)"
|
||||
|
||||
$portableEditionSymbols = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngPortableSymbolsPath -ContentType "application/zip" -AuthToken $AuthToken -Label "Portable Edition Debug Symbols"
|
||||
$normalEditionSymbols = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngNormalSymbolsPath -ContentType "application/zip" -AuthToken $AuthToken -Label "Normal Edition Debug Symbols"
|
||||
Write-Output (Get-GitHubRelease -Owner $Owner -Repository $Repository -ReleaseId $release.id -AuthToken $AuthToken)
|
||||
@@ -1,8 +1,9 @@
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using NUnit.Framework;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace mRemoteNGTests.Connection
|
||||
{
|
||||
@@ -74,6 +75,22 @@ namespace mRemoteNGTests.Connection
|
||||
Assert.That(hasEverythingInheritedProperty, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AlwaysReturnInheritedValueIfRequested()
|
||||
{
|
||||
var expectedSetting = false;
|
||||
|
||||
var container = new ContainerInfo { AutomaticResize = expectedSetting };
|
||||
var con1 = new ConnectionInfo
|
||||
{
|
||||
AutomaticResize = true,
|
||||
Inheritance = {AutomaticResize = true}
|
||||
};
|
||||
container.AddChild(con1);
|
||||
|
||||
Assert.That(con1.AutomaticResize, Is.EqualTo(expectedSetting));
|
||||
}
|
||||
|
||||
private bool AllInheritancePropertiesAreTrue()
|
||||
{
|
||||
var allPropertiesTrue = true;
|
||||
|
||||
@@ -43,6 +43,20 @@ namespace mRemoteNGTests.Connection
|
||||
Assert.That(clonedConnection.Parent, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CloneAlsoCopiesInheritanceObject()
|
||||
{
|
||||
var clonedConnection = _connectionInfo.Clone();
|
||||
Assert.That(clonedConnection.Inheritance, Is.Not.EqualTo(_connectionInfo.Inheritance));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CloneCorrectlySetsParentOfInheritanceObject()
|
||||
{
|
||||
var clonedConnection = _connectionInfo.Clone();
|
||||
Assert.That(clonedConnection.Inheritance.Parent, Is.EqualTo(clonedConnection));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFromCopiesProperties()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Config.Serializers.Xml;
|
||||
using mRemoteNG.Connection;
|
||||
@@ -29,20 +31,19 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
|
||||
new SaveFilter());
|
||||
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
|
||||
_deserializer = new XmlConnectionsDeserializer();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
_serializer = null;
|
||||
_deserializer = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeThenDeserialize()
|
||||
{
|
||||
var serializedContent = _serializer.Serialize(_originalModel);
|
||||
_deserializer = new XmlConnectionsDeserializer();
|
||||
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
||||
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
|
||||
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
|
||||
@@ -54,7 +55,6 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
{
|
||||
_serializer.UseFullEncryption = true;
|
||||
var serializedContent = _serializer.Serialize(_originalModel);
|
||||
_deserializer = new XmlConnectionsDeserializer();
|
||||
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
||||
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
|
||||
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
|
||||
@@ -66,7 +66,6 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
{
|
||||
var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" };
|
||||
var serializedContent = _serializer.Serialize(originalConnectionInfo);
|
||||
_deserializer = new XmlConnectionsDeserializer();
|
||||
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
||||
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
|
||||
Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description));
|
||||
@@ -84,13 +83,26 @@ namespace mRemoteNGTests.IntegrationTests
|
||||
new SaveFilter());
|
||||
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
|
||||
var serializedContent = _serializer.Serialize(_originalModel);
|
||||
_deserializer = new XmlConnectionsDeserializer();
|
||||
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
||||
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
|
||||
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.UI.Forms;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
@@ -44,6 +45,8 @@ namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
if (!mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit)
|
||||
return;
|
||||
if (FrmMain.Default.IsClosing)
|
||||
return;
|
||||
|
||||
_connectionsService.SaveConnectionsAsync();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -53,13 +53,14 @@ 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())
|
||||
{
|
||||
@@ -72,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
|
||||
@@ -88,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;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,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
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace mRemoteNG.Config.Settings
|
||||
{
|
||||
private readonly ExternalAppsLoader _externalAppsLoader;
|
||||
private readonly MessageCollector _messageCollector;
|
||||
private readonly MenuStrip _mainMenu;
|
||||
private readonly QuickConnectToolStrip _quickConnectToolStrip;
|
||||
private readonly ExternalToolsToolStrip _externalToolsToolStrip;
|
||||
private readonly MultiSshToolStrip _multiSshToolStrip;
|
||||
@@ -31,7 +32,8 @@ namespace mRemoteNG.Config.Settings
|
||||
MessageCollector messageCollector,
|
||||
QuickConnectToolStrip quickConnectToolStrip,
|
||||
ExternalToolsToolStrip externalToolsToolStrip,
|
||||
MultiSshToolStrip multiSshToolStrip)
|
||||
MultiSshToolStrip multiSshToolStrip,
|
||||
MenuStrip mainMenu)
|
||||
{
|
||||
if (mainForm == null)
|
||||
throw new ArgumentNullException(nameof(mainForm));
|
||||
@@ -43,13 +45,16 @@ namespace mRemoteNG.Config.Settings
|
||||
throw new ArgumentNullException(nameof(externalToolsToolStrip));
|
||||
if (multiSshToolStrip == null)
|
||||
throw new ArgumentNullException(nameof(multiSshToolStrip));
|
||||
if (mainMenu == null)
|
||||
throw new ArgumentNullException(nameof(mainMenu));
|
||||
|
||||
MainForm = mainForm;
|
||||
_messageCollector = messageCollector;
|
||||
_quickConnectToolStrip = quickConnectToolStrip;
|
||||
_externalToolsToolStrip = externalToolsToolStrip;
|
||||
_multiSshToolStrip = multiSshToolStrip;
|
||||
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
|
||||
_mainMenu = mainMenu;
|
||||
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
@@ -197,6 +202,7 @@ namespace mRemoteNG.Config.Settings
|
||||
private void LoadToolbarsFromSettings()
|
||||
{
|
||||
ResetAllToolbarLocations();
|
||||
AddMainMenuPanel();
|
||||
AddExternalAppsPanel();
|
||||
AddQuickConnectPanel();
|
||||
AddMultiSshPanel();
|
||||
@@ -210,31 +216,49 @@ namespace mRemoteNG.Config.Settings
|
||||
private void ResetAllToolbarLocations()
|
||||
{
|
||||
var tempToolStrip = new ToolStripPanel();
|
||||
tempToolStrip.Join(_mainMenu);
|
||||
tempToolStrip.Join(_quickConnectToolStrip);
|
||||
tempToolStrip.Join(_externalToolsToolStrip);
|
||||
tempToolStrip.Join(_multiSshToolStrip);
|
||||
}
|
||||
|
||||
private void AddMainMenuPanel()
|
||||
{
|
||||
SetToolstripGripStyle(_mainMenu);
|
||||
var toolStripPanel = ToolStripPanelFromString("top");
|
||||
toolStripPanel.Join(_mainMenu, new Point(3, 0));
|
||||
}
|
||||
|
||||
private void AddQuickConnectPanel()
|
||||
{
|
||||
SetToolstripGripStyle(_quickConnectToolStrip);
|
||||
_quickConnectToolStrip.Visible = mRemoteNG.Settings.Default.QuickyTBVisible;
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.QuickyTBParentDock);
|
||||
toolStripPanel.Join(_quickConnectToolStrip, mRemoteNG.Settings.Default.QuickyTBLocation);
|
||||
_quickConnectToolStrip.Visible = mRemoteNG.Settings.Default.QuickyTBVisible;
|
||||
}
|
||||
|
||||
private void AddExternalAppsPanel()
|
||||
{
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
|
||||
toolStripPanel.Join(_externalToolsToolStrip, mRemoteNG.Settings.Default.ExtAppsTBLocation);
|
||||
SetToolstripGripStyle(_externalToolsToolStrip);
|
||||
_externalToolsToolStrip.Visible = mRemoteNG.Settings.Default.ExtAppsTBVisible;
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
|
||||
toolStripPanel.Join(_externalToolsToolStrip, mRemoteNG.Settings.Default.ExtAppsTBLocation);
|
||||
}
|
||||
|
||||
private void AddMultiSshPanel()
|
||||
{
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
|
||||
toolStripPanel.Join(_multiSshToolStrip, mRemoteNG.Settings.Default.MultiSshToolbarLocation);
|
||||
SetToolstripGripStyle(_multiSshToolStrip);
|
||||
_multiSshToolStrip.Visible = mRemoteNG.Settings.Default.MultiSshToolbarVisible;
|
||||
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.MultiSshToolbarParentDock);
|
||||
toolStripPanel.Join(_multiSshToolStrip, mRemoteNG.Settings.Default.MultiSshToolbarLocation);
|
||||
}
|
||||
|
||||
private void SetToolstripGripStyle(ToolStrip toolbar)
|
||||
{
|
||||
toolbar.GripStyle = mRemoteNG.Settings.Default.LockToolbars
|
||||
? ToolStripGripStyle.Hidden
|
||||
: ToolStripGripStyle.Visible;
|
||||
}
|
||||
|
||||
private ToolStripPanel ToolStripPanelFromString(string panel)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.Http;
|
||||
@@ -15,11 +10,16 @@ using mRemoteNG.Connection.Protocol.Telnet;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
{
|
||||
[DefaultProperty("Name")]
|
||||
[DefaultProperty("Name")]
|
||||
public class ConnectionInfo : AbstractConnectionRecord, IHasParent, IInheritable
|
||||
{
|
||||
#region Public Properties
|
||||
@@ -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)
|
||||
@@ -172,8 +173,11 @@ namespace mRemoteNG.Connection
|
||||
if (!ShouldThisPropertyBeInherited(propertyName))
|
||||
return value;
|
||||
|
||||
var inheritedValue = GetInheritedPropertyValue<TPropertyType>(propertyName);
|
||||
return inheritedValue.Equals(default(TPropertyType)) ? value : inheritedValue;
|
||||
var couldGetInheritedValue = TryGetInheritedPropertyValue<TPropertyType>(propertyName, out var inheritedValue);
|
||||
|
||||
return couldGetInheritedValue
|
||||
? inheritedValue
|
||||
: value;
|
||||
}
|
||||
|
||||
private bool ShouldThisPropertyBeInherited(string propertyName)
|
||||
@@ -194,22 +198,23 @@ namespace mRemoteNG.Connection
|
||||
return inheritPropertyValue;
|
||||
}
|
||||
|
||||
private TPropertyType GetInheritedPropertyValue<TPropertyType>(string propertyName)
|
||||
private bool TryGetInheritedPropertyValue<TPropertyType>(string propertyName, out TPropertyType inheritedValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
var connectionInfoType = Parent.GetType();
|
||||
var parentPropertyInfo = connectionInfoType.GetProperty(propertyName);
|
||||
if (parentPropertyInfo == null)
|
||||
return default(TPropertyType); // shouldn't get here...
|
||||
var parentPropertyValue = (TPropertyType)parentPropertyInfo.GetValue(Parent, null);
|
||||
throw new NullReferenceException($"Could not retrieve property data for property '{propertyName}' on parent node '{Parent?.Name}'");
|
||||
|
||||
return parentPropertyValue;
|
||||
inheritedValue = (TPropertyType)parentPropertyInfo.GetValue(Parent, null);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace($"Error retrieving inherited property '{propertyName}'", e);
|
||||
return default(TPropertyType);
|
||||
inheritedValue = default(TPropertyType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
try
|
||||
{
|
||||
filename.ThrowIfNullOrEmpty(nameof(filename));
|
||||
var newConnectionsModel = new ConnectionTreeModel();
|
||||
newConnectionsModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection));
|
||||
SaveConnections(newConnectionsModel, false, new SaveFilter(), filename, true);
|
||||
@@ -130,11 +131,22 @@ namespace mRemoteNG.Connection
|
||||
RaiseConnectionsLoadedEvent(oldConnectionTreeModel, newConnectionTreeModel, oldIsUsingDatabaseValue, useDatabase, connectionFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When turned on, calls to <see cref="SaveConnections()"/> or
|
||||
/// <see cref="SaveConnectionsAsync"/> will not immediately execute.
|
||||
/// Instead, they will be deferred until <see cref="EndBatchingSaves"/>
|
||||
/// is called.
|
||||
/// </summary>
|
||||
public void BeginBatchingSaves()
|
||||
{
|
||||
_batchingSaves = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immediately executes a single <see cref="SaveConnections()"/> or
|
||||
/// <see cref="SaveConnectionsAsync"/> if one has been requested
|
||||
/// since calling <see cref="BeginBatchingSaves"/>.
|
||||
/// </summary>
|
||||
public void EndBatchingSaves()
|
||||
{
|
||||
_batchingSaves = false;
|
||||
@@ -221,9 +233,10 @@ namespace mRemoteNG.Connection
|
||||
|
||||
private void SaveConnectionsBGd()
|
||||
{
|
||||
Monitor.Enter(SaveLock);
|
||||
SaveConnections();
|
||||
Monitor.Exit(SaveLock);
|
||||
lock (SaveLock)
|
||||
{
|
||||
SaveConnections();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStartupConnectionFileName()
|
||||
|
||||
@@ -31,9 +31,14 @@ namespace mRemoteNG.Connection
|
||||
throw new SettingsPropertyNotFoundException($"No property with name '{expectedPropertyName}' found.");
|
||||
|
||||
var valueFromSource = propertyFromSource.GetValue(sourceInstance, null);
|
||||
var value = Convert.ChangeType(valueFromSource, property.PropertyType);
|
||||
|
||||
if (property.PropertyType.IsEnum)
|
||||
{
|
||||
property.SetValue(Instance, Enum.Parse(property.PropertyType, valueFromSource.ToString()), null);
|
||||
continue;
|
||||
}
|
||||
|
||||
property.SetValue(Instance, value, null);
|
||||
property.SetValue(Instance, Convert.ChangeType(valueFromSource, property.PropertyType), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -199,7 +199,14 @@ namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
return;
|
||||
}
|
||||
NativeMethods.MoveWindow(PuttyHandle, -SystemInformation.FrameBorderSize.Width, -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height), InterfaceControl.Width + SystemInformation.FrameBorderSize.Width * 2, InterfaceControl.Height + SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height * 2, true);
|
||||
|
||||
var left = -(SystemInformation.FrameBorderSize.Width + SystemInformation.HorizontalResizeBorderThickness);
|
||||
var top = -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height + SystemInformation.VerticalResizeBorderThickness);
|
||||
var width = InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width + SystemInformation.HorizontalResizeBorderThickness) * 2;
|
||||
var height = InterfaceControl.Height + SystemInformation.CaptionHeight +
|
||||
(SystemInformation.FrameBorderSize.Height + SystemInformation.VerticalResizeBorderThickness) * 2;
|
||||
|
||||
NativeMethods.MoveWindow(PuttyHandle, left, top, width, height, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -316,10 +316,19 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
return;
|
||||
}
|
||||
|
||||
var size = !Fullscreen ? Control.Size : Screen.FromControl(Control).Bounds.Size;
|
||||
try
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Resizing RDP connection to host '{_connectionInfo.Hostname}'");
|
||||
var size = !Fullscreen ? Control.Size : Screen.FromControl(Control).Bounds.Size;
|
||||
|
||||
IMsRdpClient8 msRdpClient8 = _rdpClient;
|
||||
msRdpClient8.Reconnect((uint)size.Width, (uint)size.Height);
|
||||
IMsRdpClient8 msRdpClient8 = _rdpClient;
|
||||
msRdpClient8.Reconnect((uint)size.Width, (uint)size.Height);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(string.Format(Language.ChangeConnectionResolutionError, _connectionInfo.Hostname),
|
||||
ex, MessageClass.WarningMsg, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetRdGateway()
|
||||
@@ -916,17 +925,25 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
#region Reconnect Stuff
|
||||
public void tmrReconnect_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
var srvReady = PortScanner.IsPortOpen(_connectionInfo.Hostname, Convert.ToString(_connectionInfo.Port));
|
||||
try
|
||||
{
|
||||
var srvReady = PortScanner.IsPortOpen(_connectionInfo.Hostname, Convert.ToString(_connectionInfo.Port));
|
||||
|
||||
ReconnectGroup.ServerReady = srvReady;
|
||||
ReconnectGroup.ServerReady = srvReady;
|
||||
|
||||
if (ReconnectGroup.ReconnectWhenReady && srvReady)
|
||||
{
|
||||
tmrReconnect.Enabled = false;
|
||||
ReconnectGroup.DisposeReconnectGroup();
|
||||
//SetProps()
|
||||
_rdpClient.Connect();
|
||||
}
|
||||
if (ReconnectGroup.ReconnectWhenReady && srvReady)
|
||||
{
|
||||
tmrReconnect.Enabled = false;
|
||||
ReconnectGroup.DisposeReconnectGroup();
|
||||
//SetProps()
|
||||
_rdpClient.Connect();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(string.Format(Language.AutomaticReconnectError, _connectionInfo.Hostname),
|
||||
ex, MessageClass.WarningMsg, false);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
[assembly: AssemblyVersion("1.76.6.*")]
|
||||
[assembly: AssemblyVersion("1.76.11.*")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
18
mRemoteV1/Resources/Language/Language.Designer.cs
generated
18
mRemoteV1/Resources/Language/Language.Designer.cs
generated
@@ -60,6 +60,24 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An error occurred while trying to reconnect to RDP host '{0}'.
|
||||
/// </summary>
|
||||
internal static string AutomaticReconnectError {
|
||||
get {
|
||||
return ResourceManager.GetString("AutomaticReconnectError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An error occurred while trying to change the connection resolution to host '{0}'.
|
||||
/// </summary>
|
||||
internal static string ChangeConnectionResolutionError {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangeConnectionResolutionError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Create a New Connection File.
|
||||
/// </summary>
|
||||
|
||||
@@ -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>Acerca de</value>
|
||||
@@ -1224,7 +1224,7 @@ Ver el articulo de soporte de Microsoft en http://support.microsoft.com/kb/81183
|
||||
<value>Introduzca su dominio.</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionEnableDesktopComposition" xml:space="preserve">
|
||||
<value>Seleccione si emplear composición de escrotorio o no.</value>
|
||||
<value>Seleccione si emplear composición de escritorio o no.</value>
|
||||
</data>
|
||||
<data name="strPropertyDescriptionEnableFontSmoothing" xml:space="preserve">
|
||||
<value>Seleccione si emplear suavizado de fuentes o no.</value>
|
||||
@@ -2069,4 +2069,4 @@ mRemoteNG ahora se cerrará y comenzará la instalación.</value>
|
||||
<data name="strYes" xml:space="preserve">
|
||||
<value>Sí</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
@@ -2694,4 +2694,10 @@ This page will walk you through the process of upgrading your connections file o
|
||||
<data name="strUltraVNCSingleClick" xml:space="preserve">
|
||||
<value>UltraVNC SingleClick</value>
|
||||
</data>
|
||||
<data name="AutomaticReconnectError" xml:space="preserve">
|
||||
<value>An error occurred while trying to reconnect to RDP host '{0}'</value>
|
||||
</data>
|
||||
<data name="ChangeConnectionResolutionError" xml:space="preserve">
|
||||
<value>An error occurred while trying to change the connection resolution to host '{0}'</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -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
|
||||
|
||||
@@ -23,10 +23,12 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
{
|
||||
base.OnCreateControl();
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
if (_themeManager.ThemingActive)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
// Use the Dialog_* colors since Labels generally have the same colors as panels/dialogs/windows/etc...
|
||||
BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
FontOverrider.FontOverride(this);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +40,9 @@ namespace mRemoteNG.UI.Controls.Base
|
||||
return;
|
||||
}
|
||||
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
// let's use the defaults - this looks terrible in my testing....
|
||||
//e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
//e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
if (Enabled)
|
||||
{
|
||||
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
||||
|
||||
@@ -220,14 +220,19 @@ namespace mRemoteNG.UI.Controls
|
||||
return (RootNodeInfo)ConnectionTreeModel.RootNodes.First(item => item is RootNodeInfo);
|
||||
}
|
||||
|
||||
public void Invoke(Action action)
|
||||
{
|
||||
Invoke((Delegate)action);
|
||||
}
|
||||
|
||||
public void InvokeExpand(object model)
|
||||
{
|
||||
Invoke((MethodInvoker)(() => Expand(model)));
|
||||
Invoke(() => Expand(model));
|
||||
}
|
||||
|
||||
public void InvokeRebuildAll(bool preserveState)
|
||||
{
|
||||
Invoke((MethodInvoker)(() => RebuildAll(preserveState)));
|
||||
Invoke(() => RebuildAll(preserveState));
|
||||
}
|
||||
|
||||
public IEnumerable<RootPuttySessionsNodeInfo> GetRootPuttyNodes()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Themes;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.UI.Controls
|
||||
@@ -10,12 +11,16 @@ namespace mRemoteNG.UI.Controls
|
||||
private ToolStripLabel _lblMultiSsh;
|
||||
private ToolStripTextBox _txtMultiSsh;
|
||||
private MultiSSHController _multiSshController;
|
||||
private ThemeManager _themeManager;
|
||||
|
||||
|
||||
public MultiSshToolStrip()
|
||||
public MultiSshToolStrip()
|
||||
{
|
||||
InitializeComponent();
|
||||
_multiSshController = new MultiSSHController(_txtMultiSsh);
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
_themeManager.ThemeChanged += ApplyTheme;
|
||||
ApplyTheme();
|
||||
_multiSshController = new MultiSSHController(_txtMultiSsh);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
@@ -43,7 +48,14 @@ namespace mRemoteNG.UI.Controls
|
||||
ResumeLayout(true);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
private void ApplyTheme()
|
||||
{
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
_txtMultiSsh.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background");
|
||||
_txtMultiSsh.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground");
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace mRemoteNG.UI.Forms
|
||||
//Theming support
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
vsToolStripExtender.DefaultRenderer = _toolStripProfessionalRenderer;
|
||||
SetSchema();
|
||||
ApplyTheme();
|
||||
|
||||
_screenSystemMenu = new ScreenSelectionSystemMenu(this);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ namespace mRemoteNG.UI.Forms
|
||||
Startup.Instance.InitializeProgram(messageCollector);
|
||||
|
||||
msMain.Location = Point.Empty;
|
||||
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip);
|
||||
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, msMain);
|
||||
settingsLoader.LoadSettings();
|
||||
|
||||
SetMenuDependencies();
|
||||
@@ -184,7 +184,10 @@ namespace mRemoteNG.UI.Forms
|
||||
var panelName = !string.IsNullOrEmpty(Settings.Default.StartUpPanelName)
|
||||
? Settings.Default.StartUpPanelName
|
||||
: Language.strNewPanel;
|
||||
new PanelAdder().AddPanel(panelName);
|
||||
|
||||
var panelAdder = new PanelAdder();
|
||||
if (!panelAdder.DoesPanelExist(panelName))
|
||||
panelAdder.AddPanel(panelName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,22 +250,37 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
|
||||
//Theming support
|
||||
private void SetSchema()
|
||||
{
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
// Persist settings when rebuilding UI
|
||||
pnlDock.Theme = _themeManager.ActiveTheme.Theme;
|
||||
ApplyTheme();
|
||||
}
|
||||
private void ApplyTheme()
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// this will always throw when turning themes on from
|
||||
// the options menu.
|
||||
pnlDock.Theme = _themeManager.ActiveTheme.Theme;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// intentionally ignore exception
|
||||
}
|
||||
|
||||
// Persist settings when rebuilding UI
|
||||
try
|
||||
{
|
||||
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");
|
||||
BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("Error applying theme", ex, MessageClass.WarningMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private void frmMain_Shown(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Messages;
|
||||
@@ -30,6 +31,12 @@ namespace mRemoteNG.UI.Panels
|
||||
}
|
||||
}
|
||||
|
||||
public bool DoesPanelExist(string panelName)
|
||||
{
|
||||
return Runtime.WindowList?.OfType<ConnectionWindow>().Any(w => w.TabText == panelName)
|
||||
?? false;
|
||||
}
|
||||
|
||||
private static void ShowConnectionWindow(ConnectionWindow connectionForm)
|
||||
{
|
||||
connectionForm.Show(FrmMain.Default.pnlDock, DockState.Document);
|
||||
|
||||
@@ -25,24 +25,22 @@ namespace mRemoteNG.UI.Window
|
||||
internal Controls.Base.NGLabel lblEdition;
|
||||
internal Controls.Base.NGLabel lblCredits;
|
||||
internal Controls.Base.NGTextBox txtCredits;
|
||||
private Controls.Base.NGTextBox verText;
|
||||
internal Panel pnlTop;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.pnlTop = new System.Windows.Forms.Panel();
|
||||
this.lblEdition = new Controls.Base.NGLabel();
|
||||
this.lblEdition = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.pbLogo = new System.Windows.Forms.PictureBox();
|
||||
this.pnlBottom = new System.Windows.Forms.Panel();
|
||||
this.verText = new Controls.Base.NGTextBox();
|
||||
this.lblCredits = new Controls.Base.NGLabel();
|
||||
this.txtCredits = new Controls.Base.NGTextBox();
|
||||
this.txtChangeLog = new Controls.Base.NGTextBox();
|
||||
this.lblTitle = new Controls.Base.NGLabel();
|
||||
this.lblVersion = new Controls.Base.NGLabel();
|
||||
this.lblChangeLog = new Controls.Base.NGLabel();
|
||||
this.lblLicense = new Controls.Base.NGLabel();
|
||||
this.lblCopyright = new Controls.Base.NGLabel();
|
||||
this.lblCredits = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.txtCredits = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
this.txtChangeLog = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
this.lblTitle = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblVersion = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblChangeLog = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblLicense = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.lblCopyright = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.pnlTop.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pbLogo)).BeginInit();
|
||||
this.pnlBottom.SuspendLayout();
|
||||
@@ -91,7 +89,6 @@ namespace mRemoteNG.UI.Window
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.pnlBottom.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.pnlBottom.Controls.Add(this.verText);
|
||||
this.pnlBottom.Controls.Add(this.lblCredits);
|
||||
this.pnlBottom.Controls.Add(this.txtCredits);
|
||||
this.pnlBottom.Controls.Add(this.txtChangeLog);
|
||||
@@ -106,18 +103,6 @@ namespace mRemoteNG.UI.Window
|
||||
this.pnlBottom.Size = new System.Drawing.Size(1121, 559);
|
||||
this.pnlBottom.TabIndex = 1;
|
||||
//
|
||||
// verText
|
||||
//
|
||||
this.verText.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.verText.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.verText.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.verText.Location = new System.Drawing.Point(69, 51);
|
||||
this.verText.Name = "verText";
|
||||
this.verText.Size = new System.Drawing.Size(147, 20);
|
||||
this.verText.TabIndex = 12;
|
||||
this.verText.TabStop = false;
|
||||
this.verText.Text = "w.x.y.z";
|
||||
//
|
||||
// lblCredits
|
||||
//
|
||||
this.lblCredits.AutoSize = true;
|
||||
@@ -275,14 +260,16 @@ namespace mRemoteNG.UI.Window
|
||||
|
||||
private new void ApplyTheme()
|
||||
{
|
||||
if (Themes.ThemeManager.getInstance().ThemingActive)
|
||||
{
|
||||
base.ApplyTheme();
|
||||
pnlBottom.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlBottom.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlTop.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlTop.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
if (!Themes.ThemeManager.getInstance().ThemingActive) return;
|
||||
base.ApplyTheme();
|
||||
BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlBottom.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlBottom.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlTop.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlTop.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
lblEdition.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
lblEdition.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
|
||||
private void ApplyEditions()
|
||||
@@ -329,8 +316,7 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
lblCopyright.Text = GeneralAppInfo.Copyright;
|
||||
|
||||
lblVersion.Text = @"Version ";
|
||||
verText.Text = GeneralAppInfo.ApplicationVersion;
|
||||
lblVersion.Text = $@"Version {GeneralAppInfo.ApplicationVersion}";
|
||||
|
||||
if (File.Exists(GeneralAppInfo.HomePath + "\\CHANGELOG.TXT"))
|
||||
{
|
||||
|
||||
@@ -399,6 +399,8 @@ namespace mRemoteNG.UI.Window
|
||||
WindowType = WindowType.ComponentsCheck;
|
||||
DockPnl = new DockContent();
|
||||
InitializeComponent();
|
||||
FontOverrider.FontOverride(this);
|
||||
Themes.ThemeManager.getInstance().ThemeChanged += ApplyTheme;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -406,6 +408,7 @@ namespace mRemoteNG.UI.Window
|
||||
private void ComponentsCheck_Load(object sender, EventArgs e)
|
||||
{
|
||||
ApplyLanguage();
|
||||
ApplyTheme();
|
||||
chkAlwaysShow.Checked = Settings.Default.StartupComponentsCheck;
|
||||
CheckComponents();
|
||||
}
|
||||
@@ -418,6 +421,24 @@ namespace mRemoteNG.UI.Window
|
||||
btnCheckAgain.Text = Language.strCcCheckAgain;
|
||||
}
|
||||
|
||||
private new void ApplyTheme()
|
||||
{
|
||||
if (!Themes.ThemeManager.getInstance().ThemingActive) return;
|
||||
base.ApplyTheme();
|
||||
pnlCheck1.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlCheck1.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlCheck2.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlCheck2.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlCheck3.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlCheck3.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlCheck4.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlCheck4.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlCheck5.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlCheck5.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
pnlChecks.BackColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Background");
|
||||
pnlChecks.ForeColor = Themes.ThemeManager.getInstance().ActiveTheme.ExtendedPalette.getColor("Dialog_Foreground");
|
||||
}
|
||||
|
||||
private void btnCheckAgain_Click(object sender, EventArgs e)
|
||||
{
|
||||
CheckComponents();
|
||||
|
||||
@@ -706,7 +706,6 @@ namespace mRemoteNG.UI.Window
|
||||
UpdateRootInfoNode(e);
|
||||
UpdateInheritanceNode();
|
||||
ShowHideGridItems();
|
||||
Runtime.ConnectionsService.SaveConnectionsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
public partial class ConnectionTreeWindow
|
||||
{
|
||||
private readonly ConnectionContextMenu _contextMenu;
|
||||
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
|
||||
private ThemeManager _themeManager;
|
||||
|
||||
@@ -39,8 +38,6 @@ namespace mRemoteNG.UI.Window
|
||||
WindowType = WindowType.Tree;
|
||||
DockPnl = panel;
|
||||
InitializeComponent();
|
||||
_contextMenu = new ConnectionContextMenu(olvConnections);
|
||||
olvConnections.ContextMenuStrip = _contextMenu;
|
||||
SetMenuEventHandlers();
|
||||
SetConnectionTreeEventHandlers();
|
||||
Settings.Default.PropertyChanged += OnAppSettingsChanged;
|
||||
@@ -92,7 +89,7 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
vsToolStripExtender.SetStyle(msMain, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(_contextMenu, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(olvConnections.ContextMenuStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
//Treelistview need to be manually themed
|
||||
olvConnections.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TreeView_Background");
|
||||
olvConnections.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TreeView_Foreground");
|
||||
@@ -158,6 +155,12 @@ namespace mRemoteNG.UI.Window
|
||||
|
||||
private void ConnectionsServiceOnConnectionsLoaded(object o, ConnectionsLoadedEventArgs connectionsLoadedEventArgs)
|
||||
{
|
||||
if (olvConnections.InvokeRequired)
|
||||
{
|
||||
olvConnections.Invoke(() => ConnectionsServiceOnConnectionsLoaded(o, connectionsLoadedEventArgs));
|
||||
return;
|
||||
}
|
||||
|
||||
olvConnections.ConnectionTreeModel = connectionsLoadedEventArgs.NewConnectionTreeModel;
|
||||
olvConnections.SelectedObject = connectionsLoadedEventArgs.NewConnectionTreeModel.RootNodes
|
||||
.OfType<RootNodeInfo>().FirstOrDefault();
|
||||
|
||||
@@ -134,6 +134,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
|
||||
@@ -193,6 +206,8 @@ namespace mRemoteNG.UI.Window
|
||||
ToolsListObjView.SelectedIndex = oldSelectedIndex <= maxIndex
|
||||
? oldSelectedIndex
|
||||
: maxIndex;
|
||||
|
||||
UpdateToolstipControls();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -209,15 +224,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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user