/// <summary> /// </summary> /// <param name="VirtualPath"></param> private TreeNodeAdv GetViewNodeByPath(string VirtualPath) { foreach (TreeNodeAdv Node in MainTreeView.AllNodes) { DownloadFileSystemTreeNode Meta = Node.Tag as DownloadFileSystemTreeNode; if (Meta != null && Meta.FullPath == VirtualPath) { return(Node); } } return(null); }
/// <summary> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnNodeExpanded(object sender, Aga.Controls.Tree.TreeViewAdvEventArgs e) { // Retrieve all sub nodes. foreach (TreeNodeAdv SNode in e.Node.Children) { DownloadFileSystemTreeNode Metadata = SNode.Tag as DownloadFileSystemTreeNode; if (Metadata == null || !Metadata.IsBuild) { BuildFileSystem.GetChildrenNames(Metadata.FullPath); } } // TODO: Force sub-refresh of childrens childrens after a given amount of time? }
/// <summary> /// /// </summary> private void SetupFileSystem() { RequestedBuildPaths.Clear(); Model.Nodes.Clear(); BuildFileSystem = new VirtualFileSystem(); BuildFileSystem.ChildrenRefreshInterval = 5 * 1000; BuildFileSystem.AutoRefreshChildren = false; BuildFileSystem.OnRequestChildren += (FileSystem, Path) => { if (Program.NetClient != null) { RequestedBuildPaths.Add(Path); Program.NetClient.RequestBuilds(Path); } }; BuildFileSystem.OnNodeUpdated += (FileSystem, Node) => { Node ModelNode = GetNodeByPath(Node.Path); if (ModelNode != null) { UpdateNode(ModelNode as DownloadFileSystemTreeNode, Node); } MainTreeView.Refresh(); }; BuildFileSystem.OnNodeAdded += (FileSystem, Node) => { // Ignore internal parts of the heirarchy. if (Node.Path.Contains("$") && !ShowInternal) { return; } Collection <Node> NodeCollection = Model.Root.Nodes; if (Node.Parent != null && Node.Parent.Name != "") { NodeCollection = GetNodeByPath(Node.Parent.Path).Nodes; } DownloadFileSystemTreeNode TrNode = new DownloadFileSystemTreeNode(); TrNode.IsBuildContainer = false; DateTime SortTime = DateTime.UtcNow; if (Node.Metadata != null) { NetMessage_GetBuildsResponse.BuildInfo BuildInfo = (NetMessage_GetBuildsResponse.BuildInfo)Node.Metadata; SortTime = Node.CreateTime; } // Insert based on create time. bool Inserted = false; for (int i = 0; i < NodeCollection.Count; i++) { DownloadFileSystemTreeNode SubNode = NodeCollection[i] as DownloadFileSystemTreeNode; if (SubNode != null && (SubNode.CreateTime.Ticks - SortTime.Ticks) < -10000000) // At least a second off. { NodeCollection.Insert(i, TrNode); Inserted = true; break; } } if (!Inserted) { NodeCollection.Add(TrNode); } UpdateNode(TrNode, Node); // If parent node is expanded, then request all children of this node. TreeNodeAdv ParentViewNode = null; if (TrNode.Parent != null) { DownloadFileSystemTreeNode ParentNode = TrNode.Parent as DownloadFileSystemTreeNode; if (ParentNode != null) { ParentViewNode = GetViewNodeByPath(ParentNode.FullPath); } else { ParentViewNode = MainTreeView.Root; } } if (ParentViewNode == null || ParentViewNode.IsExpanded) { if (!TrNode.IsBuild) { BuildFileSystem.GetChildrenNames(Node.Path); } } MainTreeView.FullUpdate(); SelectNextPath(); OnDateUpdated?.Invoke(this, null); }; BuildFileSystem.OnNodeRemoved += (FileSystem, Node) => { // Ignore internal parts of the heirarchy. if (Node.Path.Contains("$") && !ShowInternal) { return; } Node ModelNode = GetNodeByPath(Node.Path); if (ModelNode != null && ModelNode.Parent != null) { ModelNode.Parent.Nodes.Remove(ModelNode); } }; BuildFileSystem.Init(); }
/// <summary> /// /// </summary> /// <param name="TrNode"></param> /// <param name="Node"></param> private void UpdateNode(DownloadFileSystemTreeNode TrNode, VirtualFileSystemNode Node) { TrNode.FullPath = Node.Path; TrNode.Name = Node.Name; TrNode.Icon = Resources.appbar_box; TrNode.AvailabilityIcon = null; if (Node.Metadata != null) { NetMessage_GetBuildsResponse.BuildInfo BuildInfo = (NetMessage_GetBuildsResponse.BuildInfo)Node.Metadata; TrNode.IsBuild = BuildInfo.Guid != Guid.Empty; TrNode.ManifestId = BuildInfo.Guid; TrNode.CreateTime = Node.CreateTime; TrNode.SizeFormatted = StringUtils.FormatAsSize((long)BuildInfo.TotalSize); TrNode.CreateTimeFormatted = BuildInfo.CreateTime.ToString("dd/MM/yyyy HH:mm"); // 9 = very high // 7,8 = high // 4,5,6, = medium // 2,3 = low // 1 = very low // 0 = not TrNode.Availability = BuildInfo.AvailablePeers + " peers have entire build"; if (BuildInfo.AvailablePeers >= 9) { TrNode.AvailabilityIcon = Resources.appbar_connection_quality_veryhigh; } else if (BuildInfo.AvailablePeers >= 7) { TrNode.AvailabilityIcon = Resources.appbar_connection_quality_high; } else if (BuildInfo.AvailablePeers >= 3) { TrNode.AvailabilityIcon = Resources.appbar_connection_quality_medium; } else if (BuildInfo.AvailablePeers >= 2) { TrNode.AvailabilityIcon = Resources.appbar_connection_quality_low; } else if (BuildInfo.AvailablePeers >= 1) { TrNode.AvailabilityIcon = Resources.appbar_connection_quality_verylow; } else { TrNode.AvailabilityIcon = Resources.appbar_close; TrNode.Availability = "Last available " + BuildInfo.LastSeenOnPeer.ToString("dd/MM/yyyy HH:mm"); } if (BuildInfo.Tags != null) { TrNode.Tags = BuildInfo.Tags; TrNode.TagsFormatted = ""; foreach (Tag Tag in BuildInfo.Tags) { if (TrNode.TagsFormatted.Length > 0) { TrNode.TagsFormatted += ", "; } TrNode.TagsFormatted += Tag.Name; } } else { TrNode.TagsFormatted = ""; } } else { TrNode.IsBuild = false; TrNode.ManifestId = Guid.Empty; TrNode.CreateTime = DateTime.UtcNow; } if (!TrNode.IsBuild) { TrNode.SizeFormatted = ""; TrNode.Availability = ""; TrNode.CreateTimeFormatted = ""; TrNode.AvailabilityIcon = null; TrNode.TagsFormatted = ""; } if (TrNode.IsBuild) { TrNode.Icon = Resources.appbar_box; } else if (TrNode.IsBuildContainer) { TrNode.Icon = Resources.appbar_database; } else { TrNode.Icon = Resources.appbar_folder_open; } // If its a build, the folder parent becomes a "container". if (TrNode.IsBuild && TrNode.Parent != null) { DownloadFileSystemTreeNode ParentNode = TrNode.Parent as DownloadFileSystemTreeNode; if (ParentNode != null) { ParentNode.IsBuildContainer = true; ParentNode.Icon = Resources.appbar_database; } } }