diff --git a/Library/Providers/MatterControl/SqliteLibraryContainer.cs b/Library/Providers/MatterControl/SqliteLibraryContainer.cs index 07a3752fb..0c03237a1 100644 --- a/Library/Providers/MatterControl/SqliteLibraryContainer.cs +++ b/Library/Providers/MatterControl/SqliteLibraryContainer.cs @@ -58,8 +58,6 @@ namespace MatterHackers.MatterControl.Library public class SqliteLibraryContainer : WritableContainer { - protected List childCollections = new List(); - // Use default rootCollectionID - normally this constructor isn't used but exists to validate behavior in tests public SqliteLibraryContainer() : this(Datastore.Instance.dbSQLite.Table().Where(v => v.Name == "_library").Take(1).FirstOrDefault()?.Id ?? 0) @@ -94,14 +92,25 @@ namespace MatterHackers.MatterControl.Library public override void Load() { - childCollections = GetChildCollections(); + var childCollections = this.GetChildCollections(); - this.ChildContainers = childCollections.Select(c => new SqliteLibraryContainerLink() + var allFiles = this.GetLibraryItems(KeywordFilter); + + var zipFiles = allFiles.Where(f => string.Equals(Path.GetExtension(f.FileLocation), ".zip", StringComparison.OrdinalIgnoreCase)); + + var nonZipFiles = allFiles.Except(zipFiles); + + IEnumerable childContainers = childCollections.Select(c => new SqliteLibraryContainerLink() { - ContainerID = c.Id, Name = c.Name }).ToList(); // + ContainerID = c.Id, + Name = c.Name + }); + + this.ChildContainers = childContainers.Concat( + zipFiles.Select(f => new LocalZipContainerLink(f.FileLocation, f.Name))).OrderBy(d => d.Name).ToList(); // PrintItems projected onto FileSystemFileItem - Items = GetLibraryItems(KeywordFilter).Select(printItem => + this.Items = nonZipFiles.Select(printItem => { if (File.Exists(printItem.FileLocation)) { @@ -163,7 +172,7 @@ namespace MatterHackers.MatterControl.Library public List GetLibraryItems(string keyphrase = null) { - // TODO: String concatenation to build sql statements is the root of all sql injection attacts. This needs to be changed to use parameter objects as would be expected + // TODO: String concatenation to build sql statements is the root of all sql injection attacks. This needs to be changed to use parameter objects as would be expected string query; if (string.IsNullOrEmpty(keyphrase)) { diff --git a/Library/Providers/Zip/LocalZipContainerLink.cs b/Library/Providers/Zip/LocalZipContainerLink.cs index d99dd1f51..856106ab3 100644 --- a/Library/Providers/Zip/LocalZipContainerLink.cs +++ b/Library/Providers/Zip/LocalZipContainerLink.cs @@ -51,10 +51,15 @@ namespace MatterHackers.MatterControl.Library public override bool IsProtected { get; } = true; - public LocalZipContainerLink(string filePath) + public LocalZipContainerLink(string filePath, string nameOverride = null) : base(filePath) { this.ThumbnailKey = null; + + if (nameOverride != null) + { + this.Name = nameOverride; + } } private string currentDirectory = ""; diff --git a/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs b/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs index 4f7decb08..74528e7db 100644 --- a/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs +++ b/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs @@ -66,8 +66,13 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.Delay(1); testRunner.Type("{Enter}"); - Assert.IsTrue(testRunner.WaitForName("Row Item Batman"), "Batman part should exist after adding"); - Assert.IsTrue(testRunner.WaitForName("Row Item 2013-01-25 Mouthpiece V2"), "Mouthpiece part should exist after adding"); + testRunner.WaitForName("Batman Row Item Collection"); + + testRunner.DoubleClickByName("Batman Row Item Collection"); + + + Assert.IsTrue(testRunner.WaitForName("Row Item Batman.stl"), "Batman part should exist after adding"); + Assert.IsTrue(testRunner.WaitForName("Row Item 2013-01-25_Mouthpiece_v2.stl"), "Mouthpiece part should exist after adding"); return Task.CompletedTask; });