diff --git a/Source/Builder.csproj b/Source/Builder.csproj index 4ab63184..1d18f912 100644 --- a/Source/Builder.csproj +++ b/Source/Builder.csproj @@ -679,6 +679,8 @@ + + diff --git a/Source/Config/ThingCategory.cs b/Source/Config/ThingCategory.cs index e80cf043..c9849e47 100644 --- a/Source/Config/ThingCategory.cs +++ b/Source/Config/ThingCategory.cs @@ -179,6 +179,12 @@ namespace CodeImp.DoomBuilder.Config #region ================== Methods + // This sorts the category, if preferred + internal void SortIfNeeded() + { + if(sorted) things.Sort(); + } + // This adds a thing to the category internal void AddThing(ThingTypeInfo t) { diff --git a/Source/Config/ThingTypeInfo.cs b/Source/Config/ThingTypeInfo.cs index 64d485cf..bbb68e5a 100644 --- a/Source/Config/ThingTypeInfo.cs +++ b/Source/Config/ThingTypeInfo.cs @@ -32,7 +32,7 @@ using CodeImp.DoomBuilder.Decorate; namespace CodeImp.DoomBuilder.Config { - public class ThingTypeInfo + public class ThingTypeInfo : IComparable { #region ================== Constants @@ -229,6 +229,12 @@ namespace CodeImp.DoomBuilder.Config hangs = actor.GetFlagValue("spawnceiling", false); blocking = actor.GetFlagValue("solid", false) ? 2 : 0; } + + // This is used for sorting + public int CompareTo(ThingTypeInfo other) + { + return string.Compare(this.title, other.title, true); + } #endregion } diff --git a/Source/Data/DataManager.cs b/Source/Data/DataManager.cs index 95755f0e..fae0b58b 100644 --- a/Source/Data/DataManager.cs +++ b/Source/Data/DataManager.cs @@ -235,7 +235,7 @@ namespace CodeImp.DoomBuilder.Data // Make DataLocation.type of type Type and assign the // types of the desired reader classes. - try + //try { // Choose container type switch(dl.type) @@ -256,6 +256,7 @@ namespace CodeImp.DoomBuilder.Data break; } } + /* catch(Exception e) { // Unable to load resource @@ -264,6 +265,7 @@ namespace CodeImp.DoomBuilder.Data General.ShowErrorMessage("Unable to load resources from location \"" + dl.location + "\". Please make sure the location is accessible and not in use by another program.", MessageBoxButtons.OK); continue; } + */ // Add container if(c != null) containers.Add(c); @@ -281,6 +283,9 @@ namespace CodeImp.DoomBuilder.Data texturenames.Sort(); flatnames.Sort(); + // Sort things + foreach(ThingCategory tc in thingcategories) tc.SortIfNeeded(); + // Update the used textures General.Map.Data.UpdateUsedTextures(); @@ -666,7 +671,10 @@ namespace CodeImp.DoomBuilder.Data internal Stream GetPatchData(string pname) { Stream patch; - + if(pname.ToUpperInvariant() == "WALL57_1") + { + int t = 5; + } // Go for all opened containers for(int i = containers.Count - 1; i >= 0; i--) { diff --git a/Source/Data/DirectoryReader.cs b/Source/Data/DirectoryReader.cs index 3a0ff025..534b63bd 100644 --- a/Source/Data/DirectoryReader.cs +++ b/Source/Data/DirectoryReader.cs @@ -24,6 +24,7 @@ using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Windows.Forms; using CodeImp.DoomBuilder.IO; #endregion @@ -32,15 +33,22 @@ namespace CodeImp.DoomBuilder.Data { internal sealed class DirectoryReader : PK3StructuredReader { - #region ================== Constructor / Disposer + #region ================== Variables + + private DirectoryFilesList files; + + #endregion + #region ================== Constructor / Disposer + // Constructor public DirectoryReader(DataLocation dl) : base(dl) { General.WriteLogLine("Opening directory resource '" + location.location + "'"); // Initialize - Initialize(dl.location); + files = new DirectoryFilesList(dl.location, true); + Initialize(); // We have no destructor GC.SuppressFinalize(this); @@ -66,74 +74,53 @@ namespace CodeImp.DoomBuilder.Data // This creates an image protected override ImageData CreateImage(string name, string filename, bool flat) { - return new FileImage(name, filename, flat); + return new FileImage(name, Path.Combine(location.location, filename), flat); } // This returns true if the specified file exists protected override bool FileExists(string filename) { - return File.Exists(filename); + return files.FileExists(filename); } // This returns all files in a given directory protected override string[] GetAllFiles(string path, bool subfolders) { - if(Directory.Exists(path)) - { - if(subfolders) - return Directory.GetFiles(path, "*", SearchOption.AllDirectories); - else - return Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly); - } - else - return new string[0]; + return files.GetAllFiles(path, subfolders).ToArray(); } // This returns all files in a given directory that match the given extension protected override string[] GetFilesWithExt(string path, string extension, bool subfolders) { - if(Directory.Exists(path)) - { - if(subfolders) - return Directory.GetFiles(path, "*." + extension, SearchOption.AllDirectories); - else - return Directory.GetFiles(path, "*." + extension, SearchOption.TopDirectoryOnly); - } - else - return new string[0]; + return files.GetAllFiles(path, extension, subfolders).ToArray(); + } + + // This finds the first file that has the specific name, regardless of file extension + protected override string FindFirstFile(string beginswith, bool subfolders) + { + return files.GetFirstFile(beginswith, subfolders); } // This finds the first file that has the specific name, regardless of file extension protected override string FindFirstFile(string path, string beginswith, bool subfolders) { - string[] files = GetAllFiles(path, subfolders); - foreach(string f in files) - { - if(string.Compare(Path.GetFileNameWithoutExtension(f), beginswith, true) == 0) - return f; - } - - return null; + return files.GetFirstFile(path, beginswith, subfolders); } // This finds the first file that has the specific name protected override string FindFirstFileWithExt(string path, string beginswith, bool subfolders) { - string[] files = GetAllFiles(path, subfolders); - foreach(string f in files) - { - if(string.Compare(Path.GetFileName(f), beginswith, true) == 0) - return f; - } - - return null; + string title = Path.GetFileNameWithoutExtension(beginswith); + string ext = Path.GetExtension(beginswith); + if(ext.Length > 1) ext = ext.Substring(1); else ext = ""; + return files.GetFirstFile(path, title, subfolders, ext); } // This loads an entire file in memory and returns the stream // NOTE: Callers are responsible for disposing the stream! protected override MemoryStream LoadFile(string filename) { - return new MemoryStream(File.ReadAllBytes(filename)); + return new MemoryStream(File.ReadAllBytes(Path.Combine(location.location, filename))); } // This creates a temp file for the speciied file and return the absolute path to the temp file @@ -142,7 +129,7 @@ namespace CodeImp.DoomBuilder.Data { // Just copy the file string tempfile = General.MakeTempFilename(General.Map.TempPath, "wad"); - File.Copy(filename, tempfile); + File.Copy(Path.Combine(location.location, filename), tempfile); return tempfile; } diff --git a/Source/Data/PK3Reader.cs b/Source/Data/PK3Reader.cs index d918f9b7..58b19ea0 100644 --- a/Source/Data/PK3Reader.cs +++ b/Source/Data/PK3Reader.cs @@ -35,7 +35,7 @@ namespace CodeImp.DoomBuilder.Data { #region ================== Variables - private List fileslist; + private DirectoryFilesList files; #endregion @@ -50,22 +50,25 @@ namespace CodeImp.DoomBuilder.Data ZipInputStream zipstream = OpenPK3File(); // Make list of all files - fileslist = new List(); + List fileentries = new List(); ZipEntry entry = zipstream.GetNextEntry(); while(entry != null) { - if(entry.IsFile) fileslist.Add(entry.Name.ToLowerInvariant()); + if(entry.IsFile) fileentries.Add(new DirectoryFileEntry(entry.Name)); // Next entry = zipstream.GetNextEntry(); } + // Make files list + files = new DirectoryFilesList(fileentries); + // Done with the zip file zipstream.Close(); zipstream.Dispose(); // Initialize without path (because we use paths relative to the PK3 file) - Initialize(""); + Initialize(); // We have no destructor GC.SuppressFinalize(this); @@ -109,120 +112,40 @@ namespace CodeImp.DoomBuilder.Data // This returns true if the specified file exists protected override bool FileExists(string filename) { - string lowfile = filename.ToLowerInvariant(); - foreach(string f in fileslist) - { - if((string.Compare(f, lowfile) == 0)) return true; - } - - return false; + return files.FileExists(filename); } - + // This returns all files in a given directory protected override string[] GetAllFiles(string path, bool subfolders) { - List matches = new List(); - string lowpath = path.ToLowerInvariant(); - if(subfolders) - { - foreach(string f in fileslist) - { - if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) && - (Path.GetFileName(f).Length > 0)) - matches.Add(f); - } - } - else - { - foreach(string f in fileslist) - { - if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && - (Path.GetFileName(f).Length > 0)) - matches.Add(f); - } - } - - return matches.ToArray(); + return files.GetAllFiles(path, subfolders).ToArray(); } // This returns all files in a given directory that match the given extension protected override string[] GetFilesWithExt(string path, string extension, bool subfolders) { - List matches = new List(); - string lowpath = path.ToLowerInvariant(); - string lowext = "." + extension.ToLowerInvariant(); - if(subfolders) - { - foreach(string f in fileslist) - { - if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) && f.EndsWith(lowext)) - matches.Add(f); - } - } - else - { - foreach(string f in fileslist) - { - if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && f.EndsWith(lowext)) - matches.Add(f); - } - } - - return matches.ToArray(); + return files.GetAllFiles(path, extension, subfolders).ToArray(); + } + + // This finds the first file that has the specific name, regardless of file extension + protected override string FindFirstFile(string beginswith, bool subfolders) + { + return files.GetFirstFile(beginswith, subfolders); } // This finds the first file that has the specific name, regardless of file extension protected override string FindFirstFile(string path, string beginswith, bool subfolders) { - string lowpath = path.ToLowerInvariant(); - string lowbegin = beginswith.ToLowerInvariant(); - if(subfolders) - { - foreach(string f in fileslist) - { - if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) && - (string.Compare(Path.GetFileNameWithoutExtension(f), lowbegin) == 0)) - return f; - } - } - else - { - foreach(string f in fileslist) - { - if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && - (string.Compare(Path.GetFileNameWithoutExtension(f), lowbegin) == 0)) - return f; - } - } - - return null; + return files.GetFirstFile(path, beginswith, subfolders); } // This finds the first file that has the specific name protected override string FindFirstFileWithExt(string path, string beginswith, bool subfolders) { - string lowpath = path.ToLowerInvariant(); - string lowbegin = beginswith.ToLowerInvariant(); - if(subfolders) - { - foreach(string f in fileslist) - { - if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) && - (string.Compare(Path.GetFileName(f), lowbegin) == 0)) - return f; - } - } - else - { - foreach(string f in fileslist) - { - if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && - (string.Compare(Path.GetFileName(f), lowbegin) == 0)) - return f; - } - } - - return null; + string title = Path.GetFileNameWithoutExtension(beginswith); + string ext = Path.GetExtension(beginswith); + if(ext.Length > 1) ext = ext.Substring(1); else ext = ""; + return files.GetFirstFile(path, title, subfolders, ext); } // This loads an entire file in memory and returns the stream @@ -238,19 +161,24 @@ namespace CodeImp.DoomBuilder.Data ZipEntry entry = zipstream.GetNextEntry(); while(entry != null) { - // Is this the entry we are looking for? - if(string.Compare(entry.Name, filename, true) == 0) + if(entry.IsFile) { - int expectedsize = (int)entry.Size; - if(expectedsize < 1) expectedsize = 1024; - filedata = new MemoryStream(expectedsize); - int readsize = zipstream.Read(copybuffer, 0, copybuffer.Length); - while(readsize > 0) + string entryname = entry.Name.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + + // Is this the entry we are looking for? + if(string.Compare(entryname, filename, true) == 0) { - filedata.Write(copybuffer, 0, readsize); - readsize = zipstream.Read(copybuffer, 0, copybuffer.Length); + int expectedsize = (int)entry.Size; + if(expectedsize < 1) expectedsize = 1024; + filedata = new MemoryStream(expectedsize); + int readsize = zipstream.Read(copybuffer, 0, copybuffer.Length); + while(readsize > 0) + { + filedata.Write(copybuffer, 0, readsize); + readsize = zipstream.Read(copybuffer, 0, copybuffer.Length); + } + break; } - break; } // Next diff --git a/Source/Data/PK3StructuredReader.cs b/Source/Data/PK3StructuredReader.cs index e6905969..68182e0d 100644 --- a/Source/Data/PK3StructuredReader.cs +++ b/Source/Data/PK3StructuredReader.cs @@ -48,14 +48,6 @@ namespace CodeImp.DoomBuilder.Data private bool roottextures; private bool rootflats; - // Paths - protected string rootpath; - protected string patchespath; - protected string texturespath; - protected string flatspath; - protected string hirespath; - protected string spritespath; - // WAD files that must be loaded as well private List wads; @@ -76,18 +68,10 @@ namespace CodeImp.DoomBuilder.Data } // Call this to initialize this class - protected virtual void Initialize(string rootpath) + protected virtual void Initialize() { - // Initialize - this.rootpath = rootpath; - this.patchespath = Path.Combine(rootpath, PATCHES_DIR); - this.texturespath = Path.Combine(rootpath, TEXTURES_DIR); - this.flatspath = Path.Combine(rootpath, FLATS_DIR); - this.hirespath = Path.Combine(rootpath, HIRES_DIR); - this.spritespath = Path.Combine(rootpath, SPRITES_DIR); - // Load all WAD files in the root as WAD resources - string[] wadfiles = GetFilesWithExt(rootpath, "wad", false); + string[] wadfiles = GetFilesWithExt("", "wad", false); wads = new List(wadfiles.Length); foreach(string w in wadfiles) { @@ -181,19 +165,19 @@ namespace CodeImp.DoomBuilder.Data // Should we load the images in this directory as textures? if(roottextures) { - collection = LoadDirectoryImages(rootpath, false); + collection = LoadDirectoryImages("", false); AddImagesToList(images, collection); } // TODO: Add support for hires texture here // Add images from texture directory - collection = LoadDirectoryImages(texturespath, false); + collection = LoadDirectoryImages(TEXTURES_DIR, false); AddImagesToList(images, collection); // Load TEXTURE1 lump file List imgset = new List(); - string texture1file = FindFirstFile(rootpath, "TEXTURE1", false); + string texture1file = FindFirstFile("TEXTURE1", false); if((texture1file != null) && FileExists(texture1file)) { MemoryStream filedata = LoadFile(texture1file); @@ -202,7 +186,7 @@ namespace CodeImp.DoomBuilder.Data } // Load TEXTURE2 lump file - string texture2file = FindFirstFile(rootpath, "TEXTURE2", false); + string texture2file = FindFirstFile("TEXTURE2", false); if((texture2file != null) && FileExists(texture2file)) { MemoryStream filedata = LoadFile(texture2file); @@ -234,7 +218,7 @@ namespace CodeImp.DoomBuilder.Data } // If none of the wads provides patch names, let's see if we can - string pnamesfile = FindFirstFile(rootpath, "PNAMES", false); + string pnamesfile = FindFirstFile("PNAMES", false); if((pnamesfile != null) && FileExists(pnamesfile)) { MemoryStream pnamesdata = LoadFile(pnamesfile); @@ -261,7 +245,7 @@ namespace CodeImp.DoomBuilder.Data } // Find in patches directory - string filename = FindFirstFile(patchespath, pname, true); + string filename = FindFirstFile(PATCHES_DIR, pname, true); if((filename != null) && FileExists(filename)) { return LoadFile(filename); @@ -295,12 +279,12 @@ namespace CodeImp.DoomBuilder.Data // Should we load the images in this directory as flats? if(rootflats) { - collection = LoadDirectoryImages(rootpath, true); + collection = LoadDirectoryImages("", true); AddImagesToList(images, collection); } // Add images from flats directory - collection = LoadDirectoryImages(flatspath, true); + collection = LoadDirectoryImages(FLATS_DIR, true); AddImagesToList(images, collection); return images; @@ -326,7 +310,7 @@ namespace CodeImp.DoomBuilder.Data } // Find in sprites directory - string filename = FindFirstFile(spritespath, pfilename, true); + string filename = FindFirstFile(SPRITES_DIR, pfilename, true); if((filename != null) && FileExists(filename)) { return LoadFile(filename); @@ -351,7 +335,7 @@ namespace CodeImp.DoomBuilder.Data } // Find in sprites directory - string filename = FindFirstFile(spritespath, pfilename, true); + string filename = FindFirstFile(SPRITES_DIR, pfilename, true); if((filename != null) && FileExists(filename)) { return true; @@ -381,8 +365,7 @@ namespace CodeImp.DoomBuilder.Data // Find in root directory string filename = Path.GetFileName(pname); string pathname = Path.GetDirectoryName(pname); - string fullpath = Path.Combine(rootpath, pathname); - string foundfile = filename.IndexOf('.') > -1 ? FindFirstFileWithExt(fullpath, filename, false) : FindFirstFile(fullpath, filename, false); + string foundfile = (filename.IndexOf('.') > -1) ? FindFirstFileWithExt(pathname, filename, false) : FindFirstFile(pathname, filename, false); if((foundfile != null) && FileExists(foundfile)) { return LoadFile(foundfile); @@ -453,6 +436,9 @@ namespace CodeImp.DoomBuilder.Data // This must return all files in a given directory that match the given extension protected abstract string[] GetFilesWithExt(string path, string extension, bool subfolders); + // This must find the first file that has the specific name, regardless of file extension + protected abstract string FindFirstFile(string beginswith, bool subfolders); + // This must find the first file that has the specific name, regardless of file extension protected abstract string FindFirstFile(string path, string beginswith, bool subfolders); @@ -466,6 +452,26 @@ namespace CodeImp.DoomBuilder.Data // This must create a temp file for the speciied file and return the absolute path to the temp file // NOTE: Callers are responsible for removing the temp file when done! protected abstract string CreateTempFile(string filename); + + // This makes the path relative to the directory, if needed + protected virtual string MakeRelativePath(string anypath) + { + if(Path.IsPathRooted(anypath)) + { + // Make relative + string lowpath = anypath.ToLowerInvariant(); + string lowlocation = location.location.ToLowerInvariant(); + if((lowpath.Length > (lowlocation.Length + 1)) && lowpath.StartsWith(lowlocation)) + return anypath.Substring(lowlocation.Length + 1); + else + return anypath; + } + else + { + // Path is already relative + return anypath; + } + } #endregion } diff --git a/Source/IO/DirectoryFileEntry.cs b/Source/IO/DirectoryFileEntry.cs new file mode 100644 index 00000000..75250ad5 --- /dev/null +++ b/Source/IO/DirectoryFileEntry.cs @@ -0,0 +1,90 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.IO; + +#endregion + +namespace CodeImp.DoomBuilder.IO +{ + internal struct DirectoryFileEntry + { + // Example for: C:\WADs\Foo\Bar.WAD + // Created from: C:\WADs + // Members + public string filename; // bar.wad + public string filetitle; // bar + public string extension; // wad + public string path; // foo + public string filepathname; // Foo\Bar.WAD + public string filepathtitle; // Foo\Bar + + // Constructor + public DirectoryFileEntry(string fullname, string frompath) + { + // Get the information we need + filename = Path.GetFileName(fullname); + filetitle = Path.GetFileNameWithoutExtension(fullname); + extension = Path.GetExtension(fullname); + if(extension.Length > 1) + extension = extension.Substring(1); + else + extension = ""; + path = Path.GetDirectoryName(fullname); + if(path.Length > (frompath.Length + 1)) + path = path.Substring(frompath.Length + 1); + else + path = ""; + filepathname = Path.Combine(path, filename); + filepathtitle = Path.Combine(path, filetitle); + + // Make some lowercase + filename = filename.ToLowerInvariant(); + filetitle = filetitle.ToLowerInvariant(); + extension = extension.ToLowerInvariant(); + path = path.ToLowerInvariant(); + } + + // Constructor + public DirectoryFileEntry(string fullname) + { + // Get the information we need + filename = Path.GetFileName(fullname); + filetitle = Path.GetFileNameWithoutExtension(fullname); + extension = Path.GetExtension(fullname); + if(extension.Length > 1) + extension = extension.Substring(1); + else + extension = ""; + path = Path.GetDirectoryName(fullname); + filepathname = Path.Combine(path, filename); + filepathtitle = Path.Combine(path, filetitle); + + // Make some lowercase + filename = filename.ToLowerInvariant(); + filetitle = filetitle.ToLowerInvariant(); + extension = extension.ToLowerInvariant(); + path = path.ToLowerInvariant(); + } + } +} diff --git a/Source/IO/DirectoryFilesList.cs b/Source/IO/DirectoryFilesList.cs new file mode 100644 index 00000000..e7400d30 --- /dev/null +++ b/Source/IO/DirectoryFilesList.cs @@ -0,0 +1,266 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.IO; + +#endregion + +namespace CodeImp.DoomBuilder.IO +{ + internal sealed class DirectoryFilesList + { + #region ================== Variables + + private DirectoryFileEntry[] entries; + private Dictionary hashedentries; + + #endregion + + #region ================== Properties + + public int Count { get { return entries.Length; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor to fill list from directory and optionally subdirectories + public DirectoryFilesList(string path, bool subdirectories) + { + path = Path.GetFullPath(path); + string[] files = Directory.GetFiles(path, "*", subdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); + entries = new DirectoryFileEntry[files.Length]; + hashedentries = new Dictionary(files.Length); + for(int i = 0; i < files.Length; i++) + { + entries[i] = new DirectoryFileEntry(files[i], path); + hashedentries.Add(entries[i].filepathname.ToLowerInvariant(), entries[i]); + } + } + + // Constructor for custom list + public DirectoryFilesList(ICollection sourceentries) + { + int index = 0; + entries = new DirectoryFileEntry[sourceentries.Count]; + hashedentries = new Dictionary(sourceentries.Count); + foreach(DirectoryFileEntry e in sourceentries) + { + entries[index] = e; + hashedentries.Add(e.filepathname.ToLowerInvariant(), e); + index++; + } + } + + #endregion + + #region ================== Methods + + // This checks if a given file exists + // The given file path must not be absolute + public bool FileExists(string filepathname) + { + return hashedentries.ContainsKey(filepathname.ToLowerInvariant()); + } + + // This returns file information for the given file + // The given file path must not be absolute + public DirectoryFileEntry GetFileInfo(string filepathname) + { + return hashedentries[filepathname.ToLowerInvariant()]; + } + + // This returns a list of all files (filepathname) + public List GetAllFiles() + { + List files = new List(entries.Length); + for(int i = 0; i < entries.Length; i++) files.Add(entries[i].filepathname); + return files; + } + + // This returns a list of all files optionally with subdirectories included + public List GetAllFiles(bool subdirectories) + { + if(subdirectories) + return GetAllFiles(); + else + { + List files = new List(entries.Length); + for(int i = 0; i < entries.Length; i++) + if(entries[i].path.Length == 0) files.Add(entries[i].filepathname); + return files; + } + } + + // This returns a list of all files that are in the given path and optionally in subdirectories + public List GetAllFiles(string path, bool subdirectories) + { + path = CorrectPath(path).ToLowerInvariant(); + if(subdirectories) + { + List files = new List(entries.Length); + for(int i = 0; i < entries.Length; i++) + if(entries[i].path == path) files.Add(entries[i].filepathname); + return files; + } + else + { + List files = new List(entries.Length); + for(int i = 0; i < entries.Length; i++) + if(entries[i].path == path) files.Add(entries[i].filepathname); + return files; + } + } + + // This returns a list of all files that are in the given path and subdirectories and have the given extension + public List GetAllFiles(string path, string extension) + { + path = CorrectPath(path).ToLowerInvariant(); + extension = extension.ToLowerInvariant(); + List files = new List(entries.Length); + for(int i = 0; i < entries.Length; i++) + if(entries[i].path.StartsWith(path) && (entries[i].extension == extension)) + files.Add(entries[i].filepathname); + return files; + } + + // This returns a list of all files that are in the given path (optionally in subdirectories) and have the given extension + public List GetAllFiles(string path, string extension, bool subdirectories) + { + if(subdirectories) + return GetAllFiles(path, extension); + else + { + path = CorrectPath(path).ToLowerInvariant(); + extension = extension.ToLowerInvariant(); + List files = new List(entries.Length); + for(int i = 0; i < entries.Length; i++) + if((entries[i].path == path) && (entries[i].extension == extension)) + files.Add(entries[i].filepathname); + return files; + } + } + + // This finds the first file that has the specified name, regardless of file extension + public string GetFirstFile(string title, bool subdirectories) + { + title = title.ToLowerInvariant(); + if(subdirectories) + { + for(int i = 0; i < entries.Length; i++) + if(entries[i].filetitle == title) + return entries[i].filepathname; + } + else + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && (entries[i].path.Length == 0)) + return entries[i].filepathname; + } + + return null; + } + + // This finds the first file that has the specified name and extension + public string GetFirstFile(string title, bool subdirectories, string extension) + { + title = title.ToLowerInvariant(); + extension = extension.ToLowerInvariant(); + if(subdirectories) + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && (entries[i].extension == extension)) + return entries[i].filepathname; + } + else + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && (entries[i].path.Length == 0) && (entries[i].extension == extension)) + return entries[i].filepathname; + } + + return null; + } + + // This finds the first file that has the specified name, regardless of file extension, and is in the given path + public string GetFirstFile(string path, string title, bool subdirectories) + { + title = title.ToLowerInvariant(); + path = CorrectPath(path).ToLowerInvariant(); + if(subdirectories) + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && entries[i].path.StartsWith(path)) + return entries[i].filepathname; + } + else + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && (entries[i].path == path)) + return entries[i].filepathname; + } + + return null; + } + + // This finds the first file that has the specified name, is in the given path and has the given extension + public string GetFirstFile(string path, string title, bool subdirectories, string extension) + { + title = title.ToLowerInvariant(); + path = CorrectPath(path).ToLowerInvariant(); + extension = extension.ToLowerInvariant(); + if(subdirectories) + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && entries[i].path.StartsWith(path) && (entries[i].extension == extension)) + return entries[i].filepathname; + } + else + { + for(int i = 0; i < entries.Length; i++) + if((entries[i].filetitle == title) && (entries[i].path == path) && (entries[i].extension == extension)) + return entries[i].filepathname; + } + + return null; + } + + // This fixes a path so that it doesn't have the \ at the end + private string CorrectPath(string path) + { + if(path.Length > 0) + { + if((path[path.Length - 1] == Path.DirectorySeparatorChar) || (path[path.Length - 1] == Path.AltDirectorySeparatorChar)) + return path.Substring(0, path.Length - 1); + else + return path; + } + else + { + return path; + } + } + + #endregion + } +}