diff --git a/mRemoteNGTests/Config/Connections/DataTableSerializerTests.cs b/mRemoteNGTests/Config/Connections/DataTableSerializerTests.cs index add449e6..08173570 100644 --- a/mRemoteNGTests/Config/Connections/DataTableSerializerTests.cs +++ b/mRemoteNGTests/Config/Connections/DataTableSerializerTests.cs @@ -119,9 +119,9 @@ namespace mRemoteNGTests.Config.Connections var con1 = new ConnectionInfo {Name = "Con1", Username = "user1", Domain = "domain1", Password = "password1" }; var con2 = new ConnectionInfo {Name = "Con2", Username = "user2", Domain = "domain2", Password = "password2" }; - root.Add(folder1); - root.Add(con2); - folder1.Add(con1); + root.AddChild(folder1); + root.AddChild(con2); + folder1.AddChild(con1); model.AddRootNode(root); return model; } diff --git a/mRemoteNGTests/Container/ContainerInfoTests.cs b/mRemoteNGTests/Container/ContainerInfoTests.cs index 52899106..61a99a0a 100644 --- a/mRemoteNGTests/Container/ContainerInfoTests.cs +++ b/mRemoteNGTests/Container/ContainerInfoTests.cs @@ -27,14 +27,14 @@ namespace mRemoteNGTests.Container [Test] public void AddSetsParentPropertyOnTheChild() { - _containerInfo.Add(_connectionInfo); + _containerInfo.AddChild(_connectionInfo); Assert.That(_connectionInfo.Parent, Is.EqualTo(_containerInfo)); } [Test] public void AddAddsChildToChildrenList() { - _containerInfo.Add(_connectionInfo); + _containerInfo.AddChild(_connectionInfo); Assert.That(_containerInfo.Children, Does.Contain(_connectionInfo)); } @@ -42,23 +42,23 @@ namespace mRemoteNGTests.Container public void AddRangeAddsAllItems() { var collection = new[] {new ConnectionInfo(),new ConnectionInfo(), new ContainerInfo()}; - _containerInfo.AddRange(collection); + _containerInfo.AddChildRange(collection); Assert.That(_containerInfo.Children, Is.EquivalentTo(collection)); } [Test] public void RemoveUnsetsParentPropertyOnChild() { - _containerInfo.Add(_connectionInfo); - _containerInfo.Remove(_connectionInfo); + _containerInfo.AddChild(_connectionInfo); + _containerInfo.RemoveChild(_connectionInfo); Assert.That(_connectionInfo.Parent, Is.Not.EqualTo(_containerInfo)); } [Test] public void RemoveRemovesChildFromChildrenList() { - _containerInfo.Add(_connectionInfo); - _containerInfo.Remove(_connectionInfo); + _containerInfo.AddChild(_connectionInfo); + _containerInfo.RemoveChild(_connectionInfo); Assert.That(_containerInfo.Children, Does.Not.Contains(_connectionInfo)); } @@ -66,8 +66,8 @@ namespace mRemoteNGTests.Container public void RemoveRangeRemovesAllIndicatedItems() { var collection = new[] { new ConnectionInfo(), new ConnectionInfo(), new ContainerInfo() }; - _containerInfo.AddRange(collection); - _containerInfo.RemoveRange(collection); + _containerInfo.AddChildRange(collection); + _containerInfo.RemoveChildRange(collection); Assert.That(_containerInfo.Children, Does.Not.Contains(collection[0]).And.Not.Contains(collection[1]).And.Not.Contains(collection[2])); } @@ -75,9 +75,9 @@ namespace mRemoteNGTests.Container public void RemoveRangeDoesNotRemoveUntargetedMembers() { var collection = new[] { new ConnectionInfo(), new ConnectionInfo(), new ContainerInfo() }; - _containerInfo.AddRange(collection); - _containerInfo.Add(_connectionInfo); - _containerInfo.RemoveRange(collection); + _containerInfo.AddChildRange(collection); + _containerInfo.AddChild(_connectionInfo); + _containerInfo.RemoveChildRange(collection); Assert.That(_containerInfo.Children, Does.Contain(_connectionInfo)); } } diff --git a/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs b/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs index 8169f6fa..c5645473 100644 --- a/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs +++ b/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs @@ -39,9 +39,9 @@ namespace mRemoteNGTests.IntegrationTests var connection1 = new ConnectionInfo(); var connection2 = new ConnectionInfo(); var connection3 = new ConnectionInfo {Inheritance = {Username = true}}; - _rootNode.Add(folder1); - folder1.AddRange(new []{connection1, folder2, connection3}); - folder2.Add(connection2); + _rootNode.AddChild(folder1); + folder1.AddChildRange(new []{connection1, folder2, connection3}); + folder2.AddChild(connection2); Assert.That(connection3.Username, Is.EqualTo(folder1.Username)); } @@ -50,8 +50,8 @@ namespace mRemoteNGTests.IntegrationTests { var folder = new ContainerInfo() {Protocol = ProtocolType.SSH2, Username = "folderUser", Domain = "CoolDomain"}; var connection = new ConnectionInfo() {Inheritance = {EverythingInherited = true}}; - _rootNode.Add(folder); - folder.Add(connection); + _rootNode.AddChild(folder); + folder.AddChild(connection); Assert.That(new object[] { connection.Protocol, connection.Username, connection.Domain }, Is.EquivalentTo(new object[] {folder.Protocol, folder.Username, folder.Domain})); } @@ -62,10 +62,10 @@ namespace mRemoteNGTests.IntegrationTests var folder2 = new ContainerInfo {Inheritance = {Username = true}}; var folder3 = new ContainerInfo {Inheritance = {Username = true}}; var connection = new ConnectionInfo {Inheritance = {Username = true}}; - _rootNode.Add(folder1); - folder1.Add(folder2); - folder2.Add(folder3); - folder3.Add(connection); + _rootNode.AddChild(folder1); + folder1.AddChild(folder2); + folder2.AddChild(folder3); + folder3.AddChild(connection); Assert.That(connection.Username, Is.EqualTo(folder1.Username)); } } diff --git a/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs b/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs index f8d0d168..b392e962 100644 --- a/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs +++ b/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs @@ -29,9 +29,9 @@ namespace mRemoteNGTests.Tree var folder1 = new ContainerInfo(); var folder2 = new ContainerInfo(); var con1 = new ConnectionInfo(); - root.Add(folder1); - folder1.Add(folder2); - root.Add(con1); + root.AddChild(folder1); + folder1.AddChild(folder2); + root.AddChild(con1); _connectionTreeModel.AddRootNode(root); var connectionList = _connectionTreeModel.GetRecursiveChildList(root); Assert.That(connectionList, Is.EquivalentTo(new[] {folder1,folder2,con1})); diff --git a/mRemoteNGTests/UI/ConnectionTreeViewBuilderTests.cs b/mRemoteNGTests/UI/ConnectionTreeViewBuilderTests.cs index 05dffa1c..a9e7de66 100644 --- a/mRemoteNGTests/UI/ConnectionTreeViewBuilderTests.cs +++ b/mRemoteNGTests/UI/ConnectionTreeViewBuilderTests.cs @@ -48,7 +48,7 @@ namespace mRemoteNGTests.UI */ var root = CreateRootNode(); var con1 = new ConnectionInfo(); - root.Add(con1); + root.AddChild(con1); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(rootTreeNode.Nodes[0].Tag, Is.EqualTo(con1)); @@ -63,7 +63,7 @@ namespace mRemoteNGTests.UI */ var root = CreateRootNode(); var folder1 = new ContainerInfo(); - root.Add(folder1); + root.AddChild(folder1); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(rootTreeNode.Nodes[0].Tag, Is.EqualTo(folder1)); @@ -80,7 +80,7 @@ namespace mRemoteNGTests.UI var root = CreateRootNode(); var con1 = new ConnectionInfo(); var con2 = new ConnectionInfo(); - root.AddRange(new []{con1, con2}); + root.AddChildRange(new []{con1, con2}); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(GetTreeNodeTags(rootTreeNode.Nodes), Is.EquivalentTo(new[] { con1, con2 })); @@ -97,8 +97,8 @@ namespace mRemoteNGTests.UI var root = CreateRootNode(); var folder1 = new ContainerInfo(); var con1 = new ConnectionInfo(); - root.Add(folder1); - folder1.Add(con1); + root.AddChild(folder1); + folder1.AddChild(con1); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(rootTreeNode.Nodes[0].Tag, Is.EqualTo(folder1)); @@ -118,9 +118,9 @@ namespace mRemoteNGTests.UI var folder1 = new ContainerInfo(); var con1 = new ConnectionInfo(); var folder2 = new ContainerInfo(); - root.Add(folder1); - folder1.Add(con1); - root.Add(folder2); + root.AddChild(folder1); + folder1.AddChild(con1); + root.AddChild(folder2); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(rootTreeNode.Nodes[0].Tag, Is.EqualTo(folder1)); @@ -141,9 +141,9 @@ namespace mRemoteNGTests.UI var folder1 = new ContainerInfo(); var folder2 = new ContainerInfo(); var con1 = new ConnectionInfo(); - root.Add(folder1); - folder1.Add(folder2); - folder2.Add(con1); + root.AddChild(folder1); + folder1.AddChild(folder2); + folder2.AddChild(con1); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(rootTreeNode.Nodes[0].Nodes[0].Nodes[0].Tag, Is.EqualTo(con1)); @@ -168,12 +168,12 @@ namespace mRemoteNGTests.UI var folder3 = new ContainerInfo(); var folder4 = new ContainerInfo(); var con2 = new ConnectionInfo(); - root.Add(folder1); - folder1.Add(folder2); - folder2.Add(con1); - root.Add(folder3); - folder3.Add(folder4); - folder4.Add(con2); + root.AddChild(folder1); + folder1.AddChild(folder2); + folder2.AddChild(con1); + root.AddChild(folder3); + folder3.AddChild(folder4); + folder4.AddChild(con2); _connectionTreeViewBuilder.Build(); var rootTreeNode = _connectionTreeViewBuilder.RootNode; Assert.That(rootTreeNode.Nodes[0].Nodes[0].Nodes[0].Tag, Is.EqualTo(con1)); diff --git a/mRemoteV1/Config/Connections/DataTableDeserializer.cs b/mRemoteV1/Config/Connections/DataTableDeserializer.cs index f6598c99..b6b02718 100644 --- a/mRemoteV1/Config/Connections/DataTableDeserializer.cs +++ b/mRemoteV1/Config/Connections/DataTableDeserializer.cs @@ -189,9 +189,9 @@ namespace mRemoteNG.Config.Connections var connectionInfo = connectionList.First(node => node.ConstantID == id); var parentId = (string) row["ParentID"]; if (parentId == "0") - rootNode.Add(connectionInfo); + rootNode.AddChild(connectionInfo); else - (connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.Add(connectionInfo); + (connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.AddChild(connectionInfo); } return connectionTreeModel; } diff --git a/mRemoteV1/Config/Connections/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Connections/XmlConnectionsDeserializer.cs index 4b73f9b9..9cca6fe0 100644 --- a/mRemoteV1/Config/Connections/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Connections/XmlConnectionsDeserializer.cs @@ -140,7 +140,7 @@ namespace mRemoteNG.Config.Connections if (nodeType == TreeNodeType.Connection) { var connectionInfo = GetConnectionInfoFromXml(xmlNode); - parentContainer.Add(connectionInfo); + parentContainer.AddChild(connectionInfo); ConnectionList.Add(connectionInfo); } else if (nodeType == TreeNodeType.Container) @@ -152,7 +152,7 @@ namespace mRemoteNG.Config.Connections if (_confVersion >= 0.8) containerInfo.IsExpanded = xmlNode.Attributes?["Expanded"].Value == "True"; - parentContainer.Add(containerInfo); + parentContainer.AddChild(containerInfo); ContainerList.Add(containerInfo); AddNodesFromXmlRecursive(xmlNode, containerInfo); } diff --git a/mRemoteV1/Connection/ConnectionInfo.cs b/mRemoteV1/Connection/ConnectionInfo.cs index b76e8aac..c27237dd 100644 --- a/mRemoteV1/Connection/ConnectionInfo.cs +++ b/mRemoteV1/Connection/ConnectionInfo.cs @@ -23,7 +23,7 @@ using mRemoteNG.Tree; namespace mRemoteNG.Connection { [DefaultProperty("Name")] - public class ConnectionInfo : IParent, IInheritable + public class ConnectionInfo : IHasParent, IInheritable, IDisposable { #region Private Properties private string _description; @@ -78,6 +78,7 @@ namespace mRemoteNG.Connection private ProtocolVNC.Colors _vncColors; private ProtocolVNC.SmartSizeMode _vncSmartSizeMode; private bool _vncViewOnly; + private ContainerInfo _parent; #endregion #region Public Properties @@ -624,7 +625,7 @@ namespace mRemoteNG.Connection public bool IsDefault { get; set; } [Browsable(false)] - public ContainerInfo Parent { get; set; } + public ContainerInfo Parent { get; internal set; } [Browsable(false)] public int PositionID { get; set; } @@ -662,7 +663,7 @@ namespace mRemoteNG.Connection public ConnectionInfo(ContainerInfo parent) : this() { IsContainer = true; - parent.Add(this); + parent.AddChild(this); } #endregion @@ -714,6 +715,21 @@ namespace mRemoteNG.Connection var filteredProperties = properties.Where((prop) => !excludedPropertyNames.Contains(prop.Name)); return filteredProperties; } + + public void SetParent(ContainerInfo parent) + { + parent.AddChild(this); + } + + public void RemoveParent() + { + Parent?.RemoveChild(this); + } + + public virtual void Dispose() + { + RemoveParent(); + } #endregion #region Public Enumerations diff --git a/mRemoteV1/Connection/IHasParent.cs b/mRemoteV1/Connection/IHasParent.cs new file mode 100644 index 00000000..d43997fc --- /dev/null +++ b/mRemoteV1/Connection/IHasParent.cs @@ -0,0 +1,11 @@ +using mRemoteNG.Container; + +namespace mRemoteNG.Connection +{ + public interface IHasParent + { + ContainerInfo Parent { get; } + + void SetParent(ContainerInfo containerInfo); + } +} \ No newline at end of file diff --git a/mRemoteV1/Connection/IParent.cs b/mRemoteV1/Connection/IParent.cs deleted file mode 100644 index 49145a19..00000000 --- a/mRemoteV1/Connection/IParent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using mRemoteNG.Container; - -namespace mRemoteNG.Connection -{ - public interface IParent - { - ContainerInfo Parent { get; set; } - } -} \ No newline at end of file diff --git a/mRemoteV1/Container/ContainerInfo.cs b/mRemoteV1/Container/ContainerInfo.cs index e7ae83b3..70e94871 100644 --- a/mRemoteV1/Container/ContainerInfo.cs +++ b/mRemoteV1/Container/ContainerInfo.cs @@ -25,34 +25,42 @@ namespace mRemoteNG.Container return TreeNodeType.Container; } - public void Add(ConnectionInfo newChildItem) + public void AddChild(ConnectionInfo newChildItem) { newChildItem.Parent = this; Children.Add(newChildItem); } - public void AddRange(IEnumerable newChildren) + public void AddChildRange(IEnumerable newChildren) { foreach (var child in newChildren) { - Add(child); + AddChild(child); } } - public void Remove(ConnectionInfo removalTarget) + public void RemoveChild(ConnectionInfo removalTarget) { removalTarget.Parent = null; Children.Remove(removalTarget); } - public void RemoveRange(IEnumerable removalTargets) + public void RemoveChildRange(IEnumerable removalTargets) { foreach (var child in removalTargets) { - Remove(child); + RemoveChild(child); } } + public override void Dispose() + { + var tempChildList = Children.ToArray(); + foreach (var child in tempChildList) + child.Dispose(); + RemoveParent(); + } + public new ContainerInfo Copy() { return (ContainerInfo)MemberwiseClone(); diff --git a/mRemoteV1/Tree/ConnectionTreeModel.cs b/mRemoteV1/Tree/ConnectionTreeModel.cs index fc4562fd..425e9ad7 100644 --- a/mRemoteV1/Tree/ConnectionTreeModel.cs +++ b/mRemoteV1/Tree/ConnectionTreeModel.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.Tree.Root; namespace mRemoteNG.Tree @@ -18,5 +19,23 @@ namespace mRemoteNG.Tree { return container.GetRecursiveChildList(); } + + public void RenameNode(ConnectionInfo connectionInfo, string newName) + { + if (newName == null || newName.Length <= 0) + return; + + connectionInfo.Name = newName; + if (Settings.Default.SetHostnameLikeDisplayName) + connectionInfo.Hostname = newName; + } + + public void DeleteNode(ConnectionInfo connectionInfo) + { + if (connectionInfo is RootNodeInfo) + return; + + connectionInfo.Dispose(); + } } } \ No newline at end of file diff --git a/mRemoteV1/Tree/TreeNodeMover.cs b/mRemoteV1/Tree/TreeNodeMover.cs index eda89ded..9655cc5b 100644 --- a/mRemoteV1/Tree/TreeNodeMover.cs +++ b/mRemoteV1/Tree/TreeNodeMover.cs @@ -66,7 +66,7 @@ namespace mRemoteNG.Tree { if (ConnectionTreeNode.GetNodeType(_nodeBeingMoved.Parent) == TreeNodeType.Container) { - ((IParent)_nodeBeingMoved.Tag).Parent = (ContainerInfo)_nodeBeingMoved.Parent.Tag; + ((IHasParent)_nodeBeingMoved.Tag).SetParent((ContainerInfo)_nodeBeingMoved.Parent.Tag); ((IInheritable)_nodeBeingMoved.Tag).Inheritance.EnableInheritance(); } } @@ -75,7 +75,7 @@ namespace mRemoteNG.Tree { if (ConnectionTreeNode.GetNodeType(_nodeBeingMoved.Parent) == TreeNodeType.Root) { - ((IParent)_nodeBeingMoved.Tag).Parent = null; + ((IHasParent) _nodeBeingMoved.Tag).SetParent(null); ((IInheritable)_nodeBeingMoved.Tag).Inheritance.DisableInheritance(); } } diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 84c7b13f..d615367b 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -20,6 +20,7 @@ namespace mRemoteNG.UI.Window private ConnectionTreeModel _connectionTreeModel; private ToolTip DescriptionTooltip { get; } + private ConnectionInfo SelectedNode => (ConnectionInfo) olvConnections.SelectedObject; public ConnectionTreeModel ConnectionTreeModel { @@ -90,8 +91,8 @@ namespace mRemoteNG.UI.Window { olvConnections.Collapsed += (sender, args) => ((ContainerInfo) args.Model).IsExpanded = false; olvConnections.Expanded += (sender, args) => ((ContainerInfo) args.Model).IsExpanded = true; - //olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; - //olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; + olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; + olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; olvConnections.SelectionChanged += tvConnections_AfterSelect; } @@ -218,16 +219,14 @@ namespace mRemoteNG.UI.Window cMenTreeDelete.ShortcutKeys = Keys.None; } - //TODO Fix for TreeListView private void tvConnections_AfterLabelEdit(object sender, LabelEditEventArgs e) { try { cMenTreeDelete.ShortcutKeys = Keys.Delete; - - ConnectionTree.FinishRenameSelectedNode(e.Label); + ConnectionTreeModel.RenameNode(SelectedNode, e.Label); Windows.configForm.pGrid_SelectedObjectChanged(); - //ShowHideTreeContextMenuItems(e.Node); + ShowHideTreeContextMenuItems(SelectedNode); Runtime.SaveConnectionsBG(); } catch (Exception ex) @@ -236,7 +235,6 @@ namespace mRemoteNG.UI.Window } } - //TODO Fix for TreeListView private void tvConnections_AfterSelect(object sender, EventArgs e) { try @@ -661,18 +659,18 @@ namespace mRemoteNG.UI.Window Runtime.SaveConnectionsBG(); } - //TODO Fix for TreeListView private void cMenTreeRename_Click(object sender, EventArgs e) { - ConnectionTree.StartRenameSelectedNode(); + olvConnections.SelectedItem.BeginEdit(); Runtime.SaveConnectionsBG(); } //TODO Fix for TreeListView private void cMenTreeDelete_Click(object sender, EventArgs e) { - ConnectionTree.DeleteSelectedNode(); + ConnectionTreeModel.DeleteNode(SelectedNode); Runtime.SaveConnectionsBG(); + olvConnections.RebuildAll(true); } //TODO Fix for TreeListView diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index a8e05fa1..0f1f7fab 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -175,7 +175,7 @@ - +