Exemple #1
0
        private void CalculateFileSizes(List <DirectoryData> subDataList)
        {
            try
            {
                int  fileCount = 0;
                long fileSize  = 0;
                Parallel.ForEach(
                    this.directoryInfo.EnumerateFiles(),
                    info =>
                {
                    Interlocked.Add(ref fileSize, info.Length);
                    Interlocked.Increment(ref fileCount);
                });

                this.AdjustStats(fileSize, fileCount, 0, false);

                // Only add a [Files] node if we found some files (even 0 byte files).
                if (fileCount > 0)
                {
                    // Add a faux node for files
                    const string  FilesNodeName = "[Files]";
                    DirectoryData data          = new DirectoryData(FilesNodeName, Path.Combine(this.directoryInfo.FullName, FilesNodeName), fileSize, fileCount);
                    subDataList.Add(data);
                }
            }
            catch (Exception ex)
            {
                AddErrorData(subDataList, "File Error: ", ex.Message);
            }
        }
Exemple #2
0
 private static void SetDirectoryNodeImage(TreeNode node)
 {
     if (IsNodeADirectory(node))
     {
         DirectoryData data       = GetDataForNode(node);
         int           imageIndex = GetImageForData(data);
         node.ImageIndex         = imageIndex;
         node.SelectedImageIndex = node.ImageIndex;
     }
 }
Exemple #3
0
 private void UpdateStatusBar(TreeNode selectedNode)
 {
     if (selectedNode != null)
     {
         DirectoryData selectedData = GetDataForNode(selectedNode);
         this.UpdateStatusBar(selectedData);
     }
     else
     {
         this.UpdateStatusBar(string.Empty);
     }
 }
Exemple #4
0
        private static bool IsNodeADirectory(TreeNode node)
        {
            bool result = false;

            if (node != null)
            {
                DirectoryData data = GetDataForNode(node);
                result = data.DataType == DirectoryDataType.Directory;
            }

            return(result);
        }
Exemple #5
0
        private void CalculateDirectorySize(List <DirectoryData> subDataList, BackgroundWorker worker, DirectoryInfo info)
        {
            // Never report progress for sub-directories.  It adds too much blocking, which makes things take forever.
            // Add 1 to the folder count to account for the current directory.
            DirectoryData data = new DirectoryData(info, worker, false);

            this.AdjustStats(data.Size, data.FileCount, 1 + data.FolderCount, false);
            lock (subDataList)
            {
                subDataList.Add(data);
            }
        }
Exemple #6
0
        private void OpenFolder_Click(object sender, System.EventArgs e)
        {
            TreeNode selectedNode = this.Tree.SelectedNode;

            if (selectedNode != null)
            {
                DirectoryData selectedData = GetDataForNode(selectedNode);
                if (selectedData.DataType == DirectoryDataType.Directory)
                {
                    selectedData.Explore(this);
                }
            }
        }
Exemple #7
0
        private void Map_NodeDoubleClick(object sender, NodeEventArgs e)
        {
            // Because the tree auto-populates as its nodes are expanded,
            // we have to drill down one level at a time by parsing the path.
            // We can't assume that a given Treemap.Node will already have
            // an associated TreeViewNode.
            Node node = e.Node;

            if (node != null && this.Tree.Nodes.Count > 0)
            {
                TreeNode      rootTreeNode = this.Tree.Nodes[0];
                DirectoryData rootData     = GetDataForNode(rootTreeNode);

                DirectoryData data = GetDataForNode(node);
                if (data != null && rootData != null)
                {
                    string fullName     = data.FullName;
                    string rootFullName = rootData.FullName;
                    if (!string.IsNullOrEmpty(fullName) && !string.IsNullOrEmpty(rootFullName) &&
                        fullName.StartsWith(rootFullName, StringComparison.CurrentCultureIgnoreCase))
                    {
                        // Remove the root path first.
                        fullName = fullName.Remove(0, rootFullName.Length);

                        // Now get the remaining path parts, so we can find their tree nodes.
                        string[] parts = fullName.Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);

                        TreeNode currentNode = rootTreeNode;
                        foreach (var partName in parts)
                        {
                            currentNode.Expand();
                            int childIndex = currentNode.Nodes.IndexOfKey(partName);
                            if (childIndex >= 0)
                            {
                                currentNode = currentNode.Nodes[childIndex];
                            }
                            else
                            {
                                currentNode = null;
                                break;
                            }
                        }

                        if (currentNode != null)
                        {
                            this.Tree.SelectedNode = currentNode;
                        }
                    }
                }
            }
        }
Exemple #8
0
#pragma warning disable CC0091 // Use static method. Designer likes instance event handlers.
        private void MainWorker_DoWork(object sender, DoWorkEventArgs e)
#pragma warning restore CC0091 // Use static method
        {
            string directoryName = (string)e.Argument;

            DirectoryInfo dirInfo = new DirectoryInfo(directoryName);

            // This does all the directory walking and sizing.
            BackgroundWorker bw   = (BackgroundWorker)sender;
            DirectoryData    data = new DirectoryData(dirInfo, bw);

            e.Result = data;
            e.Cancel = bw.CancellationPending;
        }
Exemple #9
0
#pragma warning disable CC0091 // Use static method. Designer likes instance event handlers.
        private void RefreshWorker_DoWork(object sender, DoWorkEventArgs e)
#pragma warning restore CC0091 // Use static method
        {
            e.Result = e.Argument;

            var           selection    = (Tuple <TreeNode, DirectoryData, DirectoryData>)e.Argument;
            DirectoryData selectedData = selection.Item2;

            BackgroundWorker bw = (BackgroundWorker)sender;

            selectedData.Refresh(bw);

            e.Cancel = bw.CancellationPending;
        }
Exemple #10
0
        private static void AddDirectoryNode(TreeNodeCollection parentNodes, DirectoryData data)
        {
            TreeNode node = new TreeNode();

            node.Tag                = data;
            node.ImageIndex         = GetImageForData(data);
            node.SelectedImageIndex = node.ImageIndex;
            node.Name               = data.Name; // Map_NodeDoubleClick needs this so Nodes.IndexOfKey will work.
            SetNodeText(node, data);

            parentNodes.Add(node);

            if (data.SubData.Count > 0)
            {
                node.Nodes.Add(new DummyNode());
            }
        }
Exemple #11
0
 private void UpdateMap(TreeNode treeNode)
 {
     using (new WaitCursor(this))
     {
         DirectoryData data = GetDataForNode(treeNode);
         this.Map.BeginUpdate();
         try
         {
             this.Map.Clear();
             this.Map.Nodes.Add(data.TreeMapNode);
         }
         finally
         {
             this.Map.EndUpdate();
         }
     }
 }
Exemple #12
0
        private void RefreshBranch_Click(object sender, System.EventArgs e)
        {
            TreeNode selectedNode = this.Tree.SelectedNode;

            if (selectedNode != null)
            {
                // Force it to collapse first since we're populating the tree on-demand.
                selectedNode.Collapse();

                // Do the refresh asynchronously.  Make a copy of the data now, so we can
                // adjust the stats all the way up the tree later.
                DirectoryData selectedData      = GetDataForNode(selectedNode);
                DirectoryData selectedDataClone = selectedData.Clone();
                this.Progress.Value = 0;
                this.RefreshWorker.RunWorkerAsync(Tuple.Create(selectedNode, selectedData, selectedDataClone));
            }
        }
Exemple #13
0
        private void MainWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            using (new WaitCursor(this))
            {
                this.Tree.BeginUpdate();
                this.Map.BeginUpdate();
                try
                {
                    DirectoryData data;
                    if (e.Error != null)
                    {
                        data = new DirectoryData(e.Error.Message);
                    }
                    else if (e.Cancelled)
                    {
                        data = new DirectoryData("Cancelled");
                    }
                    else
                    {
                        data = (DirectoryData)e.Result;
                    }

                    // This populates the root of the tree.
                    AddDirectoryNode(this.Tree.Nodes, data);

                    // Select the first tree node so the map will update.
                    if (this.Tree.SelectedNode == null)
                    {
                        this.Tree.SelectedNode = this.Tree.Nodes[0];

                        // Expand it since that's almost always desired too.
                        this.Tree.SelectedNode.Expand();
                    }

                    // Show the total time it took.
                    this.stopwatch.Stop();
                    this.UpdateStatusBar(this.stopwatch.Elapsed);
                }
                finally
                {
                    this.Tree.EndUpdate();
                    this.Map.EndUpdate();
                }
            }
        }
Exemple #14
0
#pragma warning disable CC0091 // Use static method. Designer likes instance event handlers.
        private void Tree_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
#pragma warning restore CC0091 // Use static method
        {
            TreeNode node = e.Node;

            SetDirectoryNodeImage(node);

            if (node.FirstNode is DummyNode)
            {
                node.Nodes.Clear();

                DirectoryData data = GetDataForNode(node);
                foreach (DirectoryData childData in data.SubData)
                {
                    AddDirectoryNode(node.Nodes, childData);
                }
            }
        }
Exemple #15
0
        private static int GetImageForData(DirectoryData data)
        {
            int result;

            switch (data.DataType)
            {
            case DirectoryDataType.Directory:
                result = FolderImageIndex;
                break;

            case DirectoryDataType.Files:
                result = FilesImageIndex;
                break;

            default:
                result = ErrorImageIndex;                         // Error or Unknown
                break;
            }

            return(result);
        }
Exemple #16
0
        private void UpdateStatusBar(DirectoryData selectedData)
        {
            string message = string.Empty;

            if (selectedData != null)
            {
                switch (selectedData.DataType)
                {
                case DirectoryDataType.Directory:
                case DirectoryDataType.Files:
                    DirectoryData rootData   = GetDataForNode(this.Tree.Nodes[0]);
                    double        percentage = rootData.Size != 0 ? selectedData.Size / (double)rootData.Size : 0;
                    message = string.Format(
                        "{0:F2}% of total space usage.  {1}.  {2}.  {3}.",
                        100 * percentage,
                        FormatLongUnits(selectedData.Size, "byte"),
                        FormatLongUnits(selectedData.FileCount, "file"),
                        FormatLongUnits(selectedData.FolderCount, "folder"));
                    break;
                }
            }

            this.UpdateStatusBar(message);
        }
Exemple #17
0
        public DirectoryData Clone()
        {
            DirectoryData result = (DirectoryData)this.MemberwiseClone();

            return(result);
        }
Exemple #18
0
        private void UpdateFolderView(TreeNode treeNode)
        {
            using (new WaitCursor(this))
            {
                DirectoryData data      = GetDataForNode(treeNode);
                string        directory = null;
                bool          clearView = false;
                switch (data.DataType)
                {
                case DirectoryDataType.Directory:
                    directory = data.FullName;
                    break;

                case DirectoryDataType.Files:
                    // Show the directory where the files are located.
                    directory = Path.GetDirectoryName(data.FullName);
                    break;

                case DirectoryDataType.Error:
                    clearView = true;
                    break;
                }

                if (!string.IsNullOrEmpty(directory))
                {
                    // Make sure the directory is accessible for navigation.  Otherwise, the
                    // WebBrowser control pops up a modal error dialog.
                    if (Directory.Exists(directory))
                    {
                        try
                        {
                            // See if we can read anything in the directory (by looking for a GUID filename that should never exist).
                            // This throws an exception if we can't read from the folder.
                            Directory.GetFiles(directory, "4322F6AF-27BA-419C-AB4D-5FF8862B338C", SearchOption.TopDirectoryOnly);

                            // When arrowing down quickly between tree nodes, the browser may not finish navigating to one folder
                            // before the next navigation request comes in (since it navigates asynchronously from the UI thread).
                            // To prevent a COMException from being thrown, we'll request that any pending navigation stop first.
                            this.Browser.Stop();
                            this.Browser.Navigate(new Uri(directory, UriKind.Absolute), false);
                        }
                        catch (COMException)
                        {
                            clearView = true;
                        }
                        catch (UnauthorizedAccessException)
                        {
                            clearView = true;
                        }
                    }
                    else
                    {
                        clearView = true;
                    }
                }

                if (clearView)
                {
                    this.ClearFolderView();
                }
            }
        }
Exemple #19
0
        private void RefreshWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            using (new WaitCursor(this))
            {
                this.Tree.BeginUpdate();
                this.Map.BeginUpdate();
                try
                {
                    if (e.Error != null || e.Cancelled)
                    {
                        TreeNode           selectedNode = this.Tree.SelectedNode;
                        TreeNodeCollection nodes;
                        if (selectedNode != null)
                        {
                            nodes = selectedNode.Nodes;
                        }
                        else
                        {
                            nodes = this.Tree.Nodes;
                        }

                        nodes.Clear();
                        string        message = e.Error != null ? e.Error.Message : "Cancelled";
                        DirectoryData data    = new DirectoryData(message);
                        AddDirectoryNode(nodes, data);
                        this.UpdateStatusBar(message);
                    }
                    else
                    {
                        var           selection    = (Tuple <TreeNode, DirectoryData, DirectoryData>)e.Result;
                        TreeNode      selectedNode = selection.Item1;
                        DirectoryData selectedData = selection.Item2;
                        DirectoryData oldData      = selection.Item3;

                        SetNodeText(selectedNode, selectedData);

                        // The nodes will have to be rebuilt below it.
                        selectedNode.Nodes.Clear();
                        if (selectedData.SubData.Count > 0)
                        {
                            selectedNode.Nodes.Add(new DummyNode());
                        }

                        // Recalculate the stats for everything above it.
                        TreeNode parentNode            = selectedNode.Parent;
                        long     sizeAdjustment        = selectedData.Size - oldData.Size;
                        long     fileCountAdjustment   = selectedData.FileCount - oldData.FileCount;
                        long     folderCountAdjustment = selectedData.FolderCount - oldData.FolderCount;
                        while (parentNode != null)
                        {
                            DirectoryData parentData = GetDataForNode(parentNode);
                            parentData.AdjustStats(sizeAdjustment, fileCountAdjustment, folderCountAdjustment);
                            SetNodeText(parentNode, parentData);
                            parentNode = parentNode.Parent;
                        }

                        // Refresh the treemap
                        this.UpdateMap(selectedNode);

                        // Refresh the status bar
                        this.UpdateStatusBar(selectedNode);

                        // Expand it if it's the root node since that's almost always desired too.
                        if (selectedNode == this.Tree.Nodes[0])
                        {
                            selectedNode.Expand();
                        }
                    }
                }
                finally
                {
                    this.Tree.EndUpdate();
                    this.Map.EndUpdate();
                }
            }
        }
Exemple #20
0
 private static void SetNodeText(TreeNode node, DirectoryData data)
 {
     node.Text = string.Format("{0}: {1:N1} MB", data.Name, data.SizeInMegabytes);
 }