Пример #1
0
        /// <summary>
        ///   Copies the tree rooted at the given node.
        /// </summary>
        /// <param name="p_tndSource">The root of the tree to copy.</param>
        /// <returns>The root of the copied tree.</returns>
        private FileSystemTreeNode CopyTree(FileSystemTreeNode p_tndSource)
        {
            var tndDest = new FileSystemTreeNode(p_tndSource);

            CopyTree(p_tndSource, tndDest);
            return(tndDest);
        }
Пример #2
0
        /// <summary>
        ///   The recursive method that searches the fomod file structure for files in the specified directory
        ///   matching the given pattern.
        /// </summary>
        /// <param name="p_tndRoot">The node from which to being searching.</param>
        /// <param name="p_queDirectories">The path to the directory in which to search.</param>
        /// <param name="p_rgxFileNamePattern">The pattern of the files to find.</param>
        /// <returns>
        ///   Returns pairs of values representing the found files. The key of the pair is the fomod file path,
        ///   and the value is the source path for the file.
        /// </returns>
        private List <KeyValuePair <string, string> > FindFomodFiles(FileSystemTreeNode p_tndRoot,
                                                                     Queue <string> p_queDirectories, Regex p_rgxFileNamePattern)
        {
            var lstMatches = new List <KeyValuePair <string, string> >();

            if (p_tndRoot.IsDirectory && ((p_queDirectories.Count > 0) && p_tndRoot.Name.Equals(p_queDirectories.Peek())))
            {
                p_queDirectories.Dequeue();
                PopulateNodeWithChildren(p_tndRoot);
                var intOriginalDepth = p_queDirectories.Count;
                foreach (FileSystemTreeNode tndNode in p_tndRoot.Nodes)
                {
                    lstMatches.AddRange(FindFomodFiles(tndNode, p_queDirectories, p_rgxFileNamePattern));
                    if (intOriginalDepth != p_queDirectories.Count)
                    {
                        break;
                    }
                }
            }
            else if ((p_queDirectories.Count == 0) && p_rgxFileNamePattern.IsMatch(p_tndRoot.Name))
            {
                lstMatches.Add(new KeyValuePair <string, string>(p_tndRoot.FullPath, p_tndRoot.LastSource));
            }
            return(lstMatches);
        }
Пример #3
0
 /// <summary>
 ///   Copies the tree rooted at the given source node to the tree rooted
 ///   at the given destination node.
 /// </summary>
 /// <param name="p_tndSource">The root of the tree to copy.</param>
 /// <param name="p_tndDest">The root of the tree to which to copy.</param>
 private void CopyTree(FileSystemTreeNode p_tndSource, FileSystemTreeNode p_tndDest)
 {
     foreach (FileSystemTreeNode tndSourceNode in p_tndSource.Nodes)
     {
         var tndCopy = new FileSystemTreeNode(tndSourceNode);
         p_tndDest.Nodes.Add(tndCopy);
         CopyTree(tndSourceNode, tndCopy);
     }
 }
Пример #4
0
 /// <summary>
 ///   Populates the given node with its children.
 /// </summary>
 /// <param name="p_tndNode">The node to populate with children.</param>
 protected void PopulateNodeWithChildren(FileSystemTreeNode p_tndNode)
 {
     if (!p_tndNode.IsDirectory)
     {
         return;
     }
     foreach (var srcSource in p_tndNode.Sources)
     {
         if (srcSource.IsLoaded)
         {
             continue;
         }
         var strSource = srcSource.Path;
         srcSource.IsLoaded = true;
         if (strSource.StartsWith(Archive.ARCHIVE_PREFIX))
         {
             var kvpPath    = Archive.ParseArchivePath(strSource);
             var arcArchive = new Archive(kvpPath.Key);
             var strFolders = arcArchive.GetDirectories(kvpPath.Value);
             foreach (var folder in strFolders)
             {
                 addFomodFile(p_tndNode, Archive.GenerateArchivePath(kvpPath.Key, folder));
             }
             var strFiles = arcArchive.GetFiles(kvpPath.Value);
             foreach (var file in strFiles)
             {
                 addFomodFile(p_tndNode, Archive.GenerateArchivePath(kvpPath.Key, file));
             }
         }
         else if (!strSource.StartsWith(FileSystemTreeNode.NEW_PREFIX))
         {
             var strFolders = Directory.GetDirectories(strSource);
             foreach (var folder in strFolders)
             {
                 addFomodFile(p_tndNode, folder);
             }
             var strFiles = Directory.GetFiles(strSource);
             foreach (var file in strFiles)
             {
                 addFomodFile(p_tndNode, file);
             }
         }
     }
 }
Пример #5
0
        /// <summary>
        ///   Finds the deepest nod in the fomod file system along the given path.
        /// </summary>
        /// <param name="p_strPath">The path for which to find the deepest node.</param>
        /// <returns>The deepest nod in the fomod file structure that is along the given path.</returns>
        protected FileSystemTreeNode findNode(string p_strPath)
        {
            if (String.IsNullOrEmpty(p_strPath))
            {
                return(null);
            }
            var strPath = p_strPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);

            strPath = strPath.Trim(new[]
            {
                Path.DirectorySeparatorChar
            });
            var strPathNodes = strPath.Split(Path.DirectorySeparatorChar);

            Array.Reverse(strPathNodes);
            var stkPath  = new Stack <string>(strPathNodes);
            var tncNodes = tvwFomod.Nodes;
            FileSystemTreeNode tndLastNode = null;
            var intPathCount = 0;

            while ((tncNodes.Count > 0) && (intPathCount != stkPath.Count))
            {
                intPathCount = stkPath.Count;
                foreach (FileSystemTreeNode tndNode in tncNodes)
                {
                    if (tndNode.Name.Equals(stkPath.Peek(), StringComparison.InvariantCultureIgnoreCase))
                    {
                        stkPath.Pop();
                        if (stkPath.Count == 0)
                        {
                            return(tndNode);
                        }
                        PopulateNodeWithChildren(tndNode);
                        tndLastNode = tndNode;
                        tncNodes    = tndNode.Nodes;
                        break;
                    }
                }
            }
            return(tndLastNode);
        }
Пример #6
0
        /// <summary>
        ///   This adds a file/folder to the source file structure.
        /// </summary>
        /// <param name="p_tndRoot">The node to which to add the file/folder.</param>
        /// <param name="p_strFile">The path to add to the source file structure.</param>
        private void addSourceFile(FileSystemTreeNode p_tndRoot, string p_strFile)
        {
            if (!p_strFile.StartsWith(Archive.ARCHIVE_PREFIX) && !p_strFile.StartsWith(FileSystemTreeNode.NEW_PREFIX))
            {
                FileSystemInfo fsiInfo;
                if (Directory.Exists(p_strFile))
                {
                    fsiInfo = new DirectoryInfo(p_strFile);
                }
                else if (File.Exists(p_strFile))
                {
                    fsiInfo = new FileInfo(p_strFile);
                }
                else
                {
                    return;
                }
                if ((fsiInfo.Attributes & FileAttributes.System) > 0)
                {
                    return;
                }
            }

            FileSystemTreeNode tndFile;
            var tncSiblings = (p_tndRoot == null) ? tvwSource.Nodes : p_tndRoot.Nodes;

            if (tncSiblings.ContainsKey(p_strFile))
            {
                tndFile = (FileSystemTreeNode)tncSiblings[p_strFile];
            }
            else
            {
                tndFile      = new FileSystemTreeNode(Path.GetFileName(p_strFile), p_strFile);
                tndFile.Name = p_strFile;
                tncSiblings.Add(tndFile);
            }
            if (tndFile.IsDirectory)
            {
                tndFile.ImageKey         = "folder";
                tndFile.SelectedImageKey = "folder";
                if ((p_tndRoot == null) || (p_tndRoot.IsExpanded))
                {
                    tndFile.Sources[p_strFile].IsLoaded = true;
                    if (p_strFile.StartsWith(Archive.ARCHIVE_PREFIX))
                    {
                        var kvpPath    = Archive.ParseArchivePath(p_strFile);
                        var arcArchive = new Archive(kvpPath.Key);
                        var strFolders = arcArchive.GetDirectories(kvpPath.Value);
                        foreach (var folder in strFolders)
                        {
                            addSourceFile(tndFile, Archive.GenerateArchivePath(kvpPath.Key, folder));
                        }
                        var strFiles = arcArchive.GetFiles(kvpPath.Value);
                        foreach (var file in strFiles)
                        {
                            addSourceFile(tndFile, Archive.GenerateArchivePath(kvpPath.Key, file));
                        }
                    }
                    else if (!p_strFile.StartsWith(FileSystemTreeNode.NEW_PREFIX))
                    {
                        var strFolders = Directory.GetDirectories(p_strFile);
                        foreach (var folder in strFolders)
                        {
                            addSourceFile(tndFile, folder);
                        }
                        var strFiles = Directory.GetFiles(p_strFile);
                        foreach (var file in strFiles)
                        {
                            addSourceFile(tndFile, file);
                        }
                    }
                }
            }
            else
            {
                tndFile.Sources[p_strFile].IsLoaded = true;
                var strExtension = Path.GetExtension(p_strFile).ToLowerInvariant();
                if (!imlIcons.Images.ContainsKey(strExtension))
                {
                    var strIconPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()) + strExtension;
                    File.CreateText(strIconPath).Close();
                    imlIcons.Images.Add(strExtension, Icon.ExtractAssociatedIcon(strIconPath));
                    File.Delete(strIconPath);
                }
                tndFile.ImageKey         = strExtension;
                tndFile.SelectedImageKey = strExtension;
                if (tndFile.IsArchive)
                {
                    var arcArchive = new Archive(p_strFile);
                    var strFolders = arcArchive.GetDirectories("/");
                    foreach (var folder in strFolders)
                    {
                        addSourceFile(tndFile, Archive.GenerateArchivePath(p_strFile, folder));
                    }
                    var strFiles = arcArchive.GetFiles("/");
                    foreach (var file in strFiles)
                    {
                        addSourceFile(tndFile, Archive.GenerateArchivePath(p_strFile, file));
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        ///   This adds a file/folder to the fomod file structure.
        /// </summary>
        /// <param name="p_tndRoot">The node to which to add the file/folder.</param>
        /// <param name="p_strFile">The path to add to the fomod file structure.</param>
        /// <returns>
        ///   The node that was added for the specified file/folder. <lang langref="null" />
        ///   is returned if the given path is invalid.
        /// </returns>
        private FileSystemTreeNode addFomodFile(TreeNode p_tndRoot, string p_strFile)
        {
            if (!p_strFile.StartsWith(Archive.ARCHIVE_PREFIX) && !p_strFile.StartsWith(FileSystemTreeNode.NEW_PREFIX))
            {
                FileSystemInfo fsiInfo;
                if (Directory.Exists(p_strFile))
                {
                    fsiInfo = new DirectoryInfo(p_strFile);
                }
                else if (File.Exists(p_strFile))
                {
                    fsiInfo = new FileInfo(p_strFile);
                }
                else
                {
                    return(null);
                }
                if ((fsiInfo.Attributes & FileAttributes.System) > 0)
                {
                    return(null);
                }
            }

            var strFileName = Path.GetFileName(p_strFile);
            FileSystemTreeNode tndFile;
            var tncSiblings = (p_tndRoot == null) ? tvwFomod.Nodes : p_tndRoot.Nodes;

            if (tncSiblings.ContainsKey(strFileName.ToLowerInvariant()))
            {
                tndFile = (FileSystemTreeNode)tncSiblings[strFileName.ToLowerInvariant()];
                tndFile.AddSource(p_strFile, false);
            }
            else
            {
                tndFile = new FileSystemTreeNode(strFileName, p_strFile);
                tndFile.ContextMenuStrip = cmsFomodNode;
                tndFile.Name             = strFileName.ToLowerInvariant();
                tncSiblings.Add(tndFile);
            }
            if (tndFile.IsDirectory)
            {
                tndFile.ImageKey         = "folder";
                tndFile.SelectedImageKey = "folder";
                if ((p_tndRoot == null) || (p_tndRoot.IsExpanded))
                {
                    PopulateNodeWithChildren(tndFile);
                }
            }
            else
            {
                tndFile.Sources[p_strFile].IsLoaded = true;
                var strExtension = Path.GetExtension(p_strFile).ToLowerInvariant();
                if (!imlIcons.Images.ContainsKey(strExtension))
                {
                    var strIconPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()) + strExtension;
                    File.CreateText(strIconPath).Close();
                    imlIcons.Images.Add(strExtension, Icon.ExtractAssociatedIcon(strIconPath));
                    File.Delete(strIconPath);
                }
                tndFile.ImageKey         = strExtension;
                tndFile.SelectedImageKey = strExtension;
            }
            return(tndFile);
        }
Пример #8
0
        /// <summary>
        ///   Processes the tree rooted at the given node to romve any superfluous nodes and sources.
        /// </summary>
        /// <remarks>
        ///   This method cleans up the given tree so that the most efficient set of mappings
        ///   needed to create the fomod file structure can be generated.
        /// </remarks>
        /// <param name="p_tndNode">The node at which the fomod file structure tree is rooted.</param>
        private void ProcessTree(FileSystemTreeNode p_tndNode)
        {
            if (p_tndNode.Nodes.Count == 0)
            {
                for (var j = p_tndNode.Sources.Count - 1; j >= 0; j--)
                {
                    if (p_tndNode.Sources[j].Path.StartsWith(FileSystemTreeNode.NEW_PREFIX))
                    {
                        p_tndNode.Sources.RemoveAt(j);
                    }
                }
                return;
            }
            foreach (FileSystemTreeNode tndNode in p_tndNode.Nodes)
            {
                ProcessTree(tndNode);
            }
            var lstSubPaths = new List <string>();

            for (var j = p_tndNode.Sources.Count - 1; j >= 0; j--)
            {
                var srcSource = p_tndNode.Sources[j];
                lstSubPaths.Clear();
                if (srcSource.Path.StartsWith(Archive.ARCHIVE_PREFIX))
                {
                    var kvpPath    = Archive.ParseArchivePath(srcSource.Path);
                    var arcArchive = new Archive(kvpPath.Key);
                    foreach (var strPath in arcArchive.GetDirectories(kvpPath.Value))
                    {
                        lstSubPaths.Add(Archive.GenerateArchivePath(kvpPath.Key, strPath));
                    }
                    foreach (var strPath in arcArchive.GetFiles(kvpPath.Value))
                    {
                        lstSubPaths.Add(Archive.GenerateArchivePath(kvpPath.Key, strPath));
                    }
                }
                else if (srcSource.Path.StartsWith(FileSystemTreeNode.NEW_PREFIX))
                {
                    p_tndNode.Sources.RemoveAt(j);
                    continue;
                }
                else
                {
                    lstSubPaths.AddRange(Directory.GetDirectories(srcSource.Path));
                    foreach (var strPath in Directory.GetFiles(srcSource.Path))
                    {
                        if ((new FileInfo(strPath).Attributes & FileAttributes.System) > 0)
                        {
                            continue;
                        }
                        lstSubPaths.AddRange(Directory.GetFiles(srcSource.Path));
                    }
                }
                //if the source hasn't been loaded, then we treat it as if all
                // subpaths are present and have already been removed from
                // the children nodes, so we don't have to do anything
                if (srcSource.IsLoaded)
                {
                    //if we find all the current folder's subpaths, and each subpath
                    // has no children in the same source tree, then we can just copy
                    // the current folder instead of copying each child individually
                    var intFoundCount = 0;

                    //so, for each subpath of the current folder...
                    foreach (var strSubPath in lstSubPaths)
                    {
                        //...look through all the children nodes for the subpath...
                        foreach (FileSystemTreeNode tndChild in p_tndNode.Nodes)
                        {
                            //...if we find the subpath...
                            if (tndChild.Sources.Contains(strSubPath))
                            {
                                //...and the node containing the subpath has no children
                                // containing anything in the same source tree...
                                var booFound = false;
                                foreach (FileSystemTreeNode tndSubNode in tndChild.Nodes)
                                {
                                    foreach (string strSubSource in tndSubNode.Sources)
                                    {
                                        if (strSubSource.StartsWith(strSubPath))
                                        {
                                            booFound = true;
                                            break;
                                        }
                                    }
                                    if (booFound)
                                    {
                                        break;
                                    }
                                }
                                //...then we found the subpath.
                                // if the node containing the subpath had had children containing
                                // something in the same source tree, that would imply we aren't
                                // copying all the current folder's descendants, so we would have to
                                // copy each descendent individually, instead of just copying this folder
                                if (!booFound)
                                {
                                    intFoundCount++;
                                }
                                break;
                            }
                        }
                    }
                    //if we found all the subpaths...
                    if (intFoundCount == lstSubPaths.Count)
                    {
                        //...then remove the subpaths, so we just copy the
                        // current folder instead of copying each child individually
                        foreach (var strSubPath in lstSubPaths)
                        {
                            for (var i = p_tndNode.Nodes.Count - 1; i >= 0; i--)
                            {
                                var tndNode = (FileSystemTreeNode)p_tndNode.Nodes[i];
                                if (tndNode.Sources.Contains(strSubPath))
                                {
                                    //if we are removing the last source, and there are no
                                    // children nodes (implying this node isn't needed in
                                    // another source tree), then prune this node away...
                                    if ((tndNode.Nodes.Count == 0) && (tndNode.Sources.Count <= 1))
                                    {
                                        p_tndNode.Nodes.RemoveAt(i);
                                    }
                                    else //...otherwise just remove the source
                                    {
                                        tndNode.Sources.Remove(strSubPath);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        //...else if we only found some of the subpaths
                        // then remove the current folder from the sources so
                        // it doesn't get copied: the current folder will be
                        // created when the subpaths are copied...
                        //...else if we found no subpaths then we remove the current folder
                        // to prune empty folders
                        p_tndNode.Sources.RemoveAt(j);
                    }
                }
            }
        }