From 048e20b659e596fd93f2dc7d8a6d315c13c233f1 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Thu, 17 Feb 2022 08:08:24 -0800 Subject: [PATCH] Making the queue a file folder --- .../ApplicationView/ApplicationController.cs | 22 +- .../DialogPages/CacheDirectory.cs | 10 - .../History/PrintHistoryListItem.cs | 32 -- .../MatterControl/PrintQueueContainer.cs | 170 ---------- MatterControlLib/Queue/QueueData.cs | 302 ------------------ MatterControlLib/RootSystemWindow.cs | 3 - .../Utilities/ManifestFileHandler.cs | 160 ++++------ .../MatterControl/MatterControlUtilities.cs | 4 +- 8 files changed, 81 insertions(+), 622 deletions(-) delete mode 100644 MatterControlLib/Library/Providers/MatterControl/PrintQueueContainer.cs delete mode 100644 MatterControlLib/Queue/QueueData.cs diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index e1c6ee796..8e014de9b 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -864,15 +864,25 @@ namespace MatterHackers.MatterControl forceAddQueue = true; #endif // only add the queue if there are items in it - var queueItems = QueueData.Instance.PrintItems.ToList(); - if (forceAddQueue || queueItems.Any()) + var queueDirectory = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, "Queue"); + LegacyQueueFiles.ImportFromLegacy(queueDirectory); + if (forceAddQueue || Directory.Exists(queueDirectory)) { - this.Library.RegisterContainer( - new DynamicContainerLink( - "Print Queue".Localize(), + // make sure the queue directory exists + Directory.CreateDirectory(queueDirectory); + + this.Library.RegisterContainer(new DynamicContainerLink( + "Queue".Localize(), StaticData.Instance.LoadIcon(Path.Combine("Library", "folder.png")), StaticData.Instance.LoadIcon(Path.Combine("Library", "queue_icon.png")), - () => new PrintQueueContainer())); + () => new FileSystemContainer(queueDirectory) + { + UseIncrementedNameDuringTypeChange = true, + DefaultSort = new LibrarySortBehavior() + { + SortKey = SortKey.ModifiedDate, + } + })); } this.Library.DesignAppsCollectionContainer = new DesignAppsCollectionContainer(); diff --git a/MatterControlLib/DialogPages/CacheDirectory.cs b/MatterControlLib/DialogPages/CacheDirectory.cs index 942d32d33..9eaffe3b1 100644 --- a/MatterControlLib/DialogPages/CacheDirectory.cs +++ b/MatterControlLib/DialogPages/CacheDirectory.cs @@ -50,16 +50,6 @@ namespace MatterHackers.MatterControl HashSet filesToKeep = new HashSet(); - // Get a list of all the stl and amf files referenced in the queue. - foreach (PrintItemWrapper printItem in QueueData.Instance.PrintItems) - { - string fileLocation = printItem.FileLocation; - if (!filesToKeep.Contains(fileLocation)) - { - filesToKeep.Add(fileLocation); - } - } - var allPrintItems = Datastore.Instance.dbSQLite.Query("SELECT * FROM PrintItem;"); // Add in all the stl and amf files referenced in the library. diff --git a/MatterControlLib/History/PrintHistoryListItem.cs b/MatterControlLib/History/PrintHistoryListItem.cs index 6038a1760..d335a3ee9 100644 --- a/MatterControlLib/History/PrintHistoryListItem.cs +++ b/MatterControlLib/History/PrintHistoryListItem.cs @@ -502,40 +502,8 @@ namespace MatterHackers.MatterControl.PrintHistory primaryFlow.AddChild(timestampColumn); } - public void ShowCantFindFileMessage(PrintItemWrapper printItemWrapper) - { - itemToRemove = printItemWrapper; - UiThread.RunOnIdle(() => - { - string maxLengthName = printItemWrapper.FileLocation; - int maxLength = 43; - if (maxLengthName.Length > maxLength) - { - string start = maxLengthName.Substring(0, 15) + "..."; - int amountRemaining = maxLength - start.Length; - string end = maxLengthName.Substring(maxLengthName.Length - amountRemaining, amountRemaining); - maxLengthName = start + end; - } - - string notFoundMessage = "Oops! Could not find this file".Localize() + ":"; - string message = "{0}:\n'{1}'".FormatWith(notFoundMessage, maxLengthName); - string titleLabel = "Item not Found".Localize(); - StyledMessageBox.ShowMessageBox(OnConfirmRemove, message, titleLabel, StyledMessageBox.MessageType.OK); - }); - } - - private PrintItemWrapper itemToRemove; private PrintTask printTask; private GuiWidget indicator; private TextWidget printInfoWidget; - - private void OnConfirmRemove(bool messageBoxResponse) - { - if (messageBoxResponse) - { - int index = QueueData.Instance.GetIndex(itemToRemove); - UiThread.RunOnIdle(() => QueueData.Instance.RemoveAt(index)); - } - } } } \ No newline at end of file diff --git a/MatterControlLib/Library/Providers/MatterControl/PrintQueueContainer.cs b/MatterControlLib/Library/Providers/MatterControl/PrintQueueContainer.cs deleted file mode 100644 index 86c66db9d..000000000 --- a/MatterControlLib/Library/Providers/MatterControl/PrintQueueContainer.cs +++ /dev/null @@ -1,170 +0,0 @@ -/* -Copyright (c) 2022, John Lewin, Lars Brubaker -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using MatterHackers.Agg; -using MatterHackers.Agg.Image; -using MatterHackers.DataConverters3D; -using MatterHackers.Localizations; -using MatterHackers.MatterControl.DataStorage; -using MatterHackers.MatterControl.PrintQueue; - -namespace MatterHackers.MatterControl.Library -{ - public class PrintQueueContainer : WritableContainer - { - public PrintQueueContainer() - { - this.IsProtected = false; - this.ChildContainers = new SafeList(); - this.Items = new SafeList(); - this.Name = "Print Queue".Localize(); - } - - public override void Load() - { - var queueItems = QueueData.Instance.PrintItems.ToList(); - - var existingItems = queueItems.Where(p => File.Exists(p.FileLocation)).ToList(); - - var missingItems = queueItems.Except(existingItems).ToList(); - - this.Items = new SafeList(existingItems.Select(p => new FileSystemFileItem(p.FileLocation) - { - Name = p.Name - }) - .Concat(missingItems.Select(p => new MissingFileItem(p.Name)))); - } - - public override async void Add(IEnumerable items) - { - await AddAllItems(items); - this.ReloadContent(); - } - - public override void Save(ILibraryItem item, IObject3D content) - { - if (item is FileSystemFileItem fileItem) - { - // save using the normal uncompressed mcx file - // Serialize the scene to disk using a modified Json.net pipeline with custom ContractResolvers and JsonConverters - File.WriteAllText(fileItem.FilePath, content.ToJson().Result); - - this.OnItemContentChanged(new LibraryItemChangedEventArgs(fileItem)); - } - } - - public override void SetThumbnail(ILibraryItem item, int width, int height, ImageBuffer imageBuffer) - { -#if DEBUG - //throw new NotImplementedException(); -#endif - } - - public static async Task AddAllItems(IEnumerable items) - { - await Task.Run(async () => - { - foreach (var item in items) - { - switch (item) - { - case ILibraryAssetStream streamItem: - string itemPath; - - if (streamItem is FileSystemFileItem fileItem) - { - // Get existing file path - itemPath = fileItem.FilePath; - } - else - { - // Copy stream to library path - itemPath = ApplicationDataStorage.Instance.GetNewLibraryFilePath("." + streamItem.ContentType); - - using (var outputStream = File.OpenWrite(itemPath)) - { - using (var streamInteface = await streamItem.GetStream(null)) - { - streamInteface.Stream.CopyTo(outputStream); - } - } - } - - // Add to Queue - if (File.Exists(itemPath)) - { - QueueData.Instance.AddItem( - new PrintItemWrapper( - new PrintItem(streamItem.Name, itemPath)), - 0); - } - - break; - } - } - }); - } - - public override void Remove(IEnumerable items) - { - foreach (var fileSystemItem in items.OfType()) - { - if (fileSystemItem != null) - { - var matches = QueueData.Instance.PrintItems.Where(p => p.FileLocation == fileSystemItem.FilePath).ToList(); - - foreach(var printItem in matches) - { - int index = QueueData.Instance.GetIndex(printItem); - if (index != -1) - { - QueueData.Instance.RemoveAt(index); - } - } - } - } - - this.ReloadContent(); - } - - public override bool AllowAction(ContainerActions containerActions) - { - return containerActions != ContainerActions.AddContainers; - } - - public override void Dispose() - { - } - } -} diff --git a/MatterControlLib/Queue/QueueData.cs b/MatterControlLib/Queue/QueueData.cs deleted file mode 100644 index 591627ce7..000000000 --- a/MatterControlLib/Queue/QueueData.cs +++ /dev/null @@ -1,302 +0,0 @@ -/* -Copyright (c) 2017, Kevin Pope, John Lewin -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using MatterHackers.Agg; -using MatterHackers.Agg.Platform; -using MatterHackers.Agg.UI; -using MatterHackers.DataConverters3D; -using MatterHackers.Localizations; -using MatterHackers.MatterControl.DataStorage; -using MatterHackers.MatterControl.PrinterCommunication; -using MatterHackers.PolygonMesh.Processors; - -namespace MatterHackers.MatterControl.PrintQueue -{ - public class ItemChangedArgs : EventArgs - { - public int Index { get; private set; } - - internal ItemChangedArgs(int index) - { - this.Index = index; - } - } - - public class QueueData - { - public static readonly string SdCardFileName = "SD_CARD"; - - private List printItems = new List(); - - public List PrintItems - { - get { return printItems; } - } - - public RootedObjectEventHandler ItemAdded = new RootedObjectEventHandler(); - - public RootedObjectEventHandler ItemRemoved = new RootedObjectEventHandler(); - - private static QueueData instance; - - public static QueueData Instance - { - get - { - if (instance == null) - { - instance = new QueueData(); - instance.LoadDefaultQueue(); - } - return instance; - } - } - - public void RemoveAt(int index) - { - if (index >= 0 && index < ItemCount) - { - PrintItems.RemoveAt(index); - - OnItemRemoved(new ItemChangedArgs(index)); - SaveDefaultQueue(); - } - } - - public void OnItemRemoved(EventArgs e) - { - ItemRemoved.CallEvents(this, e); - } - - public PrintItemWrapper GetPrintItemWrapper(int index) - { - if (index >= 0 && index < PrintItems.Count) - { - return PrintItems[index]; - } - - return null; - } - - public int GetIndex(PrintItemWrapper printItem) - { - return PrintItems.IndexOf(printItem); - } - - public string[] GetItemNames() - { - List itemNames = new List(); - for (int i = 0; i < PrintItems.Count; i++) - { - itemNames.Add(PrintItems[i].Name); - } - - return itemNames.ToArray(); - } - - public string GetItemName(int itemIndex) - { - return PrintItems[itemIndex].Name; - } - - public List CreateReadOnlyPartList(bool includeProtectedItems) - { - List listToReturn = new List(); - for (int i = 0; i < ItemCount; i++) - { - var printItem = GetPrintItemWrapper(i).PrintItem; - if (includeProtectedItems - || !printItem.Protected) - { - listToReturn.Add(printItem); - } - } - - return listToReturn; - } - - private static readonly bool Is32Bit = IntPtr.Size == 4; - - private PrintItemWrapper partUnderConsideration = null; - - public enum ValidateSizeOn32BitSystems { Required, Skip } - - public void AddItem(PrintItemWrapper item, int indexToInsert = -1, ValidateSizeOn32BitSystems checkSize = ValidateSizeOn32BitSystems.Required) - { - if (Is32Bit) - { - // Check if the part we are adding is BIG. If it is warn the user and - // possibly don't add it - bool warnAboutFileSize = false; - long estimatedMemoryUse = 0; - if (File.Exists(item.FileLocation) - && checkSize == ValidateSizeOn32BitSystems.Required) - { - estimatedMemoryUse = GetEstimatedMemoryUse(item.FileLocation); - - // If we have less than 2 gigs memory, warn on smaller file size - if (AggContext.PhysicalMemory < 2000000000) - { - if (estimatedMemoryUse > 100000000) - { - warnAboutFileSize = true; - } - } - else - { - if (estimatedMemoryUse > 500000000) - { - warnAboutFileSize = true; - } - } - } - - if (warnAboutFileSize) - { - partUnderConsideration = item; - // Show a dialog and only load the part to the queue if the user clicks yes. - UiThread.RunOnIdle(() => - { - string memoryWarningMessage = "Are you sure you want to add this part ({0}) to the Queue?\nThe 3D part you are trying to load may be too complicated and cause performance or stability problems.\n\nConsider reducing the geometry before proceeding.".Localize().FormatWith(item.Name); - StyledMessageBox.ShowMessageBox( - UserSaidToAllowAddToQueue, memoryWarningMessage, "File May Cause Problems".Localize(), StyledMessageBox.MessageType.YES_NO, "Add To Queue", "Do Not Add"); - // show a dialog to tell the user there is an update - }); - return; - } - else - { - DoAddItem(item, indexToInsert); - } - } - else - { - DoAddItem(item, indexToInsert); - } - } - - public static long GetEstimatedMemoryUse(string fileLocation) - { - switch (Path.GetExtension(fileLocation).ToUpper()) - { - case ".STL": - return StlProcessing.GetEstimatedMemoryUse(fileLocation); - - case ".3MF": - case ".AMF": - return AmfDocument.GetEstimatedMemoryUse(fileLocation); - - case ".OBJ": - throw new NotImplementedException(); - } - - return 0; - } - - private void UserSaidToAllowAddToQueue(bool messageBoxResponse) - { - if (messageBoxResponse) - { - DoAddItem(partUnderConsideration, -1); - } - } - - private void DoAddItem(PrintItemWrapper item, int insertAt) - { - if (insertAt == -1) - { - insertAt = PrintItems.Count; - } - - PrintItems.Insert(insertAt, item); - OnItemAdded(new ItemChangedArgs(insertAt)); - SaveDefaultQueue(); - } - - public void LoadDefaultQueue() - { - RemoveAll(); - ManifestFileHandler manifest = new ManifestFileHandler(null); - List partFiles = manifest.ImportFromJson(); - if (partFiles != null) - { - foreach (PrintItem item in partFiles) - { - AddItem(new PrintItemWrapper(item), -1, QueueData.ValidateSizeOn32BitSystems.Skip); - } - } - RemoveAllSdCardFiles(); - } - - public void RemoveAllSdCardFiles() - { - for (int i = ItemCount - 1; i >= 0; i--) - { - PrintItem printItem = PrintItems[i].PrintItem; - if (printItem.FileLocation == QueueData.SdCardFileName) - { - RemoveAt(i); - } - } - } - - public void OnItemAdded(EventArgs e) - { - ItemAdded.CallEvents(this, e); - } - - public void SaveDefaultQueue() - { - List partList = CreateReadOnlyPartList(true); - ManifestFileHandler manifest = new ManifestFileHandler(partList); - manifest.ExportToJson(); - } - - public int ItemCount - { - get - { - return PrintItems.Count; - } - } - - public void RemoveAll() - { - for (int i = PrintItems.Count - 1; i >= 0; i--) - { - RemoveAt(i); - } - } - } -} \ No newline at end of file diff --git a/MatterControlLib/RootSystemWindow.cs b/MatterControlLib/RootSystemWindow.cs index 019fd3253..ec7718707 100644 --- a/MatterControlLib/RootSystemWindow.cs +++ b/MatterControlLib/RootSystemWindow.cs @@ -216,9 +216,6 @@ namespace MatterHackers.MatterControl ApplicationSettings.Instance.set(ApplicationSettingsKey.DesktopPosition, string.Format("{0},{1}", DesktopPosition.x, DesktopPosition.y)); } - // Save a snapshot of the prints in queue - QueueData.Instance.SaveDefaultQueue(); - // If we are waiting for a response and get another request, just cancel the close until we get a response. if (exitDialogOpen) { diff --git a/MatterControlLib/Utilities/ManifestFileHandler.cs b/MatterControlLib/Utilities/ManifestFileHandler.cs index 929fce20b..fb70b172f 100644 --- a/MatterControlLib/Utilities/ManifestFileHandler.cs +++ b/MatterControlLib/Utilities/ManifestFileHandler.cs @@ -35,113 +35,79 @@ using Newtonsoft.Json; namespace MatterHackers.MatterControl { - internal class ManifestFile + public class QueueData + { + private static QueueData instance; + public static QueueData Instance + { + get + { + if (instance == null) + { + instance = new QueueData(); + } + + return instance; + } + } + + public int ItemCount + { + get + { + throw new NotImplementedException(); + } + } + + public void AddItem(string filePath) + { + throw new NotImplementedException(); + } + + public string GetFirstItem() + { + throw new NotImplementedException(); + } + + public IEnumerable GetItemNames() + { + throw new NotImplementedException(); + } + } + + public class LegacyQueueFiles { - private List projectFiles; - private string projectName = "Test Project"; - private string projectDateCreated; + public List ProjectFiles { get; set; } - public ManifestFile() + public static void ImportFromLegacy(string destPath) { - DateTime now = DateTime.Now; - projectDateCreated = now.ToString("s"); - } + var filePath = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "default.mcp"); - public List ProjectFiles - { - get + if (!File.Exists(filePath)) { - return projectFiles; - } - - set - { - projectFiles = value; - } - } - - public string ProjectName - { - get - { - return projectName; - } - - set - { - projectName = value; - } - } - - public string ProjectDateCreated - { - get - { - return projectDateCreated; - } - - set - { - projectDateCreated = value; - } - } - } - - internal class ManifestFileHandler - { - private ManifestFile project; - - public ManifestFileHandler(List projectFiles) - { - if (projectFiles != null) - { - project = new ManifestFile(); - project.ProjectFiles = projectFiles; - } - } - - private static string applicationDataPath = ApplicationDataStorage.ApplicationUserDataPath; - private static string defaultPathAndFileName = Path.Combine(applicationDataPath , "data", "default.mcp"); - - public void ExportToJson(string savedFileName = null) - { - if (savedFileName == null) - { - savedFileName = defaultPathAndFileName; - } - - - string jsonString = JsonConvert.SerializeObject(this.project, Newtonsoft.Json.Formatting.Indented); - string pathToDataFolder = Path.Combine(applicationDataPath, "data"); - if (!Directory.Exists(pathToDataFolder)) - { - Directory.CreateDirectory(pathToDataFolder); - } - - File.WriteAllText(savedFileName, jsonString); - } - - public List ImportFromJson(string filePath = null) - { - if (filePath == null) - { - filePath = defaultPathAndFileName; - } - - if (!System.IO.File.Exists(filePath)) - { - return null; + // nothing to do + return; } string json = File.ReadAllText(filePath); - ManifestFile newProject = JsonConvert.DeserializeObject(json); - if (newProject == null) - { - return new List(); - } + LegacyQueueFiles newProject = JsonConvert.DeserializeObject(json); + if (newProject.ProjectFiles.Count == 0) + { + return; + } - return newProject.ProjectFiles; + Directory.CreateDirectory(destPath); + foreach (var printItem in newProject.ProjectFiles) + { + var destFile = Path.Combine(destPath, Path.ChangeExtension(printItem.Name, Path.GetExtension(printItem.FileLocation))); + if (!File.Exists(destFile) + && File.Exists(printItem.FileLocation)) + { + // copy the print item to the destination directory + File.Copy(printItem.FileLocation, destFile, true); + } + } } } } \ No newline at end of file diff --git a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs index 5c6b3d8ea..d754ec496 100644 --- a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs +++ b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs @@ -626,13 +626,13 @@ namespace MatterHackers.MatterControl.Tests.Automation if (!File.Exists(mcpPath)) { - File.WriteAllText(mcpPath, JsonConvert.SerializeObject(new ManifestFile() + File.WriteAllText(mcpPath, JsonConvert.SerializeObject(new LegacyQueueFiles() { ProjectFiles = new List() }, Formatting.Indented)); } - var queueItemData = JsonConvert.DeserializeObject(File.ReadAllText(mcpPath)); + var queueItemData = JsonConvert.DeserializeObject(File.ReadAllText(mcpPath)); string queueData = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "testitems");