From 7d8a5a2bdf930a604c628fffffdc4998b22e72cd Mon Sep 17 00:00:00 2001 From: David Sparer Date: Mon, 1 Apr 2019 13:26:25 -0500 Subject: [PATCH 01/10] added methods on the container info to push settings to children recursively --- .../Container/ContainerInfoTests.cs | 69 ++++++++++++++++++- ...AllConnectionPropertiesEqualityComparer.cs | 30 ++++++++ ...nheritanceAllPropertiesEqualityComparer.cs | 30 ++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 2 + mRemoteV1/Container/ContainerInfo.cs | 28 ++++++++ 5 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs create mode 100644 mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs diff --git a/mRemoteNGTests/Container/ContainerInfoTests.cs b/mRemoteNGTests/Container/ContainerInfoTests.cs index 8c08a419..0c8cb3b3 100644 --- a/mRemoteNGTests/Container/ContainerInfoTests.cs +++ b/mRemoteNGTests/Container/ContainerInfoTests.cs @@ -2,12 +2,13 @@ using System.Linq; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNGTests.TestHelpers; using NUnit.Framework; namespace mRemoteNGTests.Container { - public class ContainerInfoTests + public class ContainerInfoTests { private ContainerInfo _containerInfo; private ConnectionInfo _con1; @@ -434,5 +435,69 @@ namespace mRemoteNGTests.Container var grandchildOrderAfterSort = _containerInfo.Children.ToArray(); Assert.That(grandchildOrderAfterSort, Is.Ordered.Descending.By(nameof(ConnectionInfo.ConstantID))); } - } + + [Test] + public void CanApplyConnectionSettingsToChildren() + { + var comparer = new ConnectionInfoAllConnectionPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); + var con2 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); + container.AddChild(con1); + container.AddChild(con2); + + container.ApplyConnectionPropertiesToChildren(); + + Assert.That(con1, Is.EqualTo(container).Using(comparer)); + Assert.That(con2, Is.EqualTo(container).Using(comparer)); + } + + [Test] + public void ApplyConnectionPropertiesToChildrenWorksRecursively() + { + var comparer = new ConnectionInfoAllConnectionPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var subContainer = ConnectionInfoHelpers.GetRandomizedContainerInfo(); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); + container.AddChild(subContainer); + subContainer.AddChild(con1); + + container.ApplyConnectionPropertiesToChildren(); + + Assert.That(subContainer, Is.EqualTo(container).Using(comparer)); + Assert.That(con1, Is.EqualTo(container).Using(comparer)); + } + + [Test] + public void CanApplyInheritanceSettingsToChildren() + { + var comparer = new ConnectionInheritanceAllPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(randomizeInheritance:true); + var con2 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(randomizeInheritance: true); + container.AddChild(con1); + container.AddChild(con2); + + container.ApplyInheritancePropertiesToChildren(); + + Assert.That(con1.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + Assert.That(con2.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + } + + [Test] + public void ApplyInheritancePropertiesToChildrenWorksRecursively() + { + var comparer = new ConnectionInheritanceAllPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var subContainer = ConnectionInfoHelpers.GetRandomizedContainerInfo(randomizeInheritance: true); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(randomizeInheritance: true); + container.AddChild(subContainer); + subContainer.AddChild(con1); + + container.ApplyInheritancePropertiesToChildren(); + + Assert.That(subContainer.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + Assert.That(con1.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + } + } } \ No newline at end of file diff --git a/mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs b/mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs new file mode 100644 index 00000000..33aaf926 --- /dev/null +++ b/mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Connection; + +namespace mRemoteNGTests.TestHelpers +{ + public class ConnectionInfoAllConnectionPropertiesEqualityComparer : IEqualityComparer + { + public bool Equals(ConnectionInfo x, ConnectionInfo y) + { + if (x == null && y == null) + return true; + if ((x == null) != (y == null)) + return false; + return GetHashCode(x) == GetHashCode(y); + } + + public int GetHashCode(ConnectionInfo connectionInfo) + { + var allProperties = connectionInfo.GetSerializableProperties(); + + unchecked // Overflow is fine, just wrap + { + return allProperties + .Aggregate(17, + (current, prop) => current * 23 + prop.GetValue(connectionInfo).GetHashCode()); + } + } + } +} diff --git a/mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs b/mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs new file mode 100644 index 00000000..21fef6f9 --- /dev/null +++ b/mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Connection; + +namespace mRemoteNGTests.TestHelpers +{ + public class ConnectionInheritanceAllPropertiesEqualityComparer : IEqualityComparer + { + public bool Equals(ConnectionInfoInheritance x, ConnectionInfoInheritance y) + { + if (x == null && y == null) + return true; + if ((x == null) != (y == null)) + return false; + return GetHashCode(x) == GetHashCode(y); + } + + public int GetHashCode(ConnectionInfoInheritance inheritance) + { + var allProperties = inheritance.GetProperties(); + + unchecked // Overflow is fine, just wrap + { + return allProperties + .Aggregate(17, + (current, prop) => current * 23 + prop.GetValue(inheritance).GetHashCode()); + } + } + } +} diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 255dc136..159eeec5 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -177,7 +177,9 @@ + + diff --git a/mRemoteV1/Container/ContainerInfo.cs b/mRemoteV1/Container/ContainerInfo.cs index fa2e901c..90cf6a5d 100644 --- a/mRemoteV1/Container/ContainerInfo.cs +++ b/mRemoteV1/Container/ContainerInfo.cs @@ -263,6 +263,34 @@ namespace mRemoteNG.Container return childList; } + /// + /// Pushes the connection properties of this container to all + /// children recursively. + /// + public void ApplyConnectionPropertiesToChildren() + { + var children = GetRecursiveChildList(); + + foreach (var child in children) + { + child.CopyFrom(this); + } + } + + /// + /// Pushes the inheritance settings of this container to all + /// children recursively. + /// + public void ApplyInheritancePropertiesToChildren() + { + var children = GetRecursiveChildList(); + + foreach (var child in children) + { + child.Inheritance = Inheritance.Clone(child); + } + } + private IEnumerable GetRecursiveFavoritChildList(ContainerInfo container) { var childList = new List(); From 11ad8a8398f73300d36b232c3889db7028250570 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 25 Apr 2019 10:21:09 -0500 Subject: [PATCH 02/10] simplified how inheritance is globally disabled/enabled --- mRemoteV1/Connection/ConnectionInfo.cs | 5 +- .../Connection/ConnectionInfoInheritance.cs | 52 +++++++++---------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/mRemoteV1/Connection/ConnectionInfo.cs b/mRemoteV1/Connection/ConnectionInfo.cs index aeca82a6..cdd3bcfe 100644 --- a/mRemoteV1/Connection/ConnectionInfo.cs +++ b/mRemoteV1/Connection/ConnectionInfo.cs @@ -197,7 +197,10 @@ namespace mRemoteNG.Connection private bool ShouldThisPropertyBeInherited(string propertyName) { - return ParentIsValidInheritanceTarget() && IsInheritanceTurnedOnForThisProperty(propertyName); + return + Inheritance.InheritanceActive && + ParentIsValidInheritanceTarget() && + IsInheritanceTurnedOnForThisProperty(propertyName); } private bool ParentIsValidInheritanceTarget() diff --git a/mRemoteV1/Connection/ConnectionInfoInheritance.cs b/mRemoteV1/Connection/ConnectionInfoInheritance.cs index 08849dba..47909de3 100644 --- a/mRemoteV1/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteV1/Connection/ConnectionInfoInheritance.cs @@ -8,8 +8,6 @@ namespace mRemoteNG.Connection { public class ConnectionInfoInheritance { - private ConnectionInfoInheritance _tempInheritanceStorage; - #region Public Properties #region General @@ -20,8 +18,8 @@ namespace mRemoteNG.Connection TypeConverter(typeof(MiscTools.YesNoTypeConverter))] public bool EverythingInherited { - get { return EverythingIsInherited(); } - set { SetAllValues(value); } + get => EverythingIsInherited(); + set => SetAllValues(value); } #endregion @@ -391,7 +389,16 @@ namespace mRemoteNG.Connection TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool VNCViewOnly {get; set;} #endregion - [Browsable(false)] public ConnectionInfo Parent { get; private set; } + [Browsable(false)] + public ConnectionInfo Parent { get; private set; } + + /// + /// Indicates whether this inheritance object is enabled. + /// When false, users of this object should not respect inheritance + /// settings for individual properties. + /// + [Browsable(false)] + public bool InheritanceActive { get; set; } #endregion @@ -408,31 +415,17 @@ namespace mRemoteNG.Connection { var newInheritance = (ConnectionInfoInheritance)MemberwiseClone(); newInheritance.Parent = parent; - newInheritance._tempInheritanceStorage = null; return newInheritance; } public void EnableInheritance() { - if (_tempInheritanceStorage != null) - UnstashInheritanceData(); - } - - private void UnstashInheritanceData() - { - SetAllValues(_tempInheritanceStorage); - _tempInheritanceStorage = null; + InheritanceActive = true; } public void DisableInheritance() { - StashInheritanceData(); - TurnOffInheritanceCompletely(); - } - - private void StashInheritanceData() - { - _tempInheritanceStorage = Clone(Parent); + InheritanceActive = false; } public void TurnOnInheritanceCompletely() @@ -466,15 +459,22 @@ namespace mRemoteNG.Connection /// public IEnumerable GetEnabledInheritanceProperties() { - return GetProperties() - .Where(property => (bool)property.GetValue(this)) - .Select(property => property.Name) - .ToList(); + return InheritanceActive + ? GetProperties() + .Where(property => (bool)property.GetValue(this)) + .Select(property => property.Name) + .ToList() + : Enumerable.Empty(); } private bool FilterProperty(PropertyInfo propertyInfo) { - var exclusions = new[] {"EverythingInherited", "Parent"}; + var exclusions = new[] + { + nameof(EverythingInherited), + nameof(Parent), + nameof(InheritanceActive) + }; var valueShouldNotBeFiltered = !exclusions.Contains(propertyInfo.Name); return valueShouldNotBeFiltered; } From 9173e9e56aef4e71237f6dfba07bb88a6099e819 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Mon, 29 Apr 2019 08:39:06 -0500 Subject: [PATCH 03/10] added a context menu item to push inheritance to child nodes --- ...ectionsDeserializerMremotengFormatTests.cs | 5 +++-- .../Connection/ConnectionInfoTests.cs | 10 ---------- mRemoteNGTests/Container/RootNodeInfoTests.cs | 16 +++++++++++---- .../Connection/ConnectionInfoInheritance.cs | 2 +- .../UI/Controls/ConnectionContextMenu.cs | 20 +++++++++++++++++++ 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsDeserializerMremotengFormatTests.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsDeserializerMremotengFormatTests.cs index 7eebe29b..f669970f 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsDeserializerMremotengFormatTests.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/Csv/CsvConnectionsDeserializerMremotengFormatTests.cs @@ -16,7 +16,7 @@ using NUnit.Framework; namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv { - public class CsvConnectionsDeserializerMremotengFormatTests + public class CsvConnectionsDeserializerMremotengFormatTests { private CsvConnectionsDeserializerMremotengFormat _deserializer; private CsvConnectionsSerializerMremotengFormat _serializer; @@ -165,7 +165,8 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv var ignoreProperties = new[] { nameof(ConnectionInfoInheritance.EverythingInherited), - nameof(ConnectionInfoInheritance.Parent) + nameof(ConnectionInfoInheritance.Parent), + nameof(ConnectionInfoInheritance.EverythingInherited) }; var properties = typeof(ConnectionInfoInheritance) .GetProperties() diff --git a/mRemoteNGTests/Connection/ConnectionInfoTests.cs b/mRemoteNGTests/Connection/ConnectionInfoTests.cs index 685138a6..e0569831 100644 --- a/mRemoteNGTests/Connection/ConnectionInfoTests.cs +++ b/mRemoteNGTests/Connection/ConnectionInfoTests.cs @@ -93,16 +93,6 @@ namespace mRemoteNGTests.Connection Assert.That(nameOfModifiedProperty, Is.EqualTo("OpenConnections")); } - [TestCaseSource(typeof(InheritancePropertyProvider), nameof(InheritancePropertyProvider.GetProperties))] - public void MovingAConnectionUnderRootNodeDisablesInheritance(PropertyInfo property) - { - var rootNode = new RootNodeInfo(RootNodeType.Connection); - _connectionInfo.Inheritance.EverythingInherited = true; - _connectionInfo.SetParent(rootNode); - var propertyValue = property.GetValue(_connectionInfo.Inheritance); - Assert.That(propertyValue, Is.False); - } - [TestCaseSource(typeof(InheritancePropertyProvider), nameof(InheritancePropertyProvider.GetProperties))] public void MovingAConnectionFromUnderRootNodeToUnderADifferentNodeEnablesInheritance(PropertyInfo property) { diff --git a/mRemoteNGTests/Container/RootNodeInfoTests.cs b/mRemoteNGTests/Container/RootNodeInfoTests.cs index fbd5894e..97927e68 100644 --- a/mRemoteNGTests/Container/RootNodeInfoTests.cs +++ b/mRemoteNGTests/Container/RootNodeInfoTests.cs @@ -4,15 +4,23 @@ using NUnit.Framework; namespace mRemoteNGTests.Container { - public class RootNodeInfoTests + public class RootNodeInfoTests { [Test] public void InheritanceIsDisabledForNodesDirectlyUnderRootNode() { - var rootNode = new RootNodeInfo(RootNodeType.Connection); - var con1 = new ConnectionInfo { Inheritance = { Password = true } }; + var expected = "UnInheritedValue"; + var rootNode = new RootNodeInfo(RootNodeType.Connection) + { + Description = "thisCameFromTheRootNode" + }; + var con1 = new ConnectionInfo + { + Description = expected, + Inheritance = { Description = true } + }; rootNode.AddChild(con1); - Assert.That(con1.Inheritance.Password, Is.False); + Assert.That(con1.Description, Is.EqualTo(expected)); } } } diff --git a/mRemoteV1/Connection/ConnectionInfoInheritance.cs b/mRemoteV1/Connection/ConnectionInfoInheritance.cs index 47909de3..18c07d2b 100644 --- a/mRemoteV1/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteV1/Connection/ConnectionInfoInheritance.cs @@ -398,7 +398,7 @@ namespace mRemoteNG.Connection /// settings for individual properties. /// [Browsable(false)] - public bool InheritanceActive { get; set; } + public bool InheritanceActive { get; set; } = true; #endregion diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index e99905ff..481b6d07 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -50,6 +50,7 @@ namespace mRemoteNG.UI.Controls private ToolStripMenuItem _cMenTreeImportFile; private ToolStripMenuItem _cMenTreeImportActiveDirectory; private ToolStripMenuItem _cMenTreeImportPortScan; + private ToolStripMenuItem _cMenTreeApplyInheritanceToChildren; private readonly ConnectionTree _connectionTree; private readonly IConnectionInitiator _connectionInitiator; @@ -98,6 +99,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeImportFile = new ToolStripMenuItem(); _cMenTreeImportActiveDirectory = new ToolStripMenuItem(); _cMenTreeImportPortScan = new ToolStripMenuItem(); + _cMenTreeApplyInheritanceToChildren = new ToolStripMenuItem(); _cMenTreeExportFile = new ToolStripMenuItem(); _cMenTreeSep4 = new ToolStripSeparator(); _cMenTreeAddConnection = new ToolStripMenuItem(); @@ -134,6 +136,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeSep4, _cMenTreeAddConnection, _cMenTreeAddFolder, + _cMenTreeApplyInheritanceToChildren, _toolStripSeparator1, _cMenTreeToolsSort, _cMenTreeMoveUp, @@ -396,8 +399,17 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveDown.Size = new System.Drawing.Size(199, 22); _cMenTreeMoveDown.Text = "Move down"; _cMenTreeMoveDown.Click += OnMoveDownClicked; + // + // _cMenTreeApplyInheritanceToChildren + // + _cMenTreeApplyInheritanceToChildren.Name = "_cMenTreeApplyInheritanceToChildren"; + _cMenTreeApplyInheritanceToChildren.Size = new System.Drawing.Size(199, 22); + _cMenTreeApplyInheritanceToChildren.Text = "Apply inheritance to children"; + _cMenTreeApplyInheritanceToChildren.Click += OnApplyInheritanceToChildrenClicked; } + + private void ApplyLanguage() { _cMenTreeConnect.Text = Language.strConnect; @@ -874,6 +886,14 @@ namespace mRemoteNG.UI.Controls } } + private void OnApplyInheritanceToChildrenClicked(object sender, EventArgs e) + { + if (!(_connectionTree.SelectedNode is ContainerInfo container)) + return; + + container.ApplyInheritancePropertiesToChildren(); + } + #endregion } } \ No newline at end of file From d3a2ba26ba68da17ff97e7fc73b9d97895f0a25d Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 10 May 2019 08:10:37 -0500 Subject: [PATCH 04/10] only allow pushing inheritance from containers --- mRemoteV1/UI/Controls/ConnectionContextMenu.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index 481b6d07..0f53f8f3 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -501,6 +501,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveUp.Enabled = false; _cMenTreeMoveDown.Enabled = false; _cMenTreeConnectWithOptionsViewOnly.Enabled = false; + _cMenTreeApplyInheritanceToChildren.Enabled = false; } internal void ShowHideMenuItemsForRootConnectionNode() @@ -518,6 +519,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveUp.Enabled = false; _cMenTreeMoveDown.Enabled = false; _cMenTreeConnectWithOptionsViewOnly.Enabled = false; + _cMenTreeApplyInheritanceToChildren.Enabled = false; } internal void ShowHideMenuItemsForContainer(ContainerInfo containerInfo) @@ -554,6 +556,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeImport.Enabled = false; _cMenTreeExportFile.Enabled = false; _cMenTreeConnectWithOptionsViewOnly.Enabled = false; + _cMenTreeApplyInheritanceToChildren.Enabled = false; } internal void ShowHideMenuItemsForConnectionNode(ConnectionInfo connectionInfo) @@ -575,6 +578,8 @@ namespace mRemoteNG.UI.Controls if (connectionInfo.Protocol != ProtocolType.RDP && connectionInfo.Protocol != ProtocolType.VNC) _cMenTreeConnectWithOptionsViewOnly.Enabled = false; + + _cMenTreeApplyInheritanceToChildren.Enabled = false; } internal void DisableShortcutKeys() From fb68d0bff3ff46f6a14df0b69cb14fec2c7b761b Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 10 May 2019 13:57:58 -0500 Subject: [PATCH 05/10] added a button to apply default inheritance to the selected node --- .../Resources/Language/Language.Designer.cs | 18 +++++++++++++ mRemoteV1/Resources/Language/Language.resx | 6 +++++ .../UI/Controls/ConnectionContextMenu.cs | 25 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 462d965e..061463bf 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -60,6 +60,24 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Apply default inheritance. + /// + internal static string ApplyDefaultInheritance { + get { + return ResourceManager.GetString("ApplyDefaultInheritance", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Apply inheritance to children. + /// + internal static string ApplyInheritanceToChildren { + get { + return ResourceManager.GetString("ApplyInheritanceToChildren", resourceCulture); + } + } + /// /// Looks up a localized string similar to An error occurred while trying to reconnect to RDP host '{0}'. /// diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index cf45009c..9590a305 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2793,4 +2793,10 @@ Development Channel includes Alphas, Betas & Release Candidates. Environment + + Apply default inheritance + + + Apply inheritance to children + \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index 0f53f8f3..98b23067 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -51,6 +51,7 @@ namespace mRemoteNG.UI.Controls private ToolStripMenuItem _cMenTreeImportActiveDirectory; private ToolStripMenuItem _cMenTreeImportPortScan; private ToolStripMenuItem _cMenTreeApplyInheritanceToChildren; + private ToolStripMenuItem _cMenTreeApplyDefaultInheritance; private readonly ConnectionTree _connectionTree; private readonly IConnectionInitiator _connectionInitiator; @@ -100,6 +101,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeImportActiveDirectory = new ToolStripMenuItem(); _cMenTreeImportPortScan = new ToolStripMenuItem(); _cMenTreeApplyInheritanceToChildren = new ToolStripMenuItem(); + _cMenTreeApplyDefaultInheritance = new ToolStripMenuItem(); _cMenTreeExportFile = new ToolStripMenuItem(); _cMenTreeSep4 = new ToolStripSeparator(); _cMenTreeAddConnection = new ToolStripMenuItem(); @@ -137,6 +139,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeAddConnection, _cMenTreeAddFolder, _cMenTreeApplyInheritanceToChildren, + _cMenTreeApplyDefaultInheritance, _toolStripSeparator1, _cMenTreeToolsSort, _cMenTreeMoveUp, @@ -406,9 +409,15 @@ namespace mRemoteNG.UI.Controls _cMenTreeApplyInheritanceToChildren.Size = new System.Drawing.Size(199, 22); _cMenTreeApplyInheritanceToChildren.Text = "Apply inheritance to children"; _cMenTreeApplyInheritanceToChildren.Click += OnApplyInheritanceToChildrenClicked; + // + // _cMenTreeApplyDefaultInheritance + // + _cMenTreeApplyDefaultInheritance.Name = "_cMenTreeApplyDefaultInheritance"; + _cMenTreeApplyDefaultInheritance.Size = new System.Drawing.Size(199, 22); + _cMenTreeApplyDefaultInheritance.Text = "Apply default inheritance"; + _cMenTreeApplyDefaultInheritance.Click += OnApplyDefaultInheritanceClicked; } - private void ApplyLanguage() { @@ -445,6 +454,9 @@ namespace mRemoteNG.UI.Controls _cMenTreeToolsSortDescending.Text = Language.strSortDesc; _cMenTreeMoveUp.Text = Language.strMoveUp; _cMenTreeMoveDown.Text = Language.strMoveDown; + + _cMenTreeApplyInheritanceToChildren.Text = Language.ApplyInheritanceToChildren; + _cMenTreeApplyDefaultInheritance.Text = Language.ApplyDefaultInheritance; } internal void ShowHideMenuItems() @@ -502,6 +514,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveDown.Enabled = false; _cMenTreeConnectWithOptionsViewOnly.Enabled = false; _cMenTreeApplyInheritanceToChildren.Enabled = false; + _cMenTreeApplyDefaultInheritance.Enabled = false; } internal void ShowHideMenuItemsForRootConnectionNode() @@ -520,6 +533,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveDown.Enabled = false; _cMenTreeConnectWithOptionsViewOnly.Enabled = false; _cMenTreeApplyInheritanceToChildren.Enabled = false; + _cMenTreeApplyDefaultInheritance.Enabled = false; } internal void ShowHideMenuItemsForContainer(ContainerInfo containerInfo) @@ -557,6 +571,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeExportFile.Enabled = false; _cMenTreeConnectWithOptionsViewOnly.Enabled = false; _cMenTreeApplyInheritanceToChildren.Enabled = false; + _cMenTreeApplyDefaultInheritance.Enabled = false; } internal void ShowHideMenuItemsForConnectionNode(ConnectionInfo connectionInfo) @@ -899,6 +914,14 @@ namespace mRemoteNG.UI.Controls container.ApplyInheritancePropertiesToChildren(); } + private void OnApplyDefaultInheritanceClicked(object sender, EventArgs e) + { + if (_connectionTree.SelectedNode == null) + return; + + DefaultConnectionInheritance.Instance.SaveTo(_connectionTree.SelectedNode.Inheritance); + } + #endregion } } \ No newline at end of file From af24e3b28498a6f802b9063f84a16f57ae9a279b Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 10 May 2019 15:41:43 -0500 Subject: [PATCH 06/10] the inheritance button will now be shown on items whose parent is the root node --- .../ConnectionInfoInheritanceTests.cs | 110 ++++++++++-------- mRemoteNGTests/mRemoteNGTests.csproj | 2 + mRemoteNGTests/packages.config | 1 + .../Connection/ConnectionInfoInheritance.cs | 13 +-- mRemoteV1/Tree/Root/RootNodeInfo.cs | 14 +-- .../UI/Controls/ConnectionContextMenu.cs | 2 +- mRemoteV1/UI/Window/ConfigWindow.cs | 6 +- 7 files changed, 72 insertions(+), 76 deletions(-) diff --git a/mRemoteNGTests/Connection/ConnectionInfoInheritanceTests.cs b/mRemoteNGTests/Connection/ConnectionInfoInheritanceTests.cs index 2b18a5dc..e1e582ce 100644 --- a/mRemoteNGTests/Connection/ConnectionInfoInheritanceTests.cs +++ b/mRemoteNGTests/Connection/ConnectionInfoInheritanceTests.cs @@ -1,77 +1,91 @@ -using mRemoteNG.Connection; -using mRemoteNG.Container; -using NUnit.Framework; -using System.Collections; +using System.Collections; using System.Linq; using System.Reflection; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree.Root; +using NUnit.Framework; namespace mRemoteNGTests.Connection { - [TestFixture] + [TestFixture] public class ConnectionInfoInheritanceTests { - private ConnectionInfo _connectionInfo; - private ConnectionInfoInheritance _inheritance; - private PropertyInfo[] _inheritanceProperties = typeof(ConnectionInfoInheritance).GetProperties(); + private readonly PropertyInfo[] _inheritanceProperties = typeof(ConnectionInfoInheritance).GetProperties(); - [SetUp] - public void Setup() - { - _connectionInfo = new ConnectionInfo(); - _inheritance = new ConnectionInfoInheritance(_connectionInfo); - } - - [TearDown] - public void Teardown() - { - _connectionInfo = null; - _inheritance = null; - } - - [Test] + [Test] public void TurnOffInheritanceCompletely() { - _inheritance.Username = true; - _inheritance.TurnOffInheritanceCompletely(); - Assert.That(AllInheritancePropertiesAreFalse(), Is.True); + var inheritance = new ConnectionInfoInheritance(new ConnectionInfo()) {Username = true}; + inheritance.TurnOffInheritanceCompletely(); + Assert.That(AllInheritancePropertiesAreFalse(inheritance), Is.True); } [Test] public void TurnOnInheritanceCompletely() { - _inheritance.TurnOnInheritanceCompletely(); - Assert.That(AllInheritancePropertiesAreTrue(), Is.True); + var inheritance = new ConnectionInfoInheritance(new ConnectionInfo()); + inheritance.TurnOnInheritanceCompletely(); + Assert.That(AllInheritancePropertiesAreTrue(inheritance), Is.True); } [Test] - public void DisableInheritanceTurnsOffAllInheritance() + public void InheritanceIsDisabledWhenAttachedToARootNode() { - _inheritance.Username = true; - _inheritance.DisableInheritance(); - Assert.That(AllInheritancePropertiesAreFalse(), Is.True); + var inheritance = new ConnectionInfoInheritance(new RootNodeInfo(RootNodeType.Connection)); + Assert.That(inheritance.InheritanceActive, Is.False); } [Test] - public void EnableInheritanceRestoresPreviousInheritanceValues() + public void InheritanceIsDisabledWhenAttachedToAPuttyRootNode() { - _inheritance.Username = true; - _inheritance.DisableInheritance(); - _inheritance.EnableInheritance(); - Assert.That(_inheritance.Username, Is.True); + var inheritance = new ConnectionInfoInheritance(new RootNodeInfo(RootNodeType.PuttySessions)); + Assert.That(inheritance.InheritanceActive, Is.False); } [Test] + public void InheritanceIsDisabledWhenAttachedToAPuttyNode() + { + var inheritance = new ConnectionInfoInheritance(new RootPuttySessionsNodeInfo()); + Assert.That(inheritance.InheritanceActive, Is.False); + } + + [Test] + public void InheritanceIsDisabledWhenAttachedToANodeDirectlyUnderTheRootNode() + { + var con = new ConnectionInfo(); + new RootNodeInfo(RootNodeType.Connection).AddChild(con); + Assert.That(con.Inheritance.InheritanceActive, Is.False); + } + + [Test] + public void InheritanceIsEnabledWhenAttachedToNormalConnectionInfo() + { + var inheritance = new ConnectionInfoInheritance(new ConnectionInfo()); + Assert.That(inheritance.InheritanceActive, Is.True); + } + + [Test] + public void InheritanceIsEnabledWhenAttachedToNormalContainerInfo() + { + var inheritance = new ConnectionInfoInheritance(new ContainerInfo()); + Assert.That(inheritance.InheritanceActive, Is.True); + } + + [Test] public void GetPropertiesReturnsListOfSettableProperties() { - var hasIconProperty = _inheritance.GetProperties().Contains(typeof(ConnectionInfoInheritance).GetProperty("Icon")); + var inheritance = new ConnectionInfoInheritance(new ConnectionInfo()); + var hasIconProperty = inheritance.GetProperties().Contains(typeof(ConnectionInfoInheritance).GetProperty("Icon")); Assert.That(hasIconProperty, Is.True); } [Test] public void GetPropertiesExludesPropertiesThatShouldNotBeSet() { - var hasEverythingInheritedProperty = _inheritance.GetProperties().Contains(typeof(ConnectionInfoInheritance).GetProperty("EverythingInherited")); + var inheritance = new ConnectionInfoInheritance(new ConnectionInfo()); + var hasEverythingInheritedProperty = inheritance.GetProperties().Contains(typeof(ConnectionInfoInheritance).GetProperty("EverythingInherited")); Assert.That(hasEverythingInheritedProperty, Is.False); } @@ -91,23 +105,25 @@ namespace mRemoteNGTests.Connection Assert.That(con1.AutomaticResize, Is.EqualTo(expectedSetting)); } - private bool AllInheritancePropertiesAreTrue() + private bool AllInheritancePropertiesAreTrue(ConnectionInfoInheritance inheritance) { var allPropertiesTrue = true; foreach (var property in _inheritanceProperties) { - if (PropertyIsBoolean(property) && PropertyIsChangedWhenSettingInheritAll(property) && BooleanPropertyIsSetToFalse(property)) + if (PropertyIsBoolean(property) && PropertyIsChangedWhenSettingInheritAll(property) && + BooleanPropertyIsSetToFalse(property, inheritance)) allPropertiesTrue = false; } return allPropertiesTrue; } - private bool AllInheritancePropertiesAreFalse() + private bool AllInheritancePropertiesAreFalse(ConnectionInfoInheritance inheritance) { var allPropertiesFalse = true; foreach (var property in _inheritanceProperties) { - if (PropertyIsBoolean(property) && PropertyIsChangedWhenSettingInheritAll(property) && BooleanPropertyIsSetToTrue(property)) + if (PropertyIsBoolean(property) && PropertyIsChangedWhenSettingInheritAll(property) && + BooleanPropertyIsSetToTrue(property, inheritance)) allPropertiesFalse = false; } return allPropertiesFalse; @@ -124,14 +140,14 @@ namespace mRemoteNGTests.Connection return (property.PropertyType.Name == typeof(bool).Name); } - private bool BooleanPropertyIsSetToFalse(PropertyInfo property) + private bool BooleanPropertyIsSetToFalse(PropertyInfo property, ConnectionInfoInheritance inheritance) { - return (bool)property.GetValue(_inheritance) == false; + return (bool)property.GetValue(inheritance) == false; } - private bool BooleanPropertyIsSetToTrue(PropertyInfo property) + private bool BooleanPropertyIsSetToTrue(PropertyInfo property, ConnectionInfoInheritance inheritance) { - return (bool)property.GetValue(_inheritance); + return (bool)property.GetValue(inheritance); } } } \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 140258a0..eb830eaa 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -1,5 +1,6 @@  + Debug @@ -344,6 +345,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. +