mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Merge pull request #1389 from mRemoteNG/refactor_config_window
Refactored config window to make property management easier
This commit is contained in:
@@ -53,7 +53,8 @@ namespace mRemoteNGTests.Connection
|
||||
[Test]
|
||||
public void CloneCorrectlySetsParentOfInheritanceObject()
|
||||
{
|
||||
var clonedConnection = _connectionInfo.Clone();
|
||||
var originalConnection = new ConnectionInfo();
|
||||
var clonedConnection = originalConnection.Clone();
|
||||
Assert.That(clonedConnection.Inheritance.Parent, Is.EqualTo(clonedConnection));
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ namespace mRemoteNGTests.Connection
|
||||
{
|
||||
public static IEnumerable<PropertyInfo> GetProperties()
|
||||
{
|
||||
return new ConnectionInfoInheritance(new object()).GetProperties();
|
||||
return new ConnectionInfoInheritance(new ConnectionInfo()).GetProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace mRemoteNGTests.Connection
|
||||
[TestCaseSource(nameof(GetInheritanceProperties))]
|
||||
public void LoadingDefaultInheritanceUpdatesAllProperties(PropertyInfo property)
|
||||
{
|
||||
var inheritanceSource = new ConnectionInfoInheritance(new object(), true);
|
||||
var inheritanceSource = new ConnectionInfoInheritance(new ConnectionInfo(), true);
|
||||
inheritanceSource.TurnOnInheritanceCompletely();
|
||||
DefaultConnectionInheritance.Instance.TurnOffInheritanceCompletely();
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace mRemoteNGTests.Connection
|
||||
[TestCaseSource(nameof(GetInheritanceProperties))]
|
||||
public void SavingDefaultInheritanceExportsAllProperties(PropertyInfo property)
|
||||
{
|
||||
var saveTarget = new ConnectionInfoInheritance(new object(), true);
|
||||
var saveTarget = new ConnectionInfoInheritance(new ConnectionInfo(), true);
|
||||
saveTarget.TurnOffInheritanceCompletely();
|
||||
DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely();
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace mRemoteNGTests.Connection
|
||||
public void NewInheritanceInstancesCreatedWithDefaultInheritanceValues()
|
||||
{
|
||||
DefaultConnectionInheritance.Instance.Domain = true;
|
||||
var inheritanceInstance = new ConnectionInfoInheritance(new object());
|
||||
var inheritanceInstance = new ConnectionInfoInheritance(new ConnectionInfo());
|
||||
Assert.That(inheritanceInstance.Domain, Is.True);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace mRemoteNGTests.Connection
|
||||
public void NewInheritanceInstancesCreatedWithAllDefaultInheritanceValues(PropertyInfo property)
|
||||
{
|
||||
DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely();
|
||||
var inheritanceInstance = new ConnectionInfoInheritance(new object());
|
||||
var inheritanceInstance = new ConnectionInfoInheritance(new ConnectionInfo());
|
||||
|
||||
var valueInDestination = property.GetValue(inheritanceInstance);
|
||||
var valueInSource = property.GetValue(DefaultConnectionInheritance.Instance);
|
||||
@@ -57,7 +57,7 @@ namespace mRemoteNGTests.Connection
|
||||
|
||||
private static IEnumerable<PropertyInfo> GetInheritanceProperties()
|
||||
{
|
||||
return new ConnectionInfoInheritance(new object(), true).GetProperties();
|
||||
return new ConnectionInfoInheritance(new ConnectionInfo(), true).GetProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +1,17 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.Http;
|
||||
using mRemoteNG.Connection.Protocol.ICA;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
|
||||
namespace mRemoteNGTests.TestHelpers
|
||||
{
|
||||
internal static class ConnectionInfoHelpers
|
||||
internal static class ConnectionInfoHelpers
|
||||
{
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="ConnectionInfo"/> object with randomized
|
||||
/// values in all fields.
|
||||
/// </summary>
|
||||
internal static ConnectionInfo GetRandomizedConnectionInfo(bool randomizeInheritance = false)
|
||||
{
|
||||
var connectionInfo = new ConnectionInfo
|
||||
{
|
||||
// string types
|
||||
Name = RandomString(),
|
||||
Hostname = RandomString(),
|
||||
Description = RandomString(),
|
||||
Domain = RandomString(),
|
||||
ExtApp = RandomString(),
|
||||
Icon = RandomString(),
|
||||
LoadBalanceInfo = RandomString(),
|
||||
MacAddress = RandomString(),
|
||||
Panel = RandomString(),
|
||||
Password = RandomString(),
|
||||
PostExtApp = RandomString(),
|
||||
PreExtApp = RandomString(),
|
||||
PuttySession = RandomString(),
|
||||
RDGatewayHostname = RandomString(),
|
||||
RDGatewayUsername = RandomString(),
|
||||
RDGatewayDomain = RandomString(),
|
||||
RDGatewayPassword = RandomString(),
|
||||
UserField = RandomString(),
|
||||
Username = RandomString(),
|
||||
VNCProxyIP = RandomString(),
|
||||
VNCProxyPassword = RandomString(),
|
||||
VNCProxyUsername = RandomString(),
|
||||
|
||||
// bool types
|
||||
AutomaticResize = RandomBool(),
|
||||
CacheBitmaps = RandomBool(),
|
||||
DisplayThemes = RandomBool(),
|
||||
DisplayWallpaper = RandomBool(),
|
||||
EnableDesktopComposition = RandomBool(),
|
||||
EnableFontSmoothing = RandomBool(),
|
||||
IsContainer = RandomBool(),
|
||||
IsDefault = RandomBool(),
|
||||
IsQuickConnect = RandomBool(),
|
||||
PleaseConnect = RandomBool(),
|
||||
RDPAlertIdleTimeout = RandomBool(),
|
||||
RedirectDiskDrives = RandomBool(),
|
||||
RedirectKeys = RandomBool(),
|
||||
RedirectPorts = RandomBool(),
|
||||
RedirectPrinters = RandomBool(),
|
||||
RedirectSmartCards = RandomBool(),
|
||||
UseConsoleSession = RandomBool(),
|
||||
UseCredSsp = RandomBool(),
|
||||
VNCViewOnly = RandomBool(),
|
||||
Favorite = RandomBool(),
|
||||
|
||||
// ints
|
||||
Port = RandomInt(),
|
||||
RDPMinutesToIdleTimeout = RandomInt(),
|
||||
VNCProxyPort = RandomInt(),
|
||||
|
||||
// enums
|
||||
Colors = RandomEnum<RdpProtocol.RDPColors>(),
|
||||
ICAEncryptionStrength = RandomEnum<IcaProtocol.EncryptionStrength> (),
|
||||
Protocol = RandomEnum<ProtocolType>(),
|
||||
RDGatewayUsageMethod = RandomEnum<RdpProtocol.RDGatewayUsageMethod>(),
|
||||
RDGatewayUseConnectionCredentials = RandomEnum<RdpProtocol.RDGatewayUseConnectionCredentials>(),
|
||||
RDPAuthenticationLevel = RandomEnum<RdpProtocol.AuthenticationLevel>(),
|
||||
RedirectSound = RandomEnum<RdpProtocol.RDPSounds>(),
|
||||
RenderingEngine = RandomEnum<HTTPBase.RenderingEngine>(),
|
||||
Resolution = RandomEnum<RdpProtocol.RDPResolutions>(),
|
||||
SoundQuality = RandomEnum<RdpProtocol.RDPSoundQuality>(),
|
||||
VNCAuthMode = RandomEnum<ProtocolVNC.AuthMode>(),
|
||||
VNCColors = RandomEnum<ProtocolVNC.Colors>(),
|
||||
VNCCompression = RandomEnum<ProtocolVNC.Compression>(),
|
||||
VNCEncoding = RandomEnum<ProtocolVNC.Encoding>(),
|
||||
VNCProxyType = RandomEnum<ProtocolVNC.ProxyType>(),
|
||||
VNCSmartSizeMode = RandomEnum<ProtocolVNC.SmartSizeMode>(),
|
||||
};
|
||||
var connectionInfo = new ConnectionInfo().RandomizeValues();
|
||||
|
||||
if (randomizeInheritance)
|
||||
connectionInfo.Inheritance = GetRandomizedInheritance(connectionInfo);
|
||||
@@ -96,38 +19,24 @@ namespace mRemoteNGTests.TestHelpers
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
internal static ContainerInfo GetRandomizedContainerInfo(bool randomizeInheritance = false)
|
||||
{
|
||||
var containerInfo = new ContainerInfo().RandomizeValues();
|
||||
|
||||
if (randomizeInheritance)
|
||||
containerInfo.Inheritance = GetRandomizedInheritance(containerInfo);
|
||||
|
||||
return containerInfo;
|
||||
}
|
||||
|
||||
internal static ConnectionInfoInheritance GetRandomizedInheritance(ConnectionInfo parent)
|
||||
{
|
||||
var inheritance = new ConnectionInfoInheritance(parent, true);
|
||||
foreach (var property in inheritance.GetProperties())
|
||||
{
|
||||
property.SetValue(inheritance, RandomBool());
|
||||
property.SetValue(inheritance, Randomizer.RandomBool());
|
||||
}
|
||||
return inheritance;
|
||||
}
|
||||
|
||||
internal static string RandomString()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
internal static bool RandomBool()
|
||||
{
|
||||
return _random.Next() % 2 == 0;
|
||||
}
|
||||
|
||||
internal static int RandomInt()
|
||||
{
|
||||
return _random.Next();
|
||||
}
|
||||
|
||||
internal static T RandomEnum<T>() where T : struct, IConvertible
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new ArgumentException("T must be an enum");
|
||||
|
||||
var values = Enum.GetValues(typeof(T));
|
||||
return (T)values.GetValue(_random.Next(values.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using Enum = System.Enum;
|
||||
|
||||
namespace mRemoteNGTests.TestHelpers
|
||||
{
|
||||
internal static class Randomizer
|
||||
internal static class Randomizer
|
||||
{
|
||||
private static readonly Random Random = new Random();
|
||||
|
||||
@@ -98,7 +98,8 @@ namespace mRemoteNGTests.TestHelpers
|
||||
if (opByType.TryGetValue(property.PropertyType, out var mutator))
|
||||
mutator(property, con);
|
||||
|
||||
else if (opByType.TryGetValue(property.PropertyType.BaseType, out var mutator2))
|
||||
else if (property.PropertyType.BaseType != null &&
|
||||
opByType.TryGetValue(property.PropertyType.BaseType, out var mutator2))
|
||||
mutator2(property, con);
|
||||
}
|
||||
|
||||
|
||||
133
mRemoteNGTests/UI/Controls/FilteredPropertyGridTests.cs
Normal file
133
mRemoteNGTests/UI/Controls/FilteredPropertyGridTests.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using mRemoteNG.UI.Controls.FilteredPropertyGrid;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Controls
|
||||
{
|
||||
public class FilteredPropertyGridTests
|
||||
{
|
||||
[Test]
|
||||
public void AllPropertiesVisibleByDefault()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new {Prop1 = "hello"};
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
Assert.That(grid.VisibleProperties, Is.EquivalentTo(new []{ nameof(obj.Prop1) }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PropertiesOnTheHiddenPropertiesListAreNotShown()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = "world" };
|
||||
grid.HiddenProperties = new[] { nameof(obj.Prop1) };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
Assert.That(grid.VisibleProperties, Is.EquivalentTo(new[] { nameof(obj.Prop2) }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnlyPropertiesOnTheBrowsablePropertiesListAreShown()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = "world" };
|
||||
grid.BrowsableProperties = new[] { nameof(obj.Prop1) };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
Assert.That(grid.VisibleProperties, Is.EquivalentTo(new[] { nameof(obj.Prop1) }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void APropertyOnBothTheBrowsableAndHiddenListWillNotBeShown()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = "world", Prop3 = "!" };
|
||||
grid.BrowsableProperties = new[] { nameof(obj.Prop1), nameof(obj.Prop2) };
|
||||
grid.HiddenProperties = new[] { nameof(obj.Prop1) };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
Assert.That(grid.VisibleProperties, Is.EquivalentTo(new[] { nameof(obj.Prop2) }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExceptionThrownWhenNonExistantPropertyFoundInBrowsablePropertiesList()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello" };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
grid.BrowsableProperties = new[] {"NonExistantProperty"});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HiddenPropertiesListCanHandleNonExistentProperties()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello" };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
Assert.DoesNotThrow(() => grid.HiddenProperties = new[] { "NonExistantProperty" });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetVisibleGridItemsReturnsAllExpandedItems()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = new{Prop3 = "world"} };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
var visibleGridItems = grid.GetVisibleGridItems();
|
||||
|
||||
Assert.That(visibleGridItems.Select(i => i.Label),
|
||||
Is.EquivalentTo(new[]
|
||||
{
|
||||
nameof(obj.Prop1),
|
||||
nameof(obj.Prop2)
|
||||
}));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanSelectGridItem()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = "world" };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
grid.SelectGridItem(nameof(obj.Prop2));
|
||||
|
||||
Assert.That(grid.SelectedGridItem.PropertyDescriptor?.Name,
|
||||
Is.EqualTo(nameof(obj.Prop2)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindNextGridItemPropertyReturnsTheCorrectItem()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = "world" };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
grid.SelectGridItem(nameof(obj.Prop1));
|
||||
var nextGridItem = grid.FindNextGridItemProperty(grid.SelectedGridItem);
|
||||
|
||||
Assert.That(nextGridItem?.PropertyDescriptor?.Name,
|
||||
Is.EqualTo(nameof(obj.Prop2)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindPreviousGridItemPropertyReturnsTheCorrectItem()
|
||||
{
|
||||
var grid = new FilteredPropertyGrid();
|
||||
var obj = new { Prop1 = "hello", Prop2 = "world", Prop3 = "!" };
|
||||
grid.SelectedObject = obj;
|
||||
|
||||
grid.SelectGridItem(nameof(obj.Prop3));
|
||||
var nextGridItem = grid.FindPreviousGridItemProperty(grid.SelectedGridItem);
|
||||
|
||||
Assert.That(nextGridItem?.PropertyDescriptor?.Name,
|
||||
Is.EqualTo(nameof(obj.Prop2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,17 +12,14 @@ using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public class ConfigWindowGeneralTests
|
||||
public class ConfigWindowGeneralTests
|
||||
{
|
||||
private ConfigWindow _configWindow;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_configWindow = new ConfigWindow
|
||||
{
|
||||
PropertiesVisible = true
|
||||
};
|
||||
_configWindow = new ConfigWindow();
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(ConnectionInfoGeneralTestCases))]
|
||||
@@ -57,7 +54,92 @@ namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
|
||||
}
|
||||
|
||||
private static IEnumerable<TestCaseData> ConnectionInfoGeneralTestCases()
|
||||
[Test]
|
||||
public void SwitchFromInheritanceToConnectionPropertiesWhenClickingRootNode()
|
||||
{
|
||||
// connection with a normal parent container
|
||||
var connection = new ConnectionInfo();
|
||||
connection.SetParent(new ContainerInfo());
|
||||
|
||||
_configWindow.SelectedTreeNode = connection;
|
||||
_configWindow.ShowInheritanceProperties();
|
||||
|
||||
_configWindow.SelectedTreeNode = new RootNodeInfo(RootNodeType.Connection);
|
||||
Assert.That(_configWindow.PropertiesVisible, Is.True,
|
||||
() => "The property mode should switch from inheritance to connection properties when clicking on the root node.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SwitchFromInheritanceToConnectionPropertiesWhenClickingRootPuttyNode()
|
||||
{
|
||||
// connection with a normal parent container
|
||||
var connection = new ConnectionInfo();
|
||||
connection.SetParent(new ContainerInfo());
|
||||
|
||||
_configWindow.SelectedTreeNode = connection;
|
||||
_configWindow.ShowInheritanceProperties();
|
||||
|
||||
_configWindow.SelectedTreeNode = new RootPuttySessionsNodeInfo();
|
||||
Assert.That(_configWindow.PropertiesVisible, Is.True,
|
||||
() => "The property mode should switch from inheritance to connection properties when clicking on the root node.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SwitchFromInheritanceToConnectionPropertiesWhenClickingChildOfRootNode()
|
||||
{
|
||||
// connection with a normal parent container
|
||||
var root = new RootNodeInfo(RootNodeType.Connection);
|
||||
var containerWhoseParentIsRoot = new ContainerInfo();
|
||||
var connection = new ConnectionInfo();
|
||||
root.AddChild(containerWhoseParentIsRoot);
|
||||
containerWhoseParentIsRoot.AddChild(connection);
|
||||
|
||||
_configWindow.SelectedTreeNode = connection;
|
||||
_configWindow.ShowInheritanceProperties();
|
||||
|
||||
_configWindow.SelectedTreeNode = containerWhoseParentIsRoot;
|
||||
Assert.That(_configWindow.PropertiesVisible, Is.True,
|
||||
() => "The property mode should switch from inheritance to connection properties " +
|
||||
"when clicking on a container whose parent is the root node.");
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(EveryNodeType))]
|
||||
public void DefaultConnectionPropertiesCanBeShownRegardlessOfWhichNodeIsSelected(ConnectionInfo selectedObject)
|
||||
{
|
||||
_configWindow.SelectedTreeNode = selectedObject;
|
||||
Assert.That(_configWindow.CanShowDefaultProperties, Is.True);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(EveryNodeType))]
|
||||
public void DefaultInheritancePropertiesCanBeShownRegardlessOfWhichNodeIsSelected(ConnectionInfo selectedObject)
|
||||
{
|
||||
_configWindow.SelectedTreeNode = selectedObject;
|
||||
Assert.That(_configWindow.CanShowDefaultInheritance, Is.True);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(EveryNodeType))]
|
||||
public void ConnectionPropertiesCanAlwaysBeShownUnlessNothingIsSelected(ConnectionInfo selectedObject)
|
||||
{
|
||||
_configWindow.SelectedTreeNode = selectedObject;
|
||||
|
||||
var selectedObjectNotNull = selectedObject != null;
|
||||
Assert.That(_configWindow.CanShowProperties, Is.EqualTo(selectedObjectNotNull));
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(EveryNodeType))]
|
||||
public void InheritancePropertiesAreVisibleInCertainCases(ConnectionInfo selectedObject)
|
||||
{
|
||||
_configWindow.SelectedTreeNode = selectedObject;
|
||||
|
||||
var shouldBeAvailable = selectedObject != null &&
|
||||
!(selectedObject is RootNodeInfo) &&
|
||||
!(selectedObject is PuttySessionInfo) &&
|
||||
!(selectedObject.Parent is RootNodeInfo);
|
||||
|
||||
Assert.That(_configWindow.CanShowInheritance, Is.EqualTo(shouldBeAvailable));
|
||||
}
|
||||
|
||||
private static IEnumerable<TestCaseData> ConnectionInfoGeneralTestCases()
|
||||
{
|
||||
var protocolTypes = typeof(ProtocolType).GetEnumValues().OfType<ProtocolType>();
|
||||
var testCases = new List<TestCaseData>();
|
||||
@@ -80,6 +162,56 @@ namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
return testCases;
|
||||
}
|
||||
|
||||
private static IEnumerable<TestCaseData> EveryNodeType()
|
||||
{
|
||||
var protocolTypes = typeof(ProtocolType).GetEnumValues().OfType<ProtocolType>().ToList();
|
||||
var root = new RootNodeInfo(RootNodeType.Connection);
|
||||
var container = new ContainerInfo();
|
||||
var connectionsWithNormalParent = protocolTypes
|
||||
.Select(protocolType =>
|
||||
{
|
||||
var c = new ConnectionInfo {Protocol = protocolType};
|
||||
c.SetParent(container);
|
||||
return new TestCaseData(c).SetName(protocolType + ", Connection, NormalParent");
|
||||
});
|
||||
|
||||
var connectionsWithRootParent = protocolTypes
|
||||
.Select(protocolType =>
|
||||
{
|
||||
var c = new ConnectionInfo { Protocol = protocolType };
|
||||
c.SetParent(root);
|
||||
return new TestCaseData(c).SetName(protocolType + ", Connection, RootParent");
|
||||
});
|
||||
|
||||
var contianersWithNormalParent = protocolTypes
|
||||
.Select(protocolType =>
|
||||
{
|
||||
var c = new ContainerInfo { Protocol = protocolType };
|
||||
c.SetParent(container);
|
||||
return new TestCaseData(c).SetName(protocolType + ", Connection, NormalParent");
|
||||
});
|
||||
|
||||
var containersWithRootParent = protocolTypes
|
||||
.Select(protocolType =>
|
||||
{
|
||||
var c = new ContainerInfo { Protocol = protocolType };
|
||||
c.SetParent(root);
|
||||
return new TestCaseData(c).SetName(protocolType + ", Connection, RootParent");
|
||||
});
|
||||
|
||||
return connectionsWithNormalParent
|
||||
.Concat(connectionsWithRootParent)
|
||||
.Concat(contianersWithNormalParent)
|
||||
.Concat(containersWithRootParent)
|
||||
.Concat(new[]
|
||||
{
|
||||
new TestCaseData(root).SetName("RootNode"),
|
||||
new TestCaseData(new RootPuttySessionsNodeInfo()).SetName("RootPuttyNode"),
|
||||
new TestCaseData(new PuttySessionInfo()).SetName("PuttyNode"),
|
||||
new TestCaseData(null).SetName("Null"),
|
||||
});
|
||||
}
|
||||
|
||||
internal static ConnectionInfo ConstructConnectionInfo(ProtocolType protocol, bool isContainer)
|
||||
{
|
||||
// build connection info. set certain connection properties so
|
||||
|
||||
@@ -6,7 +6,7 @@ using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
{
|
||||
public abstract class ConfigWindowSpecialTestsBase
|
||||
public abstract class ConfigWindowSpecialTestsBase
|
||||
{
|
||||
protected abstract ProtocolType Protocol { get; }
|
||||
protected bool TestAgainstContainerInfo { get; set; } = false;
|
||||
@@ -20,10 +20,7 @@ namespace mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
ConnectionInfo = ConfigWindowGeneralTests.ConstructConnectionInfo(Protocol, TestAgainstContainerInfo);
|
||||
ExpectedPropertyList = ConfigWindowGeneralTests.BuildExpectedConnectionInfoPropertyList(Protocol, TestAgainstContainerInfo);
|
||||
|
||||
ConfigWindow = new ConfigWindow
|
||||
{
|
||||
PropertiesVisible = true,
|
||||
};
|
||||
ConfigWindow = new ConfigWindow();
|
||||
}
|
||||
|
||||
public void RunVerification()
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
<Compile Include="Tree\ClickHandlers\SwitchToConnectionClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\SelectedConnectionDeletionConfirmerTests.cs" />
|
||||
<Compile Include="UI\Controls\ConnectionTreeTests.cs" />
|
||||
<Compile Include="UI\Controls\FilteredPropertyGridTests.cs" />
|
||||
<Compile Include="UI\Controls\PageSequenceTests.cs" />
|
||||
<Compile Include="UI\Controls\SecureTextBoxTestForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.Http;
|
||||
@@ -7,11 +6,11 @@ using mRemoteNG.Connection.Protocol.ICA;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tools.Attributes;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
{
|
||||
[Obsolete("Valid for mRemoteNG v1.75 (confCons v2.6) or earlier")]
|
||||
public abstract class AbstractConnectionRecord : INotifyPropertyChanged
|
||||
{
|
||||
#region Fields
|
||||
@@ -132,7 +131,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameAddress"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAddress")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAddress"),
|
||||
UsedInAllProtocolsExcept()]
|
||||
public virtual string Hostname
|
||||
{
|
||||
get => _hostname.Trim();
|
||||
@@ -141,7 +141,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameUsername"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUsername")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUsername"),
|
||||
UsedInAllProtocolsExcept(ProtocolType.VNC, ProtocolType.Telnet, ProtocolType.Rlogin, ProtocolType.RAW)]
|
||||
public virtual string Username
|
||||
{
|
||||
get => GetPropertyValue("Username", _username);
|
||||
@@ -151,7 +152,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNamePassword"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPassword"),
|
||||
PasswordPropertyText(true)]
|
||||
PasswordPropertyText(true),
|
||||
UsedInAllProtocolsExcept(ProtocolType.Telnet, ProtocolType.Rlogin, ProtocolType.RAW)]
|
||||
public virtual string Password
|
||||
{
|
||||
get => GetPropertyValue("Password", _password);
|
||||
@@ -160,7 +162,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameDomain"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDomain")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDomain"),
|
||||
UsedInProtocol(ProtocolType.RDP, ProtocolType.ICA, ProtocolType.IntApp)]
|
||||
public string Domain
|
||||
{
|
||||
get => GetPropertyValue("Domain", _domain).Trim();
|
||||
@@ -184,7 +187,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalTool"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalTool"),
|
||||
TypeConverter(typeof(ExternalToolsTypeConverter))]
|
||||
TypeConverter(typeof(ExternalToolsTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.IntApp)]
|
||||
public string ExtApp
|
||||
{
|
||||
get => GetPropertyValue("ExtApp", _extApp);
|
||||
@@ -193,7 +197,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNamePort"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPort")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPort"),
|
||||
UsedInAllProtocolsExcept(ProtocolType.ICA)]
|
||||
public virtual int Port
|
||||
{
|
||||
get => GetPropertyValue("Port", _port);
|
||||
@@ -203,7 +208,9 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNamePuttySession"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPuttySession"),
|
||||
TypeConverter(typeof(Config.Putty.PuttySessionsManager.SessionList))]
|
||||
TypeConverter(typeof(Config.Putty.PuttySessionsManager.SessionList)),
|
||||
UsedInProtocol(ProtocolType.SSH1, ProtocolType.SSH2, ProtocolType.Telnet,
|
||||
ProtocolType.RAW, ProtocolType.Rlogin)]
|
||||
public virtual string PuttySession
|
||||
{
|
||||
get => GetPropertyValue("PuttySession", _puttySession);
|
||||
@@ -213,7 +220,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameEncryptionStrength"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEncryptionStrength"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.ICA)]
|
||||
public IcaProtocol.EncryptionStrength ICAEncryptionStrength
|
||||
{
|
||||
get => GetPropertyValue("ICAEncryptionStrength", _icaEncryption);
|
||||
@@ -223,7 +231,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameUseConsoleSession"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUseConsoleSession"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool UseConsoleSession
|
||||
{
|
||||
get => GetPropertyValue("UseConsoleSession", _useConsoleSession);
|
||||
@@ -233,7 +242,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameAuthenticationLevel"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAuthenticationLevel"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public RdpProtocol.AuthenticationLevel RDPAuthenticationLevel
|
||||
{
|
||||
get => GetPropertyValue("RDPAuthenticationLevel", _rdpAuthenticationLevel);
|
||||
@@ -242,7 +252,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPMinutesToIdleTimeout"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPMinutesToIdleTimeout")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPMinutesToIdleTimeout"),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public virtual int RDPMinutesToIdleTimeout
|
||||
{
|
||||
get => GetPropertyValue("RDPMinutesToIdleTimeout", _rdpMinutesToIdleTimeout);
|
||||
@@ -258,7 +269,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPAlertIdleTimeout"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPAlertIdleTimeout")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPAlertIdleTimeout"),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RDPAlertIdleTimeout
|
||||
{
|
||||
get => GetPropertyValue("RDPAlertIdleTimeout", _rdpAlertIdleTimeout);
|
||||
@@ -267,7 +279,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameLoadBalanceInfo"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionLoadBalanceInfo")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionLoadBalanceInfo"),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public string LoadBalanceInfo
|
||||
{
|
||||
get => GetPropertyValue("LoadBalanceInfo", _loadBalanceInfo).Trim();
|
||||
@@ -277,7 +290,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRenderingEngine"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRenderingEngine"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.HTTP, ProtocolType.HTTPS)]
|
||||
public HTTPBase.RenderingEngine RenderingEngine
|
||||
{
|
||||
get => GetPropertyValue("RenderingEngine", _renderingEngine);
|
||||
@@ -287,7 +301,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameUseCredSsp"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUseCredSsp"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool UseCredSsp
|
||||
{
|
||||
get => GetPropertyValue("UseCredSsp", _useCredSsp);
|
||||
@@ -301,7 +316,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUsageMethod"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsageMethod"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public RdpProtocol.RDGatewayUsageMethod RDGatewayUsageMethod
|
||||
{
|
||||
get => GetPropertyValue("RDGatewayUsageMethod", _rdGatewayUsageMethod);
|
||||
@@ -310,7 +326,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayHostname"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayHostname")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayHostname"),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public string RDGatewayHostname
|
||||
{
|
||||
get => GetPropertyValue("RDGatewayHostname", _rdGatewayHostname).Trim();
|
||||
@@ -320,7 +337,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUseConnectionCredentials"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUseConnectionCredentials"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public RdpProtocol.RDGatewayUseConnectionCredentials RDGatewayUseConnectionCredentials
|
||||
{
|
||||
get => GetPropertyValue("RDGatewayUseConnectionCredentials", _rdGatewayUseConnectionCredentials);
|
||||
@@ -329,7 +347,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUsername"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsername")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsername"),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public string RDGatewayUsername
|
||||
{
|
||||
get => GetPropertyValue("RDGatewayUsername", _rdGatewayUsername).Trim();
|
||||
@@ -339,7 +358,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayPassword"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyNameRDGatewayPassword"),
|
||||
PasswordPropertyText(true)]
|
||||
PasswordPropertyText(true),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public string RDGatewayPassword
|
||||
{
|
||||
get => GetPropertyValue("RDGatewayPassword", _rdGatewayPassword);
|
||||
@@ -348,7 +368,8 @@ namespace mRemoteNG.Connection
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayDomain"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayDomain")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayDomain"),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public string RDGatewayDomain
|
||||
{
|
||||
get => GetPropertyValue("RDGatewayDomain", _rdGatewayDomain).Trim();
|
||||
@@ -362,7 +383,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameResolution"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionResolution"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP, ProtocolType.ICA)]
|
||||
public RdpProtocol.RDPResolutions Resolution
|
||||
{
|
||||
get => GetPropertyValue("Resolution", _resolution);
|
||||
@@ -372,7 +394,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameAutomaticResize"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAutomaticResize"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool AutomaticResize
|
||||
{
|
||||
get => GetPropertyValue("AutomaticResize", _automaticResize);
|
||||
@@ -382,7 +405,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameColors"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionColors"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP, ProtocolType.ICA)]
|
||||
public RdpProtocol.RDPColors Colors
|
||||
{
|
||||
get => GetPropertyValue("Colors", _colors);
|
||||
@@ -392,7 +416,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameCacheBitmaps"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionCacheBitmaps"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP, ProtocolType.ICA)]
|
||||
public bool CacheBitmaps
|
||||
{
|
||||
get => GetPropertyValue("CacheBitmaps", _cacheBitmaps);
|
||||
@@ -402,7 +427,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameDisplayWallpaper"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDisplayWallpaper"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool DisplayWallpaper
|
||||
{
|
||||
get => GetPropertyValue("DisplayWallpaper", _displayWallpaper);
|
||||
@@ -412,7 +438,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameDisplayThemes"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDisplayThemes"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool DisplayThemes
|
||||
{
|
||||
get => GetPropertyValue("DisplayThemes", _displayThemes);
|
||||
@@ -422,7 +449,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameEnableFontSmoothing"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEnableFontSmoothing"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool EnableFontSmoothing
|
||||
{
|
||||
get => GetPropertyValue("EnableFontSmoothing", _enableFontSmoothing);
|
||||
@@ -432,7 +460,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameEnableDesktopComposition"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEnableDesktopComposition"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool EnableDesktopComposition
|
||||
{
|
||||
get => GetPropertyValue("EnableDesktopComposition", _enableDesktopComposition);
|
||||
@@ -446,7 +475,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectKeys"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectKeys"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectKeys
|
||||
{
|
||||
get => GetPropertyValue("RedirectKeys", _redirectKeys);
|
||||
@@ -456,7 +486,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectDrives"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectDrives"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectDiskDrives
|
||||
{
|
||||
get => GetPropertyValue("RedirectDiskDrives", _redirectDiskDrives);
|
||||
@@ -466,7 +497,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectPrinters"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectPrinters"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectPrinters
|
||||
{
|
||||
get => GetPropertyValue("RedirectPrinters", _redirectPrinters);
|
||||
@@ -476,7 +508,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectClipboard"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectClipboard"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectClipboard
|
||||
{
|
||||
get { return GetPropertyValue("RedirectClipboard", _redirectClipboard); }
|
||||
@@ -487,7 +520,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectPorts"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectPorts"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectPorts
|
||||
{
|
||||
get => GetPropertyValue("RedirectPorts", _redirectPorts);
|
||||
@@ -497,7 +531,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectSmartCards"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectSmartCards"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectSmartCards
|
||||
{
|
||||
get => GetPropertyValue("RedirectSmartCards", _redirectSmartCards);
|
||||
@@ -507,7 +542,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectSounds"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectSounds"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public RdpProtocol.RDPSounds RedirectSound
|
||||
{
|
||||
get => GetPropertyValue("RedirectSound", _redirectSound);
|
||||
@@ -517,7 +553,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameSoundQuality"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionSoundQuality"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public RdpProtocol.RDPSoundQuality SoundQuality
|
||||
{
|
||||
get => GetPropertyValue("SoundQuality", _soundQuality);
|
||||
@@ -527,18 +564,19 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectAudioCapture"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectAudioCapture"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.RDP)]
|
||||
public bool RedirectAudioCapture
|
||||
{
|
||||
get { return GetPropertyValue("RedirectAudioCapture", _redirectAudioCapture); }
|
||||
set { SetField(ref _redirectAudioCapture, value, "RedirectAudioCapture"); }
|
||||
get => GetPropertyValue(nameof(RedirectAudioCapture), _redirectAudioCapture);
|
||||
set => SetField(ref _redirectAudioCapture, value, nameof(RedirectAudioCapture));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
|
||||
[Browsable(false)] public string ConstantID { get; /*set;*/ }
|
||||
[Browsable(false)] public string ConstantID { get; }
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalToolBefore"),
|
||||
@@ -590,12 +628,14 @@ namespace mRemoteNG.Connection
|
||||
#endregion
|
||||
|
||||
#region VNC
|
||||
|
||||
// TODO: it seems all these VNC properties were added and serialized but
|
||||
// never hooked up to the VNC protocol or shown to the user
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameCompression"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionCompression"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public ProtocolVNC.Compression VNCCompression
|
||||
{
|
||||
get => GetPropertyValue("VNCCompression", _vncCompression);
|
||||
@@ -603,10 +643,11 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameEncoding"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEncoding"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public ProtocolVNC.Encoding VNCEncoding
|
||||
{
|
||||
get => GetPropertyValue("VNCEncoding", _vncEncoding);
|
||||
@@ -614,10 +655,11 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameAuthenticationMode"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAuthenticationMode"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public ProtocolVNC.AuthMode VNCAuthMode
|
||||
{
|
||||
get => GetPropertyValue("VNCAuthMode", _vncAuthMode);
|
||||
@@ -625,10 +667,11 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProxy", 7),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyType"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyType"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public ProtocolVNC.ProxyType VNCProxyType
|
||||
{
|
||||
get => GetPropertyValue("VNCProxyType", _vncProxyType);
|
||||
@@ -636,9 +679,10 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProxy", 7),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyAddress"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyAddress")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyAddress"),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public string VNCProxyIP
|
||||
{
|
||||
get => GetPropertyValue("VNCProxyIP", _vncProxyIp);
|
||||
@@ -646,9 +690,10 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProxy", 7),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyPort"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPort")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPort"),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public int VNCProxyPort
|
||||
{
|
||||
get => GetPropertyValue("VNCProxyPort", _vncProxyPort);
|
||||
@@ -656,9 +701,10 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProxy", 7),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyUsername"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyUsername")]
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyUsername"),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public string VNCProxyUsername
|
||||
{
|
||||
get => GetPropertyValue("VNCProxyUsername", _vncProxyUsername);
|
||||
@@ -666,10 +712,11 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProxy", 7),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyPassword"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPassword"),
|
||||
PasswordPropertyText(true)]
|
||||
PasswordPropertyText(true),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public string VNCProxyPassword
|
||||
{
|
||||
get => GetPropertyValue("VNCProxyPassword", _vncProxyPassword);
|
||||
@@ -677,10 +724,11 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
Browsable(false),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameColors"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionColors"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC),
|
||||
Browsable(false)]
|
||||
public ProtocolVNC.Colors VNCColors
|
||||
{
|
||||
get => GetPropertyValue("VNCColors", _vncColors);
|
||||
@@ -690,7 +738,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameSmartSizeMode"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionSmartSizeMode"),
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC)]
|
||||
public ProtocolVNC.SmartSizeMode VNCSmartSizeMode
|
||||
{
|
||||
get => GetPropertyValue("VNCSmartSizeMode", _vncSmartSizeMode);
|
||||
@@ -700,7 +749,8 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameViewOnly"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionViewOnly"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
|
||||
UsedInProtocol(ProtocolType.VNC)]
|
||||
public bool VNCViewOnly
|
||||
{
|
||||
get => GetPropertyValue("VNCViewOnly", _vncViewOnly);
|
||||
|
||||
@@ -22,9 +22,18 @@ namespace mRemoteNG.Connection
|
||||
[DefaultProperty("Name")]
|
||||
public class ConnectionInfo : AbstractConnectionRecord, IHasParent, IInheritable
|
||||
{
|
||||
private ConnectionInfoInheritance _inheritance;
|
||||
|
||||
#region Public Properties
|
||||
|
||||
[Browsable(false)] public ConnectionInfoInheritance Inheritance { get; set; }
|
||||
[Browsable(false)]
|
||||
public ConnectionInfoInheritance Inheritance
|
||||
{
|
||||
get => _inheritance;
|
||||
set => _inheritance = _inheritance.Parent != this
|
||||
? _inheritance.Clone(this)
|
||||
: value;
|
||||
}
|
||||
|
||||
[Browsable(false)] public ProtocolList OpenConnections { get; protected set; }
|
||||
|
||||
@@ -72,11 +81,14 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
var newConnectionInfo = new ConnectionInfo();
|
||||
newConnectionInfo.CopyFrom(this);
|
||||
newConnectionInfo.Inheritance = Inheritance.Clone();
|
||||
newConnectionInfo.Inheritance.Parent = newConnectionInfo;
|
||||
return newConnectionInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies all connection and inheritance values
|
||||
/// from the given <see cref="sourceConnectionInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="sourceConnectionInfo"></param>
|
||||
public void CopyFrom(ConnectionInfo sourceConnectionInfo)
|
||||
{
|
||||
var properties = GetType().BaseType?.GetProperties().Where(prop => prop.CanRead && prop.CanWrite);
|
||||
@@ -88,8 +100,7 @@ namespace mRemoteNG.Connection
|
||||
property.SetValue(this, remotePropertyValue, null);
|
||||
}
|
||||
|
||||
var clonedInheritance = sourceConnectionInfo.Inheritance.Clone();
|
||||
clonedInheritance.Parent = this;
|
||||
var clonedInheritance = sourceConnectionInfo.Inheritance.Clone(this);
|
||||
Inheritance = clonedInheritance;
|
||||
}
|
||||
|
||||
@@ -388,7 +399,7 @@ namespace mRemoteNG.Connection
|
||||
|
||||
private void SetNonBrowsablePropertiesDefaults()
|
||||
{
|
||||
Inheritance = new ConnectionInfoInheritance(this);
|
||||
_inheritance = new ConnectionInfoInheritance(this);
|
||||
SetNewOpenConnectionList();
|
||||
//PositionID = 0;
|
||||
}
|
||||
|
||||
@@ -391,12 +391,12 @@ namespace mRemoteNG.Connection
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool VNCViewOnly {get; set;}
|
||||
#endregion
|
||||
|
||||
[Browsable(false)] public object Parent { get; set; }
|
||||
[Browsable(false)] public ConnectionInfo Parent { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public ConnectionInfoInheritance(object parent, bool ignoreDefaultInheritance = false)
|
||||
public ConnectionInfoInheritance(ConnectionInfo parent, bool ignoreDefaultInheritance = false)
|
||||
{
|
||||
Parent = parent;
|
||||
if (!ignoreDefaultInheritance)
|
||||
@@ -404,9 +404,10 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
|
||||
|
||||
public ConnectionInfoInheritance Clone()
|
||||
public ConnectionInfoInheritance Clone(ConnectionInfo parent)
|
||||
{
|
||||
var newInheritance = (ConnectionInfoInheritance)MemberwiseClone();
|
||||
newInheritance.Parent = parent;
|
||||
newInheritance._tempInheritanceStorage = null;
|
||||
return newInheritance;
|
||||
}
|
||||
@@ -431,7 +432,7 @@ namespace mRemoteNG.Connection
|
||||
|
||||
private void StashInheritanceData()
|
||||
{
|
||||
_tempInheritanceStorage = Clone();
|
||||
_tempInheritanceStorage = Clone(Parent);
|
||||
}
|
||||
|
||||
public void TurnOnInheritanceCompletely()
|
||||
@@ -458,6 +459,19 @@ namespace mRemoteNG.Connection
|
||||
return filteredProperties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of all properties where inheritance is turned on
|
||||
/// (set to True).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<string> GetEnabledInheritanceProperties()
|
||||
{
|
||||
return GetProperties()
|
||||
.Where(property => (bool)property.GetValue(this))
|
||||
.Select(property => property.Name)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private bool FilterProperty(PropertyInfo propertyInfo)
|
||||
{
|
||||
var exclusions = new[] {"EverythingInherited", "Parent"};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using mRemoteNG.App;
|
||||
|
||||
@@ -7,6 +8,7 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
public class DefaultConnectionInfo : ConnectionInfo
|
||||
{
|
||||
[Browsable(false)]
|
||||
public static DefaultConnectionInfo Instance { get; } = new DefaultConnectionInfo();
|
||||
|
||||
private DefaultConnectionInfo()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.App;
|
||||
|
||||
|
||||
@@ -6,6 +7,7 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
public class DefaultConnectionInheritance : ConnectionInfoInheritance
|
||||
{
|
||||
[Browsable(false)]
|
||||
public static DefaultConnectionInheritance Instance { get; } = new DefaultConnectionInheritance();
|
||||
|
||||
private DefaultConnectionInheritance() : base(null, true)
|
||||
|
||||
@@ -204,7 +204,7 @@ namespace mRemoteNG.Container
|
||||
var newContainer = new ContainerInfo();
|
||||
newContainer.CopyFrom(this);
|
||||
newContainer.OpenConnections = new ProtocolList();
|
||||
newContainer.Inheritance = Inheritance.Clone();
|
||||
newContainer.Inheritance = Inheritance.Clone(newContainer);
|
||||
foreach (var child in Children.ToArray())
|
||||
{
|
||||
var newChild = child.Clone();
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
|
||||
namespace mRemoteNG.Tools.Attributes
|
||||
{
|
||||
public class UsedInAllProtocolsExceptAttribute : UsedInProtocolAttribute
|
||||
{
|
||||
public UsedInAllProtocolsExceptAttribute(params ProtocolType[] exceptions)
|
||||
: base(Enum
|
||||
.GetValues(typeof(ProtocolType))
|
||||
.Cast<ProtocolType>()
|
||||
.Except(exceptions)
|
||||
.ToArray())
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
16
mRemoteV1/Tools/Attributes/UsedInProtocolAttribute.cs
Normal file
16
mRemoteV1/Tools/Attributes/UsedInProtocolAttribute.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
|
||||
namespace mRemoteNG.Tools.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class UsedInProtocolAttribute : Attribute
|
||||
{
|
||||
public ProtocolType[] SupportedProtocolTypes { get; }
|
||||
|
||||
public UsedInProtocolAttribute(params ProtocolType[] supportedProtocolTypes)
|
||||
{
|
||||
SupportedProtocolTypes = supportedProtocolTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
mRemoteV1/UI/Controls/ConnectionInfoPropertyGrid/ConnectionInfoPropertyGrid.Designer.cs
generated
Normal file
37
mRemoteV1/UI/Controls/ConnectionInfoPropertyGrid/ConnectionInfoPropertyGrid.Designer.cs
generated
Normal file
@@ -0,0 +1,37 @@
|
||||
namespace mRemoteNG.UI.Controls.ConnectionInfoPropertyGrid
|
||||
{
|
||||
partial class ConnectionInfoPropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tools.Attributes;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.UI.Controls.ConnectionInfoPropertyGrid
|
||||
{
|
||||
public partial class ConnectionInfoPropertyGrid : FilteredPropertyGrid.FilteredPropertyGrid
|
||||
{
|
||||
private readonly Dictionary<Type, IEnumerable<PropertyInfo>> _propertyCache = new Dictionary<Type, IEnumerable<PropertyInfo>>();
|
||||
private ConnectionInfo _selectedConnectionInfo;
|
||||
private PropertyMode _propertyMode;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ConnectionInfo"/> currently being shown by this
|
||||
/// property grid.
|
||||
/// </summary>
|
||||
public ConnectionInfo SelectedConnectionInfo
|
||||
{
|
||||
get => _selectedConnectionInfo;
|
||||
set
|
||||
{
|
||||
if (_selectedConnectionInfo == value)
|
||||
return;
|
||||
|
||||
_selectedConnectionInfo = value;
|
||||
RootNodeSelected = SelectedConnectionInfo is RootNodeInfo;
|
||||
SetGridObject();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines which set of properties this grid will display.
|
||||
/// </summary>
|
||||
public PropertyMode PropertyMode
|
||||
{
|
||||
get => _propertyMode;
|
||||
set
|
||||
{
|
||||
if (_propertyMode == value)
|
||||
return;
|
||||
_propertyMode = value;
|
||||
SetGridObject();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the property grid showing the selected connection's
|
||||
/// inheritance info? If false, the connection's normal
|
||||
/// properties are shown instead.
|
||||
/// </summary>
|
||||
public bool IsShowingInheritance => PropertyMode == PropertyMode.Inheritance ||
|
||||
PropertyMode == PropertyMode.DefaultInheritance;
|
||||
|
||||
/// <summary>
|
||||
/// This indicates whether the current <see cref="SelectedConnectionInfo"/>
|
||||
/// is a <see cref="DefaultConnectionInfo"/>.
|
||||
/// </summary>
|
||||
public bool IsShowingDefaultProperties => PropertyMode == PropertyMode.DefaultConnection ||
|
||||
PropertyMode == PropertyMode.DefaultInheritance;
|
||||
|
||||
/// <summary>
|
||||
/// True when the <see cref="SelectedConnectionInfo"/> is
|
||||
/// of type <see cref="RootNodeInfo"/>.
|
||||
/// </summary>
|
||||
public bool RootNodeSelected { get; private set; }
|
||||
|
||||
public ConnectionInfoPropertyGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
PropertyValueChanged += pGrid_PropertyValueChanged;
|
||||
}
|
||||
|
||||
private void SetGridObject()
|
||||
{
|
||||
ClearFilters();
|
||||
|
||||
switch (PropertyMode)
|
||||
{
|
||||
case PropertyMode.Connection:
|
||||
default:
|
||||
SelectedObject = SelectedConnectionInfo;
|
||||
break;
|
||||
case PropertyMode.Inheritance:
|
||||
SelectedObject = SelectedConnectionInfo?.Inheritance;
|
||||
break;
|
||||
case PropertyMode.DefaultConnection:
|
||||
SelectedObject = DefaultConnectionInfo.Instance;
|
||||
break;
|
||||
case PropertyMode.DefaultInheritance:
|
||||
SelectedObject = DefaultConnectionInheritance.Instance;
|
||||
break;
|
||||
}
|
||||
|
||||
if (SelectedObject != null)
|
||||
ShowHideGridItems();
|
||||
}
|
||||
|
||||
private void ShowHideGridItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SelectedConnectionInfo == null)
|
||||
return;
|
||||
|
||||
if (RootNodeSelected && PropertyMode == PropertyMode.Connection)
|
||||
{
|
||||
if (SelectedConnectionInfo is RootPuttySessionsNodeInfo)
|
||||
{
|
||||
BrowsableProperties = new[]
|
||||
{
|
||||
nameof(RootPuttySessionsNodeInfo.Name)
|
||||
};
|
||||
}
|
||||
else if (SelectedConnectionInfo is RootNodeInfo)
|
||||
{
|
||||
BrowsableProperties = new[]
|
||||
{
|
||||
nameof(RootNodeInfo.Name),
|
||||
nameof(RootNodeInfo.Password)
|
||||
};
|
||||
}
|
||||
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
// set all browsable properties valid for this connection's protocol
|
||||
BrowsableProperties =
|
||||
GetPropertiesForGridObject(SelectedObject)
|
||||
.Where(property =>
|
||||
IsValidForProtocol(property, SelectedConnectionInfo.Protocol, IsShowingInheritance))
|
||||
.Select(property => property.Name)
|
||||
.ToArray();
|
||||
|
||||
var strHide = new List<string>();
|
||||
|
||||
if (PropertyMode == PropertyMode.Connection)
|
||||
{
|
||||
// hide any inherited properties
|
||||
strHide.AddRange(SelectedConnectionInfo.Inheritance.GetEnabledInheritanceProperties());
|
||||
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (SelectedConnectionInfo.Protocol)
|
||||
{
|
||||
case ProtocolType.RDP:
|
||||
strHide.AddRange(SpecialRdpExclusions());
|
||||
break;
|
||||
case ProtocolType.VNC:
|
||||
strHide.AddRange(SpecialVncExclusions());
|
||||
break;
|
||||
}
|
||||
|
||||
if (SelectedConnectionInfo.IsContainer)
|
||||
strHide.Add(nameof(AbstractConnectionRecord.Hostname));
|
||||
|
||||
if (SelectedConnectionInfo is PuttySessionInfo)
|
||||
strHide.Add(nameof(AbstractConnectionRecord.Favorite));
|
||||
}
|
||||
else if (PropertyMode == PropertyMode.DefaultConnection)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.Hostname));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.Name));
|
||||
}
|
||||
|
||||
HiddenProperties = strHide.ToArray();
|
||||
Refresh();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(
|
||||
MessageClass.ErrorMsg,
|
||||
Language.strConfigPropertyGridHideItemsFailed +
|
||||
Environment.NewLine + ex.Message, true);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<PropertyInfo> GetPropertiesForGridObject(object currentGridObject)
|
||||
{
|
||||
if (_propertyCache.TryGetValue(currentGridObject.GetType(), out var properties))
|
||||
return properties;
|
||||
|
||||
var type = currentGridObject.GetType();
|
||||
var props = type.GetProperties();
|
||||
_propertyCache.Add(type, props);
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
private bool IsValidForProtocol(PropertyInfo property, ProtocolType protocol, bool skipProtocolCheck)
|
||||
{
|
||||
return
|
||||
property.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false &&
|
||||
(skipProtocolCheck || property.GetCustomAttribute<UsedInProtocolAttribute>()?
|
||||
.SupportedProtocolTypes
|
||||
.Contains(protocol) != false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private List<string> SpecialRdpExclusions()
|
||||
{
|
||||
var strHide = new List<string>();
|
||||
|
||||
if (SelectedConnectionInfo.RDPMinutesToIdleTimeout <= 0)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDPAlertIdleTimeout));
|
||||
}
|
||||
|
||||
if (SelectedConnectionInfo.RDGatewayUsageMethod == RdpProtocol.RDGatewayUsageMethod.Never)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayDomain));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayHostname));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayPassword));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayUseConnectionCredentials));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayUsername));
|
||||
}
|
||||
else if (SelectedConnectionInfo.RDGatewayUseConnectionCredentials ==
|
||||
RdpProtocol.RDGatewayUseConnectionCredentials.Yes)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayDomain));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayPassword));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayUsername));
|
||||
}
|
||||
|
||||
if (!(SelectedConnectionInfo.Resolution == RdpProtocol.RDPResolutions.FitToWindow ||
|
||||
SelectedConnectionInfo.Resolution == RdpProtocol.RDPResolutions.Fullscreen))
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.AutomaticResize));
|
||||
}
|
||||
|
||||
if (SelectedConnectionInfo.RedirectSound != RdpProtocol.RDPSounds.BringToThisComputer)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.SoundQuality));
|
||||
}
|
||||
|
||||
return strHide;
|
||||
}
|
||||
|
||||
private List<string> SpecialVncExclusions()
|
||||
{
|
||||
var strHide = new List<string>();
|
||||
if (SelectedConnectionInfo.VNCAuthMode == ProtocolVNC.AuthMode.AuthVNC)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.Username));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.Domain));
|
||||
}
|
||||
|
||||
if (SelectedConnectionInfo.VNCProxyType == ProtocolVNC.ProxyType.ProxyNone)
|
||||
{
|
||||
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyIP));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyPassword));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyPort));
|
||||
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyUsername));
|
||||
}
|
||||
|
||||
return strHide;
|
||||
}
|
||||
|
||||
private void UpdateConnectionInfoNode(PropertyValueChangedEventArgs e)
|
||||
{
|
||||
if (IsShowingInheritance)
|
||||
return;
|
||||
|
||||
if (e.ChangedItem.Label == Language.strPropertyNameProtocol)
|
||||
{
|
||||
SelectedConnectionInfo.SetDefaultPort();
|
||||
}
|
||||
else if (e.ChangedItem.Label == Language.strPropertyNameName)
|
||||
{
|
||||
if (Settings.Default.SetHostnameLikeDisplayName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SelectedConnectionInfo.Name))
|
||||
SelectedConnectionInfo.Hostname = SelectedConnectionInfo.Name;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsShowingDefaultProperties)
|
||||
DefaultConnectionInfo.Instance.SaveTo(Settings.Default, a => "ConDefault" + a);
|
||||
}
|
||||
|
||||
private void UpdateRootInfoNode(PropertyValueChangedEventArgs e)
|
||||
{
|
||||
if (!(SelectedObject is RootNodeInfo rootInfo))
|
||||
return;
|
||||
|
||||
if (e.ChangedItem.PropertyDescriptor?.Name != "Password")
|
||||
return;
|
||||
|
||||
if (rootInfo.Password)
|
||||
{
|
||||
var passwordName = Settings.Default.UseSQLServer
|
||||
? Language.strSQLServer.TrimEnd(':')
|
||||
: Path.GetFileName(Runtime.ConnectionsService.GetStartupConnectionFileName());
|
||||
|
||||
var password = MiscTools.PasswordDialog(passwordName);
|
||||
|
||||
// operation cancelled, dont set a password
|
||||
if (!password.Any() || password.First().Length == 0)
|
||||
{
|
||||
rootInfo.Password = false;
|
||||
return;
|
||||
}
|
||||
|
||||
rootInfo.PasswordString = password.First().ConvertToUnsecureString();
|
||||
}
|
||||
else
|
||||
{
|
||||
rootInfo.PasswordString = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateInheritanceNode()
|
||||
{
|
||||
if (IsShowingDefaultProperties && IsShowingInheritance)
|
||||
DefaultConnectionInheritance.Instance.SaveTo(Settings.Default, a => "InhDefault" + a);
|
||||
}
|
||||
|
||||
private void pGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
UpdateConnectionInfoNode(e);
|
||||
UpdateRootInfoNode(e);
|
||||
UpdateInheritanceNode();
|
||||
ShowHideGridItems();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg,
|
||||
Language.strConfigPropertyGridValueFailed + Environment.NewLine +
|
||||
ex.Message, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace mRemoteNG.UI.Controls.ConnectionInfoPropertyGrid
|
||||
{
|
||||
public enum PropertyMode
|
||||
{
|
||||
Connection,
|
||||
Inheritance,
|
||||
DefaultConnection,
|
||||
DefaultInheritance,
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
|
||||
namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
{
|
||||
@@ -126,8 +125,8 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
}
|
||||
else if (_mWrapper.SelectedObject != value)
|
||||
{
|
||||
var needrefresh = value.GetType() != _mWrapper.SelectedObject.GetType();
|
||||
_mWrapper.SelectedObject = value;
|
||||
var needrefresh = value?.GetType() != _mWrapper.SelectedObject?.GetType();
|
||||
_mWrapper.SelectedObject = value ?? new object();
|
||||
if (needrefresh)
|
||||
RefreshProperties();
|
||||
}
|
||||
@@ -139,6 +138,159 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
}
|
||||
}
|
||||
|
||||
public List<GridItem> GetVisibleGridItems()
|
||||
{
|
||||
var gridRoot = SelectedGridItem;
|
||||
while (gridRoot.GridItemType != GridItemType.Root)
|
||||
{
|
||||
gridRoot = gridRoot.Parent;
|
||||
}
|
||||
return GetVisibleGridItemsRecursive(gridRoot, new List<GridItem>());
|
||||
}
|
||||
|
||||
private List<GridItem> GetVisibleGridItemsRecursive(GridItem item, List<GridItem> gridItems)
|
||||
{
|
||||
if (item.GridItemType == GridItemType.Property && !gridItems.Contains(item))
|
||||
gridItems.Add(item);
|
||||
|
||||
if (item.Expandable && !item.Expanded)
|
||||
return gridItems;
|
||||
|
||||
foreach (GridItem child in item.GridItems)
|
||||
{
|
||||
GetVisibleGridItemsRecursive(child, gridItems);
|
||||
}
|
||||
|
||||
return gridItems;
|
||||
}
|
||||
|
||||
public GridItem FindPreviousGridItemProperty(GridItem startItem)
|
||||
{
|
||||
var gridItems = GetVisibleGridItems();
|
||||
|
||||
if (gridItems.Count == 0 || startItem == null)
|
||||
return null;
|
||||
|
||||
var startIndex = gridItems.IndexOf(startItem);
|
||||
if (startItem.GridItemType == GridItemType.Property)
|
||||
{
|
||||
startIndex--;
|
||||
if (startIndex < 0)
|
||||
{
|
||||
startIndex = gridItems.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
var previousIndex = 0;
|
||||
var previousIndexValid = false;
|
||||
for (var index = startIndex; index >= 0; index--)
|
||||
{
|
||||
if (gridItems[index].GridItemType != GridItemType.Property) continue;
|
||||
previousIndex = index;
|
||||
previousIndexValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (previousIndexValid)
|
||||
return gridItems[previousIndex];
|
||||
|
||||
for (var index = gridItems.Count - 1; index >= startIndex + 1; index--)
|
||||
{
|
||||
if (gridItems[index].GridItemType != GridItemType.Property) continue;
|
||||
previousIndex = index;
|
||||
previousIndexValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return !previousIndexValid ? null : gridItems[previousIndex];
|
||||
}
|
||||
|
||||
public GridItem FindNextGridItemProperty(GridItem startItem)
|
||||
{
|
||||
var gridItems = GetVisibleGridItems();
|
||||
|
||||
if (gridItems.Count == 0 || startItem == null)
|
||||
return null;
|
||||
|
||||
var startIndex = gridItems.IndexOf(startItem);
|
||||
if (startItem.GridItemType == GridItemType.Property)
|
||||
{
|
||||
startIndex++;
|
||||
if (startIndex >= gridItems.Count)
|
||||
{
|
||||
startIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var nextIndex = 0;
|
||||
var nextIndexValid = false;
|
||||
for (var index = startIndex; index <= gridItems.Count - 1; index++)
|
||||
{
|
||||
if (gridItems[index].GridItemType != GridItemType.Property) continue;
|
||||
nextIndex = index;
|
||||
nextIndexValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextIndexValid)
|
||||
return gridItems[nextIndex];
|
||||
|
||||
for (var index = 0; index <= startIndex - 1; index++)
|
||||
{
|
||||
if (gridItems[index].GridItemType != GridItemType.Property) continue;
|
||||
nextIndex = index;
|
||||
nextIndexValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return !nextIndexValid ? null : gridItems[nextIndex];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects the next grid item in the property grid
|
||||
/// using the currently selected grid item as a reference.
|
||||
/// Does nothing if there is no next item.
|
||||
/// </summary>
|
||||
public void SelectNextGridItem()
|
||||
{
|
||||
var nextGridItem = FindNextGridItemProperty(SelectedGridItem);
|
||||
if (nextGridItem != null)
|
||||
SelectedGridItem = nextGridItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects the previous grid item in the property grid
|
||||
/// using the currently selected grid item as a reference.
|
||||
/// Does nothing if there is no previous item.
|
||||
/// </summary>
|
||||
public void SelectPreviousGridItem()
|
||||
{
|
||||
var previousGridItem = FindPreviousGridItemProperty(SelectedGridItem);
|
||||
if (previousGridItem != null)
|
||||
SelectedGridItem = previousGridItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select the grid item whose backing property name
|
||||
/// matches the given <see cref="propertyName"/>.
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
public void SelectGridItem(string propertyName)
|
||||
{
|
||||
var item = GetVisibleGridItems()
|
||||
.FirstOrDefault(gridItem => gridItem.PropertyDescriptor?.Name == propertyName);
|
||||
|
||||
if (item != null)
|
||||
SelectedGridItem = item;
|
||||
}
|
||||
|
||||
public void ClearFilters()
|
||||
{
|
||||
_mBrowsableProperties = null;
|
||||
_mHiddenProperties = null;
|
||||
RefreshProperties();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build the list of the properties to be displayed in the PropertyGrid, following the filters defined the Browsable and Hidden properties.
|
||||
/// </summary>
|
||||
@@ -156,7 +308,24 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
foreach (Attribute attribute in _browsableAttributes)
|
||||
ShowAttribute(attribute);
|
||||
}
|
||||
else
|
||||
|
||||
// Display if necessary, some properties
|
||||
if (_mBrowsableProperties != null && _mBrowsableProperties.Length > 0)
|
||||
{
|
||||
var allproperties = TypeDescriptor.GetProperties(_mWrapper.SelectedObject);
|
||||
foreach (var propertyname in _mBrowsableProperties)
|
||||
{
|
||||
var property = allproperties[propertyname];
|
||||
|
||||
if (property == null)
|
||||
throw new InvalidOperationException($"Property '{propertyname}' not found on object '{_mWrapper.GetClassName()}'");
|
||||
|
||||
ShowProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
if ((_browsableAttributes == null || _browsableAttributes.Count == 0) &&
|
||||
(_mBrowsableProperties == null || _mBrowsableProperties.Length == 0))
|
||||
{
|
||||
// Fill the collection with all the properties.
|
||||
var originalPropertyDescriptors = TypeDescriptor
|
||||
@@ -166,15 +335,12 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
|
||||
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(_mWrapper.SelectedObject);
|
||||
// Remove from the list the attributes that mustn't be displayed.
|
||||
if (_hiddenAttributes != null)
|
||||
foreach (Attribute attribute in _hiddenAttributes)
|
||||
HideAttribute(attribute);
|
||||
|
||||
// Hide if necessary, some properties
|
||||
if (_mHiddenProperties != null && _mHiddenProperties.Length > 0)
|
||||
@@ -182,33 +348,10 @@ namespace mRemoteNG.UI.Controls.FilteredPropertyGrid
|
||||
// Remove from the list the properties that mustn't be displayed.
|
||||
foreach (var propertyname in _mHiddenProperties)
|
||||
{
|
||||
try
|
||||
{
|
||||
var property = allproperties[propertyname];
|
||||
// Remove from the list the property
|
||||
HideProperty(property);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("FilteredPropertyGrid: Could not hide Property.",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
var property = _propertyDescriptors.FirstOrDefault(p => p.Name == propertyname);
|
||||
|
||||
// Display if necessary, some properties
|
||||
if (_mBrowsableProperties != null && _mBrowsableProperties.Length > 0)
|
||||
{
|
||||
foreach (var propertyname in _mBrowsableProperties)
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProperty(allproperties[propertyname]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("FilteredPropertyGrid: Property not found", ex);
|
||||
}
|
||||
// Remove from the list the property
|
||||
HideProperty(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -284,6 +284,7 @@
|
||||
<Compile Include="Themes\MremoteNGThemeBase.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Tools\Attributes\UsedInAllProtocolsExceptAttribute.cs" />
|
||||
<Compile Include="Tools\Clipboard\WindowsClipboard.cs" />
|
||||
<Compile Include="Tools\CustomCollections\IFullyNotifiableList.cs" />
|
||||
<Compile Include="Tools\CustomCollections\FullyObservableCollection.cs" />
|
||||
@@ -350,6 +351,7 @@
|
||||
<Compile Include="Tools\MultiSSHController.cs" />
|
||||
<Compile Include="Tools\MouseClickSimulator.cs" />
|
||||
<Compile Include="Tools\NotificationAreaIcon.cs" />
|
||||
<Compile Include="Tools\Attributes\UsedInProtocolAttribute.cs" />
|
||||
<Compile Include="Tools\WindowsRegistry\IRegistry.cs" />
|
||||
<Compile Include="Tools\WindowsRegistry\RegistryHive.cs" />
|
||||
<Compile Include="Tools\WindowsRegistry\WindowsRegistry.cs" />
|
||||
@@ -415,6 +417,13 @@
|
||||
<Compile Include="UI\Controls\ConnectionContextMenu.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UI\Controls\ConnectionInfoPropertyGrid\ConnectionInfoPropertyGrid.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UI\Controls\ConnectionInfoPropertyGrid\ConnectionInfoPropertyGrid.Designer.cs">
|
||||
<DependentUpon>ConnectionInfoPropertyGrid.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Controls\ConnectionInfoPropertyGrid\PropertyMode.cs" />
|
||||
<Compile Include="UI\Controls\ConnectionTree\ConnectionTree.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
@@ -1104,16 +1113,16 @@
|
||||
<None Include="Resources\Templates\Installer_Header.psd" />
|
||||
<None Include="Resources\Templates\Installer_Side.psd" />
|
||||
<None Include="Resources\Themes\darcula.vstheme">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Themes\vs2015blue.vstheme">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Themes\vs2015dark.vstheme">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Themes\vs2015light.vstheme">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Templates\VisualElements_150_dark.psd" />
|
||||
<None Include="Resources\Templates\VisualElements_150_light.psd" />
|
||||
@@ -1247,13 +1256,13 @@
|
||||
</Content>
|
||||
<None Include="Resources\Images\Header_dark.png" />
|
||||
<None Include="Resources\Tiles\mRemoteNG.VisualElementsManifest.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Tiles\VisualElements_70.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Tiles\VisualElements_150.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Resources\Icons\Appearance_Icon.ico" />
|
||||
<None Include="Resources\Icons\mRemoteNG_Icon.ico" />
|
||||
|
||||
Reference in New Issue
Block a user