Imports System.Windows.Forms Imports mRemoteNG.App.Runtime Imports System.DirectoryServices Namespace Tree Public Class Node Public Enum Type Root = 0 Container = 1 Connection = 2 NONE = 66 End Enum Private Shared _TreeView As TreeView Public Shared Property TreeView() As TreeView Get Return _TreeView End Get Set(ByVal value As TreeView) _TreeView = value End Set End Property Public Shared Property SelectedNode() As TreeNode Get Return _TreeView.SelectedNode End Get Set(ByVal value As TreeNode) treeNodeToBeSelected = value SelectNode() End Set End Property Private Shared treeNodeToBeSelected As TreeNode Private Delegate Sub SelectNodeCB() Private Shared Sub SelectNode() If _TreeView.InvokeRequired = True Then Dim d As New SelectNodeCB(AddressOf SelectNode) _TreeView.Invoke(d) Else _TreeView.SelectedNode = treeNodeToBeSelected End If End Sub Public Shared Function GetConstantID(ByVal node As TreeNode) As String Select Case GetNodeType(node) Case Type.Connection Return TryCast(node.Tag, mRemoteNG.Connection.Info).ConstantID Case Type.Container Return TryCast(node.Tag, mRemoteNG.Container.Info).ConnectionInfo.ConstantID End Select Return Nothing End Function Public Shared Function GetNodeFromPositionID(ByVal id As Integer) As TreeNode For Each conI As Connection.Info In cL If conI.PositionID = id Then If conI.IsContainer Then Return TryCast(conI.Parent, Container.Info).TreeNode Else Return conI.TreeNode End If End If Next Return Nothing End Function Public Shared Function GetNodeFromConstantID(ByVal id As String) As TreeNode For Each conI As Connection.Info In cL If conI.ConstantID = id Then If conI.IsContainer Then Return TryCast(conI.Parent, Container.Info).TreeNode Else Return conI.TreeNode End If End If Next Return Nothing End Function Public Shared Function GetNodeType(ByVal treeNode As TreeNode) As Tree.Node.Type Try If treeNode Is Nothing Then Return Type.NONE End If If treeNode.Tag Is Nothing Then Return Type.NONE End If If TypeOf treeNode.Tag Is Root.Info Then Return Type.Root ElseIf TypeOf treeNode.Tag Is Container.Info Then Return Type.Container ElseIf TypeOf treeNode.Tag Is Connection.Info Then Return Type.Connection End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't get node type" & vbNewLine & ex.Message, True) End Try Return Type.NONE End Function Public Shared Function GetNodeTypeFromString(ByVal str As String) As Tree.Node.Type Try Select Case LCase(str) Case "root" Return Type.Root Case "container" Return Type.Container Case "connection" Return Type.Connection End Select Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't get node type from string" & vbNewLine & ex.Message, True) End Try Return Type.NONE End Function Public Shared Function Find(ByVal treeNode As TreeNode, ByVal searchFor As String) As TreeNode Dim tmpNode As TreeNode Try If InStr(LCase(treeNode.Text), LCase(searchFor)) > 0 Then Return treeNode Else For Each childNode As TreeNode In treeNode.Nodes tmpNode = Find(childNode, searchFor) If Not tmpNode Is Nothing Then Return tmpNode End If Next End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Find node failed" & vbNewLine & ex.Message, True) End Try Return Nothing End Function Public Shared Function Find(ByVal treeNode As TreeNode, ByVal conInfo As Connection.Info) As TreeNode Dim tmpNode As TreeNode Try If treeNode.Tag Is conInfo Then Return treeNode Else For Each childNode As TreeNode In treeNode.Nodes tmpNode = Find(childNode, conInfo) If Not tmpNode Is Nothing Then Return tmpNode End If Next End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Find node failed" & vbNewLine & ex.Message, True) End Try Return Nothing End Function Public Shared Function IsEmpty(ByVal treeNode As TreeNode) As Boolean Try If treeNode.Nodes.Count <= 0 Then Return False End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "IsEmpty (Tree.Node) failed" & vbNewLine & ex.Message, True) End Try Return True End Function Public Shared Function AddNode(ByVal NodeType As Tree.Node.Type, Optional ByVal Text As String = "") As TreeNode Try Dim nNode As New TreeNode Select Case NodeType Case Type.Connection nNode.Text = My.Resources.strNewConnection nNode.ImageIndex = Images.Enums.TreeImage.ConnectionClosed nNode.SelectedImageIndex = Images.Enums.TreeImage.ConnectionClosed Case Type.Container nNode.Text = My.Resources.strNewFolder nNode.ImageIndex = Images.Enums.TreeImage.Container nNode.SelectedImageIndex = Images.Enums.TreeImage.Container Case Type.Root nNode.Text = My.Resources.strNewRoot nNode.ImageIndex = Images.Enums.TreeImage.Root nNode.SelectedImageIndex = Images.Enums.TreeImage.Root End Select If Text <> "" Then nNode.Text = Text End If Return nNode Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "AddNode failed" & vbNewLine & ex.Message, True) End Try Return Nothing End Function Public Shared Sub AddADNodes(ByVal ldapPath As String) Try Dim adCNode As TreeNode = Tree.Node.AddNode(Type.Container) Dim nContI As New mRemoteNG.Container.Info() nContI.TreeNode = adCNode nContI.ConnectionInfo = New mRemoteNG.Connection.Info(nContI) If Tree.Node.SelectedNode IsNot Nothing Then If Tree.Node.GetNodeType(Tree.Node.SelectedNode) = Tree.Node.Type.Container Then nContI.Parent = Tree.Node.SelectedNode.Tag End If End If Dim strDisplayName As String strDisplayName = ldapPath.Remove(0, ldapPath.IndexOf("OU=") + 3) strDisplayName = strDisplayName.Substring(0, strDisplayName.IndexOf(",")) nContI.Name = strDisplayName nContI.TreeNode.Text = strDisplayName adCNode.Tag = nContI ctL.Add(nContI) CreateADSubNodes(adCNode, ldapPath) SelectedNode.Nodes.Add(adCNode) SelectedNode = SelectedNode.Nodes(SelectedNode.Nodes.Count - 1) Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "AddADNodes failed" & vbNewLine & ex.Message, True) End Try End Sub Private Shared Sub CreateADSubNodes(ByVal rNode As TreeNode, ByVal ldapPath As String) Try Dim strDisplayName, strDescription, strHostName As String Dim ldapFilter As String = "(objectClass=computer)" '"sAMAccountName=*" Dim ldapSearcher As New DirectorySearcher Dim ldapResults As SearchResultCollection Dim ldapResult As SearchResult Dim ResultFields() As String = {"securityEquals", "cn"} With ldapSearcher .SearchRoot = New DirectoryEntry(ldapPath) .PropertiesToLoad.AddRange(ResultFields) .Filter = ldapFilter .SearchScope = SearchScope.OneLevel ldapResults = .FindAll End With For Each ldapResult In ldapResults With ldapResult.GetDirectoryEntry() strDisplayName = .Properties("cn").Value strDescription = .Properties("Description").Value strHostName = .Properties("dNSHostName").Value End With Dim adNode As TreeNode = Tree.Node.AddNode(Type.Connection, strDisplayName) Dim nConI As New mRemoteNG.Connection.Info() Dim nInh As New mRemoteNG.Connection.Info.Inheritance(nConI, True) nInh.Description = False If TypeOf rNode.Tag Is mRemoteNG.Container.Info Then nConI.Parent = rNode.Tag End If nConI.Inherit = nInh nConI.Name = strDisplayName nConI.Hostname = strHostName nConI.Description = strDescription nConI.TreeNode = adNode adNode.Tag = nConI 'set the nodes tag to the conI 'add connection to connections cL.Add(nConI) rNode.Nodes.Add(adNode) Next Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "CreateADSubNodes failed" & vbNewLine & ex.Message, True) End Try End Sub Public Shared Sub CloneNode(ByVal tNode As TreeNode, Optional ByVal ParentNode As TreeNode = Nothing) Try If GetNodeType(tNode) = Type.Connection Then Dim conI As Connection.Info = tNode.Tag Dim nConI As Connection.Info = conI.Copy Dim nInh As Connection.Info.Inheritance = conI.Inherit.Copy() nConI.Inherit = nInh cL.Add(nConI) Dim nNode As New TreeNode(nConI.Name) nNode.Tag = nConI nNode.ImageIndex = Images.Enums.TreeImage.ConnectionClosed nNode.SelectedImageIndex = Images.Enums.TreeImage.ConnectionClosed nConI.TreeNode = nNode If ParentNode Is Nothing Then tNode.Parent.Nodes.Add(nNode) Tree.Node.TreeView.SelectedNode = nNode Else ParentNode.Nodes.Add(nNode) End If ElseIf GetNodeType(tNode) = Type.Container Then Dim nCont As Container.Info = TryCast(tNode.Tag, Container.Info).Copy Dim nConI As Connection.Info = TryCast(tNode.Tag, Container.Info).ConnectionInfo.Copy nCont.ConnectionInfo = nConI Dim nNode As New TreeNode(nCont.Name) nNode.Tag = nCont nNode.ImageIndex = Images.Enums.TreeImage.Container nNode.SelectedImageIndex = Images.Enums.TreeImage.Container nCont.ConnectionInfo.Parent = nCont ctL.Add(nCont) tNode.Parent.Nodes.Add(nNode) Tree.Node.TreeView.SelectedNode = nNode For Each cNode As TreeNode In tNode.Nodes CloneNode(cNode, nNode) Next End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.WarningMsg, "CloneNode failed (Tree.Node)" & vbNewLine & ex.Message) End Try End Sub Public Shared Sub SetNodeImage(ByVal treeNode As TreeNode, ByVal Img As Images.Enums.TreeImage) SetNodeImageIndex(treeNode, Img) End Sub Private Delegate Sub SetNodeImageIndexCB(ByVal tNode As TreeNode, ByVal ImgIndex As Integer) Private Shared Sub SetNodeImageIndex(ByVal tNode As TreeNode, ByVal ImgIndex As Integer) If _TreeView.InvokeRequired Then Dim s As New SetNodeImageIndexCB(AddressOf SetNodeImageIndex) _TreeView.Invoke(s, New Object() {tNode, ImgIndex}) Else tNode.ImageIndex = ImgIndex tNode.SelectedImageIndex = ImgIndex End If End Sub Public Shared Sub SetNodeToolTip(ByVal e As MouseEventArgs, ByVal tTip As ToolTip) Try If My.Settings.ShowDescriptionTooltipsInTree Then 'Find the node under the mouse. Static old_node As TreeNode Dim new_node As TreeNode = _TreeView.GetNodeAt(e.X, e.Y) If new_node Is old_node Then Exit Sub old_node = new_node 'See if we have a node. If old_node Is Nothing Then tTip.SetToolTip(_TreeView, "") Else 'Get this node's object data. If GetNodeType(old_node) = Type.Connection Then tTip.SetToolTip(_TreeView, TryCast(old_node.Tag, mRemoteNG.Connection.Info).Description) End If End If End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "SetNodeToolTip failed" & vbNewLine & ex.Message, True) End Try End Sub Public Shared Sub DeleteSelectedNode() Try If SelectedNode Is Nothing Then Return Select Case Tree.Node.GetNodeType(SelectedNode) Case Type.Root mC.AddMessage(Messages.MessageClass.WarningMsg, "The root item cannot be deleted!") Case Type.Container If Tree.Node.IsEmpty(SelectedNode) = False Then If MsgBox(String.Format(My.Resources.strConfirmDeleteNodeFolder, SelectedNode.Text), MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then SelectedNode.Remove() End If Else If MsgBox(String.Format(My.Resources.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Text), MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then For Each tNode As TreeNode In SelectedNode.Nodes tNode.Remove() Next SelectedNode.Remove() End If End If Case Type.Connection If MsgBox(String.Format(My.Resources.strConfirmDeleteNodeConnection, SelectedNode.Text), MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then SelectedNode.Remove() End If Case Else mC.AddMessage(Messages.MessageClass.WarningMsg, "Tree item type is unknown so it cannot be deleted!") End Select Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Deleting selected node failed" & vbNewLine & ex.Message, True) End Try End Sub Public Shared Sub StartRenameSelectedNode() If SelectedNode IsNot Nothing Then Windows.treeForm.cMenTreeDelete.ShortcutKeys = Keys.None SelectedNode.BeginEdit() End If End Sub Public Shared Sub FinishRenameSelectedNode(ByVal NewName As String) Windows.treeForm.cMenTreeDelete.ShortcutKeys = Keys.Delete If NewName IsNot Nothing Then If NewName.Length > 0 Then SelectedNode.Tag.Name = NewName End If End If End Sub Public Shared Sub MoveNodeUp() Try If SelectedNode IsNot Nothing Then If Not (SelectedNode.PrevNode Is Nothing) Then Dim oldParent As TreeNode = SelectedNode.Parent Dim nNode As TreeNode = SelectedNode.Clone SelectedNode.Parent.Nodes.Insert(SelectedNode.Index - 1, nNode) SelectedNode.Remove() SelectedNode = nNode End If End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "MoveNodeUp failed" & vbNewLine & ex.Message, True) End Try End Sub Public Shared Sub MoveNodeDown() Try If SelectedNode IsNot Nothing Then If Not (SelectedNode.NextNode Is Nothing) Then Dim oldParent As TreeNode = SelectedNode.Parent Dim nNode As TreeNode = SelectedNode.Clone SelectedNode.Parent.Nodes.Insert(SelectedNode.Index + 2, nNode) SelectedNode.Remove() SelectedNode = nNode End If End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "MoveNodeDown failed" & vbNewLine & ex.Message, True) End Try End Sub Public Shared Sub ExpandAllNodes() _TreeView.ExpandAll() End Sub Public Shared Sub CollapseAllNodes() For Each tNode As TreeNode In _TreeView.Nodes(0).Nodes tNode.Collapse(False) Next End Sub Public Shared Sub Sort(ByVal treeNode As TreeNode, ByVal sortType As Tools.Controls.TreeNodeSorter.SortType) Try If Tree.Node.GetNodeType(treeNode) <> Type.Connection Then Dim ns As New Tools.Controls.TreeNodeSorter(treeNode, sortType) _TreeView.TreeViewNodeSorter = ns _TreeView.Sort() _TreeView.Sorted = False End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Sort nodes failed" & vbNewLine & ex.Message, True) End Try End Sub Private Delegate Sub ResetTreeCB() Public Shared Sub ResetTree() If _TreeView.InvokeRequired Then Dim d As New ResetTreeCB(AddressOf ResetTree) Windows.treeForm.Invoke(d) Else _TreeView.Nodes.Clear() '_TreeView.Nodes.Add("Credentials") _TreeView.Nodes.Add(My.Resources.strConnections) End If End Sub End Class End Namespace