diff --git a/ControlElements/MHTextEditWidget.cs b/ControlElements/MHTextEditWidget.cs index 5aa3bc11b..18ca3c7bf 100644 --- a/ControlElements/MHTextEditWidget.cs +++ b/ControlElements/MHTextEditWidget.cs @@ -43,7 +43,7 @@ namespace MatterHackers.MatterControl { if (noContentFieldDescription != null) { - if (Text == "" || !ContainsFocus) + if (Text == "") { noContentFieldDescription.Visible = true; } diff --git a/Library/LibraryDataView.cs b/Library/LibraryDataView.cs index d5565f6a1..6226e92e0 100644 --- a/Library/LibraryDataView.cs +++ b/Library/LibraryDataView.cs @@ -68,6 +68,9 @@ namespace MatterHackers.MatterControl.PrintLibrary public LibraryDataView() { + currentLibraryProvider = LibraryProviderSelector.Instance; + currentLibraryProvider.DataReloaded += LibraryDataReloaded; + if (libraryDataViewInstance != null) { throw new Exception("There should only ever be one of these, Lars."); @@ -97,7 +100,7 @@ namespace MatterHackers.MatterControl.PrintLibrary public event HoverValueChangedEventHandler HoverValueChanged; - public event Action SelectedValueChanged; + public event Action SelectedIndexChanged; private event EventHandler unregisterEvents; @@ -105,11 +108,6 @@ namespace MatterHackers.MatterControl.PrintLibrary { get { - if (currentLibraryProvider == null) - { - currentLibraryProvider = LibraryProviderSelector.Instance; - } - return currentLibraryProvider; } @@ -371,9 +369,9 @@ namespace MatterHackers.MatterControl.PrintLibrary public void OnSelectedIndexChanged() { Invalidate(); - if (SelectedValueChanged != null) + if (SelectedIndexChanged != null) { - SelectedValueChanged(this, null); + SelectedIndexChanged(this, null); } } diff --git a/Library/LibraryRowItem.cs b/Library/LibraryRowItem.cs index e7be5c03b..be63ba92d 100644 --- a/Library/LibraryRowItem.cs +++ b/Library/LibraryRowItem.cs @@ -224,7 +224,7 @@ namespace MatterHackers.MatterControl.PrintLibrary public abstract void Edit(); public abstract void Export(); - + public abstract void RemoveFromCollection(); protected abstract SlideWidget GetItemActionButtons(); diff --git a/Library/PrintLibraryWidget.cs b/Library/PrintLibraryWidget.cs index 4d9000691..7b27cc63d 100644 --- a/Library/PrintLibraryWidget.cs +++ b/Library/PrintLibraryWidget.cs @@ -57,6 +57,7 @@ namespace MatterHackers.MatterControl.PrintLibrary public class PrintLibraryWidget : GuiWidget { private static CreateFolderWindow createFolderWindow = null; + private static RenameItemWindow renameItemWindow = null; private static TextImageButtonFactory textImageButtonFactory = new TextImageButtonFactory(); private TextImageButtonFactory editButtonFactory = new TextImageButtonFactory(); private TextWidget navigationLabel; @@ -187,7 +188,7 @@ namespace MatterHackers.MatterControl.PrintLibrary addToLibraryButton = textImageButtonFactory.Generate(LocalizedString.Get("Add"), "icon_circle_plus.png"); buttonPanel.AddChild(addToLibraryButton); addToLibraryButton.Margin = new BorderDouble(0, 0, 3, 0); - addToLibraryButton.Click += new EventHandler((sender, e) => UiThread.RunOnIdle(importToLibraryloadFile_ClickOnIdle)); + addToLibraryButton.Click += (sender, e) => UiThread.RunOnIdle(importToLibraryloadFile_ClickOnIdle); } // the create folder button @@ -195,19 +196,21 @@ namespace MatterHackers.MatterControl.PrintLibrary Button createFolderButton = textImageButtonFactory.Generate(LocalizedString.Get("Create Folder")); buttonPanel.AddChild(createFolderButton); createFolderButton.Margin = new BorderDouble(0, 0, 3, 0); - createFolderButton.Click += new EventHandler((sender, e) => + createFolderButton.Click += (sender, e) => { if (createFolderWindow == null) { - createFolderWindow = new CreateFolderWindow(CreateNamedFolder); - createFolderWindow.Closed += new EventHandler(CreateFolderWindow_Closed); + createFolderWindow = new CreateFolderWindow((returnInfo) => + { + LibraryDataView.CurrentLibraryProvider.AddCollectionToLibrary(returnInfo.newName); + }); + createFolderWindow.Closed += (sender2, e2) => { createFolderWindow = null; }; } else { createFolderWindow.BringToFront(); } - } - ); + }; } //Add extra buttons (ex. from plugins) if available @@ -236,17 +239,6 @@ namespace MatterHackers.MatterControl.PrintLibrary } } - - private static void CreateFolderWindow_Closed(object sender, EventArgs e) - { - createFolderWindow = null; - } - - private static void CreateNamedFolder(CreateFolderWindow.CreateFolderReturnInfo returnInfo) - { - LibraryDataView.CurrentLibraryProvider.AddCollectionToLibrary(returnInfo.newName); - } - private void CreateEditBarButtons() { itemOperationButtons = new FlowLayoutWidget(); @@ -257,25 +249,64 @@ namespace MatterHackers.MatterControl.PrintLibrary Button exportItemButton = editButtonFactory.Generate("Export".Localize()); exportItemButton.Margin = new BorderDouble(3, 0); - exportItemButton.Click += new EventHandler(exportButton_Click); + exportItemButton.Click += exportButton_Click; editButtonsEnableData.Add(new ButtonEnableData(false, false)); itemOperationButtons.AddChild(exportItemButton); Button editItemButton = editButtonFactory.Generate("Edit".Localize()); editItemButton.Margin = new BorderDouble(3, 0); - editItemButton.Click += new EventHandler(editButton_Click); + editItemButton.Click += editButton_Click; editButtonsEnableData.Add(new ButtonEnableData(false, false)); itemOperationButtons.AddChild(editItemButton); - Button removeFromLibraryButton = editButtonFactory.Generate("Remove".Localize()); - removeFromLibraryButton.Margin = new BorderDouble(3, 0); - removeFromLibraryButton.Click += new EventHandler(deleteFromLibraryButton_Click); - editButtonsEnableData.Add(new ButtonEnableData(true, false)); - itemOperationButtons.AddChild(removeFromLibraryButton); + // add the remove button + { + Button removeFromLibraryButton = editButtonFactory.Generate("Remove".Localize()); + removeFromLibraryButton.Margin = new BorderDouble(3, 0); + removeFromLibraryButton.Click += deleteFromLibraryButton_Click; + editButtonsEnableData.Add(new ButtonEnableData(true, false)); + itemOperationButtons.AddChild(removeFromLibraryButton); + } + + // add a rename button + { + Button renameFromLibraryButton = editButtonFactory.Generate("Rename".Localize()); + renameFromLibraryButton.Margin = new BorderDouble(3, 0); + editButtonsEnableData.Add(new ButtonEnableData(true, false)); + itemOperationButtons.AddChild(renameFromLibraryButton); + + renameFromLibraryButton.Click += (sender, e) => + { + if (libraryDataView.SelectedItems.Count == 1) + { + if (renameItemWindow == null) + { + string currentName = "currentName"; + renameItemWindow = new RenameItemWindow(currentName, (returnInfo) => + { + }); + + renameItemWindow.Closed += (sender2, e2) => { renameItemWindow = null; }; + } + else + { + renameItemWindow.BringToFront(); + } + + /* + LibraryDataView.CurrentLibraryProvider.RenameCollection(collectionIndex, newName); + + LibraryRowItem libraryItem = libraryDataView.SelectedItems[0]; + libraryItem.RenameThisInPrintLibrary(newName.Data); + + */ + } + }; + } Button addToQueueButton = editButtonFactory.Generate("Add to Queue".Localize()); addToQueueButton.Margin = new BorderDouble(3, 0); - addToQueueButton.Click += new EventHandler(addToQueueButton_Click); + addToQueueButton.Click += addToQueueButton_Click; editButtonsEnableData.Add(new ButtonEnableData(true, true)); itemOperationButtons.AddChild(addToQueueButton); @@ -370,7 +401,7 @@ namespace MatterHackers.MatterControl.PrintLibrary searchButtonClick(null, null); } - private void enterEditModeButtonClick(object sender, EventArgs mouseEvent) + private void enterEditModeButtonClick(object sender, EventArgs e) { enterEditModeButton.Visible = false; leaveEditModeButton.Visible = true; @@ -380,7 +411,7 @@ namespace MatterHackers.MatterControl.PrintLibrary SetEditButtonsStates(); } - private void leaveEditModeButtonClick(object sender, EventArgs mouseEvent) + private void leaveEditModeButtonClick(object sender, EventArgs e) { enterEditModeButton.Visible = true; leaveEditModeButton.Visible = false; @@ -390,7 +421,7 @@ namespace MatterHackers.MatterControl.PrintLibrary SetEditButtonsStates(); } - private void searchButtonClick(object sender, EventArgs mouseEvent) + private void searchButtonClick(object sender, EventArgs e) { string searchText = searchInput.Text.Trim(); LibraryDataView.CurrentLibraryProvider.KeywordFilter = searchText; @@ -455,7 +486,7 @@ namespace MatterHackers.MatterControl.PrintLibrary this.AnchorAll(); } - private void deleteFromLibraryButton_Click(object sender, EventArgs mouseEvent) + private void deleteFromLibraryButton_Click(object sender, EventArgs e) { foreach (LibraryRowItem item in libraryDataView.SelectedItems) { @@ -468,7 +499,7 @@ namespace MatterHackers.MatterControl.PrintLibrary private ExportPrintItemWindow exportingWindow; private bool exportingWindowIsOpen = false; - private void exportButton_Click(object sender, EventArgs mouseEvent) + private void exportButton_Click(object sender, EventArgs e) { //Open export options if (libraryDataView.SelectedItems.Count == 1) @@ -478,7 +509,7 @@ namespace MatterHackers.MatterControl.PrintLibrary } } - private void editButton_Click(object sender, EventArgs mouseEvent) + private void editButton_Click(object sender, EventArgs e) { //Open export options if (libraryDataView.SelectedItems.Count == 1) diff --git a/Library/Provider/LibraryProvider.cs b/Library/Provider/LibraryProvider.cs index 49cea0d81..2580f160f 100644 --- a/Library/Provider/LibraryProvider.cs +++ b/Library/Provider/LibraryProvider.cs @@ -157,8 +157,12 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider public abstract void RemoveCollection(int collectionIndexToRemove); + public abstract void RenameCollection(int collectionIndexToRename, string newName); + public abstract void RemoveItem(int itemIndexToRemove); + public abstract void RenameItem(int itemIndexToRename, string newName); + #endregion Abstract Methods #region Static Methods diff --git a/Library/Provider/LibraryProviderFileSystem.cs b/Library/Provider/LibraryProviderFileSystem.cs index 75d6bb7e8..ecbef9688 100644 --- a/Library/Provider/LibraryProviderFileSystem.cs +++ b/Library/Provider/LibraryProviderFileSystem.cs @@ -84,6 +84,11 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider } } + public override void RenameItem(int itemIndexToRename, string newName) + { + throw new NotImplementedException(); + } + public override int ItemCount { get @@ -181,13 +186,31 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider return new LibraryProviderFileSystem(Path.Combine(rootPath, collection.Key), collection.Name, this); } + public override void RenameCollection(int collectionIndexToRename, string newName) + { + string sourceDir = Path.Combine(rootPath, currentDirectoryDirectories[collectionIndexToRename]); + if (Directory.Exists(sourceDir)) + { + string destDir = Path.Combine(Path.GetDirectoryName(sourceDir), sourceDir); + Directory.Move(sourceDir, destDir); + Stopwatch time = Stopwatch.StartNew(); + // Wait for up to some amount of time for the directory to be gone. + while (Directory.Exists(destDir) + && time.ElapsedMilliseconds < 100) + { + Thread.Sleep(1); // make sure we are not eating all the cpu time. + } + GetFilesAndCollectionsInCurrentDirectory(); + } + } + public override void RemoveCollection(int collectionIndexToRemove) { string directoryPath = Path.Combine(rootPath, currentDirectoryDirectories[collectionIndexToRemove]); if (Directory.Exists(directoryPath)) { - Stopwatch time = Stopwatch.StartNew(); Directory.Delete(directoryPath, true); + Stopwatch time = Stopwatch.StartNew(); // Wait for up to some amount of time for the directory to be gone. while (Directory.Exists(directoryPath) && time.ElapsedMilliseconds < 100) diff --git a/Library/Provider/LibraryProviderHistory.cs b/Library/Provider/LibraryProviderHistory.cs new file mode 100644 index 000000000..a4cefc162 --- /dev/null +++ b/Library/Provider/LibraryProviderHistory.cs @@ -0,0 +1,349 @@ +/* +Copyright (c) 2015, 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 MatterHackers.Agg; +using MatterHackers.Agg.Image; +using MatterHackers.Agg.PlatformAbstract; +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.DataStorage; +using MatterHackers.MatterControl.PrintHistory; +using MatterHackers.MatterControl.PrintQueue; +using MatterHackers.MatterControl.SettingsManagement; +using MatterHackers.PolygonMesh; +using MatterHackers.PolygonMesh.Processors; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace MatterHackers.MatterControl.PrintLibrary.Provider +{ + public class LibraryProviderHistory : LibraryProvider + { + private static LibraryProviderHistory instance = null; + private PrintItemCollection baseLibraryCollection; + + private List childCollections = new List(); + private string keywordFilter = string.Empty; + + EventHandler unregisterEvent; + + public LibraryProviderHistory(PrintItemCollection baseLibraryCollection, LibraryProvider parentLibraryProvider) + : base(parentLibraryProvider) + { + this.baseLibraryCollection = baseLibraryCollection; + + //PrintHistoryData.Instance.ItemAdded.RegisterEvent((sender, e) => OnDataReloaded(null), ref unregisterEvent); + } + + public static LibraryProvider Instance + { + get + { + if (instance == null) + { + instance = new LibraryProviderHistory(null, null); + } + + return instance; + } + } + + public override string GetPrintItemName(int itemIndex) + { + return "item"; + //return PrintHistoryData.Instance.GetHistoryItem(itemIndex); + } + + public override void RenameCollection(int collectionIndexToRename, string newName) + { + throw new NotImplementedException(); + } + + public override void RenameItem(int itemIndexToRename, string newName) + { + throw new NotImplementedException(); + } + + public static string StaticProviderKey + { + get + { + return "LibraryProviderHistoryKey"; + } + } + + public override bool Visible + { + get { return true; } + } + + public override void Dispose() + { + } + + public override int CollectionCount + { + get + { + return 0; + } + } + + public override int ItemCount + { + get + { + return 10; + //return PrintHistoryData.Instance.Count; + } + } + + public override string KeywordFilter + { + get + { + return keywordFilter; + } + + set + { + keywordFilter = value; + } + } + + public override string Name + { + get + { + return "Print History"; + } + } + + public override string ProviderData + { + get + { + return baseLibraryCollection.Id.ToString(); + } + } + + public override string ProviderKey + { + get + { + return StaticProviderKey; + } + } + + static public void SaveToLibraryFolder(PrintItemWrapper printItemWrapper, List meshGroups, bool AbsolutePositioned) + { + string[] metaData = { "Created By", "MatterControl" }; + if (AbsolutePositioned) + { + metaData = new string[] { "Created By", "MatterControl", "BedPosition", "Absolute" }; + } + if (printItemWrapper.FileLocation.Contains(ApplicationDataStorage.Instance.ApplicationLibraryDataPath)) + { + MeshOutputSettings outputInfo = new MeshOutputSettings(MeshOutputSettings.OutputType.Binary, metaData); + MeshFileIo.Save(meshGroups, printItemWrapper.FileLocation, outputInfo); + } + else // save a copy to the library and update this to point at it + { + string fileName = Path.ChangeExtension(Path.GetRandomFileName(), ".amf"); + printItemWrapper.FileLocation = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, fileName); + + MeshOutputSettings outputInfo = new MeshOutputSettings(MeshOutputSettings.OutputType.Binary, metaData); + MeshFileIo.Save(meshGroups, printItemWrapper.FileLocation, outputInfo); + + printItemWrapper.PrintItem.Commit(); + + // let the queue know that the item has changed so it load the correct part + QueueData.Instance.SaveDefaultQueue(); + } + + printItemWrapper.OnFileHasChanged(); + } + + public override void AddCollectionToLibrary(string collectionName) + { + } + + public override void AddItem(PrintItemWrapper itemToAdd) + { + throw new NotImplementedException(); + //PrintHistoryData.Instance.AddItem(itemToAdd); + } + + public void AddItem(PrintItemWrapper item, int indexToInsert = -1) + { + throw new NotImplementedException(); + //PrintHistoryData.Instance.AddItem(item, indexToInsert); + } + + public override PrintItemCollection GetCollectionItem(int collectionIndex) + { + return childCollections[collectionIndex]; + } + + public async override Task GetPrintItemWrapperAsync(int index, ReportProgressRatio reportProgress = null) + { + throw new NotImplementedException(); + //return PrintHistoryData.Instance.GetPrintItemWrapper(index); + } + + public override LibraryProvider GetProviderForCollection(PrintItemCollection collection) + { + return new LibraryProviderHistory(collection, this); + } + + public override void RemoveCollection(int collectionIndexToRemove) + { + } + + public override void RemoveItem(int itemToRemoveIndex) + { + throw new NotImplementedException(); + //PrintHistoryData.Instance.RemoveAt(itemToRemoveIndex); + OnDataReloaded(null); + } + + private static void AddStlOrGcode(LibraryProviderHistory libraryToAddTo, string loadedFileName, string extension) + { + PrintItem printItem = new PrintItem(); + printItem.Name = Path.GetFileNameWithoutExtension(loadedFileName); + printItem.FileLocation = Path.GetFullPath(loadedFileName); + printItem.PrintItemCollectionID = libraryToAddTo.baseLibraryCollection.Id; + printItem.Commit(); + + if (MeshFileIo.ValidFileExtensions().Contains(extension)) + { + List meshToConvertAndSave = MeshFileIo.Load(loadedFileName); + + try + { + PrintItemWrapper printItemWrapper = new PrintItemWrapper(printItem, libraryToAddTo); + SaveToLibraryFolder(printItemWrapper, meshToConvertAndSave, false); + libraryToAddTo.AddItem(printItemWrapper); + } + catch (System.UnauthorizedAccessException) + { + UiThread.RunOnIdle(() => + { + //Do something special when unauthorized? + StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes, unauthorized access", "Unable to save"); + }); + } + catch + { + UiThread.RunOnIdle(() => + { + StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes.", "Unable to save"); + }); + } + } + else // it is not a mesh so just add it + { + PrintItemWrapper printItemWrapper = new PrintItemWrapper(printItem, libraryToAddTo); + if (false) + { + libraryToAddTo.AddItem(printItemWrapper); + } + else // save a copy to the library and update this to point at it + { + string sourceFileName = printItem.FileLocation; + string newFileName = Path.ChangeExtension(Path.GetRandomFileName(), Path.GetExtension(printItem.FileLocation)); + string destFileName = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, newFileName); + + File.Copy(sourceFileName, destFileName, true); + + printItemWrapper.FileLocation = destFileName; + printItemWrapper.PrintItem.Commit(); + + // let the queue know that the item has changed so it load the correct part + libraryToAddTo.AddItem(printItemWrapper); + } + } + } + + private IEnumerable GetChildCollections() + { + string query = string.Format("SELECT * FROM PrintItemCollection WHERE ParentCollectionID = {0} ORDER BY Name ASC;", baseLibraryCollection.Id); + IEnumerable result = (IEnumerable)Datastore.Instance.dbSQLite.Query(query); + return result; + } + + public IEnumerable GetLibraryItems(string keyphrase = null) + { + string query; + if (keyphrase == null) + { + query = string.Format("SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} ORDER BY Name ASC;", baseLibraryCollection.Id); + } + else + { + query = string.Format("SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} AND Name LIKE '%{1}%' ORDER BY Name ASC;", baseLibraryCollection.Id, keyphrase); + } + IEnumerable result = (IEnumerable)Datastore.Instance.dbSQLite.Query(query); + return result; + } + + private void loadFilesIntoLibraryBackgoundWorker_DoWork(IList fileList) + { + foreach (string loadedFileName in fileList) + { + string extension = Path.GetExtension(loadedFileName).ToUpper(); + if (MeshFileIo.ValidFileExtensions().Contains(extension) + || extension == ".GCODE" + || extension == ".ZIP") + { + if (extension == ".ZIP") + { + ProjectFileHandler project = new ProjectFileHandler(null); + List partFiles = project.ImportFromProjectArchive(loadedFileName); + if (partFiles != null) + { + foreach (PrintItem part in partFiles) + { + AddStlOrGcode(this, part.FileLocation, Path.GetExtension(part.FileLocation).ToUpper()); + } + } + } + else + { + AddStlOrGcode(this, loadedFileName, extension); + } + } + } + } + } +} \ No newline at end of file diff --git a/Library/Provider/LibraryProviderQueue.cs b/Library/Provider/LibraryProviderQueue.cs new file mode 100644 index 000000000..5ac8c48d1 --- /dev/null +++ b/Library/Provider/LibraryProviderQueue.cs @@ -0,0 +1,342 @@ +/* +Copyright (c) 2015, 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 MatterHackers.Agg; +using MatterHackers.Agg.Image; +using MatterHackers.Agg.PlatformAbstract; +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.DataStorage; +using MatterHackers.MatterControl.PrintQueue; +using MatterHackers.MatterControl.SettingsManagement; +using MatterHackers.PolygonMesh; +using MatterHackers.PolygonMesh.Processors; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace MatterHackers.MatterControl.PrintLibrary.Provider +{ + public class LibraryProviderQueue : LibraryProvider + { + private static LibraryProviderQueue instance = null; + private PrintItemCollection baseLibraryCollection; + + private List childCollections = new List(); + private string keywordFilter = string.Empty; + + EventHandler unregisterEvent; + + public LibraryProviderQueue(PrintItemCollection baseLibraryCollection, LibraryProvider parentLibraryProvider) + : base(parentLibraryProvider) + { + this.baseLibraryCollection = baseLibraryCollection; + + QueueData.Instance.ItemAdded.RegisterEvent((sender, e) => OnDataReloaded(null), ref unregisterEvent); + } + + public static LibraryProvider Instance + { + get + { + if (instance == null) + { + instance = new LibraryProviderQueue(null, null); + } + + return instance; + } + } + + public override string GetPrintItemName(int itemIndex) + { + return QueueData.Instance.GetItemName(itemIndex); + } + + public override void RenameCollection(int collectionIndexToRename, string newName) + { + throw new NotImplementedException(); + } + + public override void RenameItem(int itemIndexToRename, string newName) + { + throw new NotImplementedException(); + } + + public static string StaticProviderKey + { + get + { + return "LibraryProviderQueueKey"; + } + } + + public override bool Visible + { + get { return true; } + } + + public override void Dispose() + { + } + + public override int CollectionCount + { + get + { + return 0; + } + } + + public override int ItemCount + { + get + { + return QueueData.Instance.Count; + } + } + + public override string KeywordFilter + { + get + { + return keywordFilter; + } + + set + { + keywordFilter = value; + } + } + + public override string Name + { + get + { + return "Print Queue"; + } + } + + public override string ProviderData + { + get + { + return baseLibraryCollection.Id.ToString(); + } + } + + public override string ProviderKey + { + get + { + return StaticProviderKey; + } + } + + static public void SaveToLibraryFolder(PrintItemWrapper printItemWrapper, List meshGroups, bool AbsolutePositioned) + { + string[] metaData = { "Created By", "MatterControl" }; + if (AbsolutePositioned) + { + metaData = new string[] { "Created By", "MatterControl", "BedPosition", "Absolute" }; + } + if (printItemWrapper.FileLocation.Contains(ApplicationDataStorage.Instance.ApplicationLibraryDataPath)) + { + MeshOutputSettings outputInfo = new MeshOutputSettings(MeshOutputSettings.OutputType.Binary, metaData); + MeshFileIo.Save(meshGroups, printItemWrapper.FileLocation, outputInfo); + } + else // save a copy to the library and update this to point at it + { + string fileName = Path.ChangeExtension(Path.GetRandomFileName(), ".amf"); + printItemWrapper.FileLocation = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, fileName); + + MeshOutputSettings outputInfo = new MeshOutputSettings(MeshOutputSettings.OutputType.Binary, metaData); + MeshFileIo.Save(meshGroups, printItemWrapper.FileLocation, outputInfo); + + printItemWrapper.PrintItem.Commit(); + + // let the queue know that the item has changed so it load the correct part + QueueData.Instance.SaveDefaultQueue(); + } + + printItemWrapper.OnFileHasChanged(); + } + + public override void AddCollectionToLibrary(string collectionName) + { + } + + public override void AddItem(PrintItemWrapper itemToAdd) + { + QueueData.Instance.AddItem(itemToAdd); + } + + public void AddItem(PrintItemWrapper item, int indexToInsert = -1) + { + QueueData.Instance.AddItem(item, indexToInsert); + } + + public override PrintItemCollection GetCollectionItem(int collectionIndex) + { + return childCollections[collectionIndex]; + } + + public async override Task GetPrintItemWrapperAsync(int index, ReportProgressRatio reportProgress = null) + { + return QueueData.Instance.GetPrintItemWrapper(index); + } + + public override LibraryProvider GetProviderForCollection(PrintItemCollection collection) + { + return new LibraryProviderQueue(collection, this); + } + + public override void RemoveCollection(int collectionIndexToRemove) + { + } + + public override void RemoveItem(int itemToRemoveIndex) + { + QueueData.Instance.RemoveAt(itemToRemoveIndex); + OnDataReloaded(null); + } + + private static void AddStlOrGcode(LibraryProviderQueue libraryToAddTo, string loadedFileName, string extension) + { + PrintItem printItem = new PrintItem(); + printItem.Name = Path.GetFileNameWithoutExtension(loadedFileName); + printItem.FileLocation = Path.GetFullPath(loadedFileName); + printItem.PrintItemCollectionID = libraryToAddTo.baseLibraryCollection.Id; + printItem.Commit(); + + if (MeshFileIo.ValidFileExtensions().Contains(extension)) + { + List meshToConvertAndSave = MeshFileIo.Load(loadedFileName); + + try + { + PrintItemWrapper printItemWrapper = new PrintItemWrapper(printItem, libraryToAddTo); + SaveToLibraryFolder(printItemWrapper, meshToConvertAndSave, false); + libraryToAddTo.AddItem(printItemWrapper); + } + catch (System.UnauthorizedAccessException) + { + UiThread.RunOnIdle(() => + { + //Do something special when unauthorized? + StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes, unauthorized access", "Unable to save"); + }); + } + catch + { + UiThread.RunOnIdle(() => + { + StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes.", "Unable to save"); + }); + } + } + else // it is not a mesh so just add it + { + PrintItemWrapper printItemWrapper = new PrintItemWrapper(printItem, libraryToAddTo); + if (false) + { + libraryToAddTo.AddItem(printItemWrapper); + } + else // save a copy to the library and update this to point at it + { + string sourceFileName = printItem.FileLocation; + string newFileName = Path.ChangeExtension(Path.GetRandomFileName(), Path.GetExtension(printItem.FileLocation)); + string destFileName = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, newFileName); + + File.Copy(sourceFileName, destFileName, true); + + printItemWrapper.FileLocation = destFileName; + printItemWrapper.PrintItem.Commit(); + + // let the queue know that the item has changed so it load the correct part + libraryToAddTo.AddItem(printItemWrapper); + } + } + } + + private IEnumerable GetChildCollections() + { + string query = string.Format("SELECT * FROM PrintItemCollection WHERE ParentCollectionID = {0} ORDER BY Name ASC;", baseLibraryCollection.Id); + IEnumerable result = (IEnumerable)Datastore.Instance.dbSQLite.Query(query); + return result; + } + + public IEnumerable GetLibraryItems(string keyphrase = null) + { + string query; + if (keyphrase == null) + { + query = string.Format("SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} ORDER BY Name ASC;", baseLibraryCollection.Id); + } + else + { + query = string.Format("SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} AND Name LIKE '%{1}%' ORDER BY Name ASC;", baseLibraryCollection.Id, keyphrase); + } + IEnumerable result = (IEnumerable)Datastore.Instance.dbSQLite.Query(query); + return result; + } + + private void loadFilesIntoLibraryBackgoundWorker_DoWork(IList fileList) + { + foreach (string loadedFileName in fileList) + { + string extension = Path.GetExtension(loadedFileName).ToUpper(); + if (MeshFileIo.ValidFileExtensions().Contains(extension) + || extension == ".GCODE" + || extension == ".ZIP") + { + if (extension == ".ZIP") + { + ProjectFileHandler project = new ProjectFileHandler(null); + List partFiles = project.ImportFromProjectArchive(loadedFileName); + if (partFiles != null) + { + foreach (PrintItem part in partFiles) + { + AddStlOrGcode(this, part.FileLocation, Path.GetExtension(part.FileLocation).ToUpper()); + } + } + } + else + { + AddStlOrGcode(this, loadedFileName, extension); + } + } + } + } + } +} \ No newline at end of file diff --git a/Library/Provider/LibraryProviderSelector.cs b/Library/Provider/LibraryProviderSelector.cs index a58fe1fc6..6e19edb33 100644 --- a/Library/Provider/LibraryProviderSelector.cs +++ b/Library/Provider/LibraryProviderSelector.cs @@ -49,8 +49,6 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider private static LibraryProviderSelector instance = null; private List libraryProviders = new List(); - private List visibleProviders; - internal LibraryProvider PurchasedLibrary { get; private set; } private event EventHandler unregisterEvents; @@ -63,9 +61,18 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider ApplicationController.Instance.CloudSyncStatusChanged.RegisterEvent(CloudSyncStatusChanged, ref unregisterEvents); + // This is test code for how to add these when we get to it + // put in the queue provider + libraryProviders.Add(new LibraryProviderQueue(null, this)); + AddFolderImage("queue_folder.png"); + + // put in the queue provider + libraryProviders.Add(new LibraryProviderHistory(null, this)); + AddFolderImage("queue_folder.png"); + // */ + // put in the sqlite provider libraryProviders.Add(new LibraryProviderSQLite(null, this)); - AddFolderImage("library_folder.png"); // Check for LibraryProvider factories and put them in the list too. @@ -110,8 +117,16 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider private void FilterProviders() { - this.visibleProviders = libraryProviders.Where(p => p.Visible).ToList(); - OnDataReloaded(null); + } + + public override void RenameCollection(int collectionIndexToRename, string newName) + { + throw new NotImplementedException(); + } + + public override void RenameItem(int itemIndexToRename, string newName) + { + throw new NotImplementedException(); } public void CloudSyncStatusChanged(object sender, EventArgs eventArgs) @@ -156,7 +171,7 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider { get { - return this.visibleProviders.Count; + return this.libraryProviders.Count; } } @@ -212,17 +227,28 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider public override void AddCollectionToLibrary(string collectionName) { - throw new NotImplementedException(); + UiThread.RunOnIdle(() => + FileDialog.SelectFolderDialog(new SelectFolderDialogParams("Select Folder"), (SelectFolderDialogParams folderParams) => + { + libraryProviders.Add(new LibraryProviderFileSystem(folderParams.FolderPath, collectionName, this)); + AddFolderImage("folder.png"); + UiThread.RunOnIdle(() => OnDataReloaded(null)); + })); } public override void AddItem(PrintItemWrapper itemToAdd) { - throw new NotImplementedException(); + if (Directory.Exists(itemToAdd.FileLocation)) + { + libraryProviders.Add(new LibraryProviderFileSystem(itemToAdd.FileLocation, Path.GetFileName(itemToAdd.FileLocation), this)); + AddFolderImage("folder.png"); + UiThread.RunOnIdle(() => OnDataReloaded(null)); + } } public override PrintItemCollection GetCollectionItem(int collectionIndex) { - LibraryProvider provider = visibleProviders[collectionIndex]; + LibraryProvider provider = libraryProviders[collectionIndex]; return new PrintItemCollection(provider.Name, provider.ProviderKey); } @@ -233,7 +259,7 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider public override LibraryProvider GetProviderForCollection(PrintItemCollection collection) { - foreach (LibraryProvider libraryProvider in visibleProviders) + foreach (LibraryProvider libraryProvider in libraryProviders) { if (collection.Key == libraryProvider.ProviderKey) { diff --git a/Library/Provider/LibraryProviderSqlite.cs b/Library/Provider/LibraryProviderSqlite.cs index 48dfa7121..f94d76726 100644 --- a/Library/Provider/LibraryProviderSqlite.cs +++ b/Library/Provider/LibraryProviderSqlite.cs @@ -86,6 +86,16 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider return printItems[itemIndex].Name; } + public override void RenameCollection(int collectionIndexToRename, string newName) + { + throw new NotImplementedException(); + } + + public override void RenameItem(int itemIndexToRename, string newName) + { + throw new NotImplementedException(); + } + public static string StaticProviderKey { get @@ -307,7 +317,7 @@ namespace MatterHackers.MatterControl.PrintLibrary.Provider return new LibraryProviderSQLite(collection, this); } - public void LoadLibraryItems() + void LoadLibraryItems() { printItems.Clear(); IEnumerable partFiles = GetLibraryItems(KeywordFilter); diff --git a/Library/RenameItemWindow.cs b/Library/RenameItemWindow.cs new file mode 100644 index 000000000..a74b80b01 --- /dev/null +++ b/Library/RenameItemWindow.cs @@ -0,0 +1,164 @@ +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.CustomWidgets; +using MatterHackers.MatterControl.DataStorage; +using System; +using System.IO; + +namespace MatterHackers.MatterControl +{ + public class RenameItemWindow : SystemWindow + { + private Action functionToCallToCreateNamedFolder; + private TextImageButtonFactory textImageButtonFactory = new TextImageButtonFactory(); + private MHTextEditWidget folderNameWidget; + + public class RenameItemReturnInfo + { + public string newName; + + public RenameItemReturnInfo(string newName) + { + this.newName = newName; + } + } + + public RenameItemWindow(string currentItemName, Action functionToCallToRenameItem) + : base(480, 180) + { + Title = "MatterControl - Rename Item"; + AlwaysOnTopOfMain = true; + + this.functionToCallToCreateNamedFolder = functionToCallToRenameItem; + + FlowLayoutWidget topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom); + topToBottom.AnchorAll(); + topToBottom.Padding = new BorderDouble(3, 0, 3, 5); + + // Creates Header + FlowLayoutWidget headerRow = new FlowLayoutWidget(FlowDirection.LeftToRight); + headerRow.HAnchor = HAnchor.ParentLeftRight; + headerRow.Margin = new BorderDouble(0, 3, 0, 0); + headerRow.Padding = new BorderDouble(0, 3, 0, 3); + BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; + + //Creates Text and adds into header + { + string renameItemLabel = "Rename Item:".Localize(); + TextWidget elementHeader = new TextWidget(renameItemLabel, pointSize: 14); + elementHeader.TextColor = ActiveTheme.Instance.PrimaryTextColor; + elementHeader.HAnchor = HAnchor.ParentLeftRight; + elementHeader.VAnchor = Agg.UI.VAnchor.ParentBottom; + + headerRow.AddChild(elementHeader); + topToBottom.AddChild(headerRow); + this.AddChild(topToBottom); + } + + //Creates container in the middle of window + FlowLayoutWidget middleRowContainer = new FlowLayoutWidget(FlowDirection.TopToBottom); + { + middleRowContainer.HAnchor = HAnchor.ParentLeftRight; + middleRowContainer.VAnchor = VAnchor.ParentBottomTop; + middleRowContainer.Padding = new BorderDouble(5); + middleRowContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor; + } + + string fileNameLabel = "New Name".Localize(); + TextWidget textBoxHeader = new TextWidget(fileNameLabel, pointSize: 12); + textBoxHeader.TextColor = ActiveTheme.Instance.PrimaryTextColor; + textBoxHeader.Margin = new BorderDouble(5); + textBoxHeader.HAnchor = HAnchor.ParentLeft; + + //Adds text box and check box to the above container + folderNameWidget = new MHTextEditWidget(currentItemName, pixelWidth: 300, messageWhenEmptyAndNotSelected: "Enter New Name Here".Localize()); + folderNameWidget.HAnchor = HAnchor.ParentLeftRight; + folderNameWidget.Margin = new BorderDouble(5); + + middleRowContainer.AddChild(textBoxHeader); + middleRowContainer.AddChild(folderNameWidget); + middleRowContainer.AddChild(new HorizontalSpacer()); + topToBottom.AddChild(middleRowContainer); + + //Creates button container on the bottom of window + FlowLayoutWidget buttonRow = new FlowLayoutWidget(FlowDirection.LeftToRight); + { + BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; + buttonRow.HAnchor = HAnchor.ParentLeftRight; + buttonRow.Padding = new BorderDouble(0, 3); + } + + Button renameItemButton = textImageButtonFactory.Generate("Rename".Localize(), centerText: true); + renameItemButton.Visible = true; + renameItemButton.Cursor = Cursors.Hand; + buttonRow.AddChild(renameItemButton); + + renameItemButton.Click += new EventHandler(renameItemButton_Click); + folderNameWidget.ActualTextEditWidget.EnterPressed += new KeyEventHandler(ActualTextEditWidget_EnterPressed); + + //Adds Create and Close Button to button container + buttonRow.AddChild(new HorizontalSpacer()); + + Button cancelButton = textImageButtonFactory.Generate("Cancel".Localize(), centerText: true); + cancelButton.Visible = true; + cancelButton.Cursor = Cursors.Hand; + buttonRow.AddChild(cancelButton); + cancelButton.Click += (sender, e) => + { + CloseOnIdle(); + }; + + topToBottom.AddChild(buttonRow); + + ShowAsSystemWindow(); + } + + bool firstDraw = true; + public override void OnDraw(Graphics2D graphics2D) + { + if (firstDraw) + { + folderNameWidget.Focus(); + folderNameWidget.ActualTextEditWidget.InternalTextEditWidget.SelectAll(); + + firstDraw = false; + } + base.OnDraw(graphics2D); + } + + private void ActualTextEditWidget_EnterPressed(object sender, KeyEventArgs keyEvent) + { + SubmitForm(); + } + + private void renameItemButton_Click(object sender, EventArgs mouseEvent) + { + SubmitForm(); + } + + private void SubmitForm() + { + string newName = folderNameWidget.ActualTextEditWidget.Text; + if (newName != "") + { + string fileName = Path.ChangeExtension(Path.GetRandomFileName(), ".amf"); + string fileNameAndPath = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, fileName); + + RenameItemReturnInfo returnInfo = new RenameItemReturnInfo(newName); + functionToCallToCreateNamedFolder(returnInfo); + CloseOnIdle(); + } + } + + public class CreateFolderReturnInfo + { + public string newName; + + public CreateFolderReturnInfo(string newName) + { + this.newName = newName; + } + } + } +} \ No newline at end of file diff --git a/MatterControl.csproj b/MatterControl.csproj index 5039b57ca..890ef6d7e 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -168,6 +168,9 @@ + + + diff --git a/Queue/QueueData.cs b/Queue/QueueData.cs index 355a5fc8c..2ed6f559e 100644 --- a/Queue/QueueData.cs +++ b/Queue/QueueData.cs @@ -204,6 +204,11 @@ namespace MatterHackers.MatterControl.PrintQueue return itemNames.ToArray(); } + public string GetItemName(int itemIndex) + { + return PrintItems[itemIndex].Name; + } + private bool gotBeginFileList = false; private event EventHandler unregisterEvents; diff --git a/StaticData/Icons/FileDialog/queue_folder.png b/StaticData/Icons/FileDialog/queue_folder.png new file mode 100644 index 000000000..38b95cc72 Binary files /dev/null and b/StaticData/Icons/FileDialog/queue_folder.png differ