From 3e66187afab8e96dde12e95d2f260898346397b5 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sat, 7 Oct 2017 10:19:54 -0700 Subject: [PATCH 01/19] Use self rather than static to self --- MatterControlApplication.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 4afc00372..b8c9ced24 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -523,9 +523,8 @@ namespace MatterHackers.MatterControl ApplicationController.Instance.ActivePrinter.Connection.Disable(); } - MatterControlApplication app = MatterControlApplication.Instance; - app.RestartOnClose = false; - app.Close(); + this.RestartOnClose = false; + this.Close(); } } From cbe63e9ee3007d833194e44fb0df7663d3655ce9 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sat, 7 Oct 2017 10:24:50 -0700 Subject: [PATCH 02/19] Refactor for clarity --- MatterControlApplication.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index b8c9ced24..c9aa030bb 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -510,17 +510,25 @@ namespace MatterHackers.MatterControl bool closeMessageBoxIsOpen = false; private void ConditionalyCloseNow(bool continueWithShutdown) { - // Response received, cecord that we are not waiting anymore. + // Response received, record that we are not waiting anymore. closeMessageBoxIsOpen = false; + + // Exit if confirmed if (continueWithShutdown) { closeHasBeenConfirmed = true; - bool printingFromSdCard = ApplicationController.Instance.ActivePrinter.Connection.CommunicationState == CommunicationStates.PrintingFromSd - || (ApplicationController.Instance.ActivePrinter.Connection.CommunicationState == CommunicationStates.Paused - && ApplicationController.Instance.ActivePrinter.Connection.PrePauseCommunicationState == CommunicationStates.PrintingFromSd); - if (!printingFromSdCard) + + // Always call PrinterConnection.Disable on exit unless PrintingFromSd + PrinterConnection printerConnection = ApplicationController.Instance.ActivePrinter.Connection; + switch(printerConnection.CommunicationState) { - ApplicationController.Instance.ActivePrinter.Connection.Disable(); + case CommunicationStates.PrintingFromSd: + case CommunicationStates.Paused when printerConnection.PrePauseCommunicationState == CommunicationStates.PrintingFromSd: + break; + + default: + printerConnection.Disable(); + break; } this.RestartOnClose = false; From e7b721e063ea01084c530deeec03961a356d41a8 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sat, 7 Oct 2017 10:48:19 -0700 Subject: [PATCH 03/19] More clearly depict unused and discarded out variable --- MatterControlApplication.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index c9aa030bb..52cceef57 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -752,10 +752,9 @@ namespace MatterHackers.MatterControl private void onConfirmExit(bool messageBoxResponse) { - bool CancelClose; if (messageBoxResponse) { - base.OnClosing(out CancelClose); + base.OnClosing(out _); } } From 35bca112f8be0ce8ec6b4a812796fae8f79995e4 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sat, 7 Oct 2017 10:53:26 -0700 Subject: [PATCH 04/19] Inline callback to better depict behavior and its discarded out --- MatterControlApplication.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 52cceef57..94ed1161c 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -497,7 +497,17 @@ namespace MatterHackers.MatterControl } else if (PartsSheet.IsSaving()) { - StyledMessageBox.ShowMessageBox(onConfirmExit, savePartsSheetExitAnywayMessage, confirmExit, StyledMessageBox.MessageType.YES_NO); + StyledMessageBox.ShowMessageBox( + (exitAnyway) => + { + if (exitAnyway) + { + base.OnClosing(out _); + } + }, + savePartsSheetExitAnywayMessage, + confirmExit, + StyledMessageBox.MessageType.YES_NO); cancelClose = true; } else if(!cancelClose) // only check if we have not already canceled @@ -750,14 +760,6 @@ namespace MatterHackers.MatterControl } } - private void onConfirmExit(bool messageBoxResponse) - { - if (messageBoxResponse) - { - base.OnClosing(out _); - } - } - private static void AssertDebugNotDefined() { #if DEBUG From 6a767faf26df4db4e358b9ad18e7b8eb58a192aa Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sat, 7 Oct 2017 11:02:22 -0700 Subject: [PATCH 05/19] Remove non-production code --- MatterControlApplication.cs | 79 +--------------- .../MatterControl.Tests.csproj | 1 + .../MatterControl.Tests/RemovedFromProduct.cs | 92 +++++++++++++++++++ 3 files changed, 95 insertions(+), 77 deletions(-) create mode 100644 Tests/MatterControl.Tests/RemovedFromProduct.cs diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 94ed1161c..5ef23deac 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -378,38 +378,6 @@ namespace MatterHackers.MatterControl return instance; } - public static void WriteTestGCodeFile() - { - using (StreamWriter file = new StreamWriter("PerformanceTest.gcode")) - { - //int loops = 150000; - int loops = 150; - int steps = 200; - double radius = 50; - Vector2 center = new Vector2(150, 100); - - file.WriteLine("G28 ; home all axes"); - file.WriteLine("G90 ; use absolute coordinates"); - file.WriteLine("G21 ; set units to millimeters"); - file.WriteLine("G92 E0"); - file.WriteLine("G1 F7800"); - file.WriteLine("G1 Z" + (5).ToString()); - WriteMove(file, center); - - for (int loop = 0; loop < loops; loop++) - { - for (int step = 0; step < steps; step++) - { - Vector2 nextPosition = new Vector2(radius, 0); - nextPosition.Rotate(MathHelper.Tau / steps * step); - WriteMove(file, center + nextPosition); - } - } - - file.WriteLine("M84 ; disable motors"); - } - } - public void LaunchBrowser(string targetUri) { UiThread.RunOnIdle(() => @@ -517,7 +485,8 @@ namespace MatterHackers.MatterControl } bool closeHasBeenConfirmed = false; - bool closeMessageBoxIsOpen = false; + internal bool closeMessageBoxIsOpen = false; + private void ConditionalyCloseNow(bool continueWithShutdown) { // Response received, record that we are not waiting anymore. @@ -607,44 +576,6 @@ namespace MatterHackers.MatterControl base.OnLoad(args); } - private static void HtmlWindowTest() - { - try - { - SystemWindow htmlTestWindow = new SystemWindow(640, 480); - string htmlContent = ""; - if (true) - { - string releaseNotesFile = Path.Combine("C:\\Users\\lbrubaker\\Downloads", "test1.html"); - htmlContent = File.ReadAllText(releaseNotesFile); - } - else - { - WebClient webClient = new WebClient(); - htmlContent = webClient.DownloadString("http://www.matterhackers.com/s/store?q=pla"); - } - - HtmlWidget content = new HtmlWidget(htmlContent, RGBA_Bytes.Black); - content.AddChild(new GuiWidget() - { - HAnchor = HAnchor.Absolute, - VAnchor = VAnchor.Stretch - }); - content.VAnchor |= VAnchor.Top; - content.BackgroundColor = RGBA_Bytes.White; - htmlTestWindow.AddChild(content); - htmlTestWindow.BackgroundColor = RGBA_Bytes.Cyan; - UiThread.RunOnIdle((state) => - { - htmlTestWindow.ShowAsSystemWindow(); - }, 1); - } - catch - { - int stop = 1; - } - } - public override void OnMouseMove(MouseEventArgs mouseEvent) { // run this first to make sure a child has the chance to take the drag drop event @@ -700,11 +631,6 @@ namespace MatterHackers.MatterControl } } - private static void WriteMove(StreamWriter file, Vector2 center) - { - file.WriteLine("G1 X" + center.x.ToString() + " Y" + center.y.ToString()); - } - private void CheckOnPrinter() { try @@ -788,4 +714,3 @@ namespace MatterHackers.MatterControl } } } - diff --git a/Tests/MatterControl.Tests/MatterControl.Tests.csproj b/Tests/MatterControl.Tests/MatterControl.Tests.csproj index dc26bddab..e399af631 100644 --- a/Tests/MatterControl.Tests/MatterControl.Tests.csproj +++ b/Tests/MatterControl.Tests/MatterControl.Tests.csproj @@ -77,6 +77,7 @@ + diff --git a/Tests/MatterControl.Tests/RemovedFromProduct.cs b/Tests/MatterControl.Tests/RemovedFromProduct.cs new file mode 100644 index 000000000..559de0516 --- /dev/null +++ b/Tests/MatterControl.Tests/RemovedFromProduct.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl; +using MatterHackers.VectorMath; + +namespace MatterControl.Tests +{ + class RemovedFromProduct + { + public static void WriteTestGCodeFile() + { + using (StreamWriter file = new StreamWriter("PerformanceTest.gcode")) + { + //int loops = 150000; + int loops = 150; + int steps = 200; + double radius = 50; + Vector2 center = new Vector2(150, 100); + + file.WriteLine("G28 ; home all axes"); + file.WriteLine("G90 ; use absolute coordinates"); + file.WriteLine("G21 ; set units to millimeters"); + file.WriteLine("G92 E0"); + file.WriteLine("G1 F7800"); + file.WriteLine("G1 Z" + (5).ToString()); + WriteMove(file, center); + + for (int loop = 0; loop < loops; loop++) + { + for (int step = 0; step < steps; step++) + { + Vector2 nextPosition = new Vector2(radius, 0); + nextPosition.Rotate(MathHelper.Tau / steps * step); + WriteMove(file, center + nextPosition); + } + } + + file.WriteLine("M84 ; disable motors"); + } + } + + private static void WriteMove(StreamWriter file, Vector2 center) + { + file.WriteLine("G1 X" + center.x.ToString() + " Y" + center.y.ToString()); + } + + private static void HtmlWindowTest() + { + try + { + SystemWindow htmlTestWindow = new SystemWindow(640, 480); + string htmlContent = ""; + if (true) + { + string releaseNotesFile = Path.Combine("C:\\Users\\lbrubaker\\Downloads", "test1.html"); + htmlContent = File.ReadAllText(releaseNotesFile); + } + else + { + WebClient webClient = new WebClient(); + htmlContent = webClient.DownloadString("http://www.matterhackers.com/s/store?q=pla"); + } + + HtmlWidget content = new HtmlWidget(htmlContent, RGBA_Bytes.Black); + content.AddChild(new GuiWidget() + { + HAnchor = HAnchor.Absolute, + VAnchor = VAnchor.Stretch + }); + content.VAnchor |= VAnchor.Top; + content.BackgroundColor = RGBA_Bytes.White; + htmlTestWindow.AddChild(content); + htmlTestWindow.BackgroundColor = RGBA_Bytes.Cyan; + UiThread.RunOnIdle((state) => + { + htmlTestWindow.ShowAsSystemWindow(); + }, 1); + } + catch + { + int stop = 1; + } + } + } +} From 80c5a4f1380fbe0477b324899c3f53d076109c3b Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sat, 7 Oct 2017 11:16:36 -0700 Subject: [PATCH 06/19] Revise naming around Application Exit due to similarity to Closing --- MatterControlApplication.cs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 5ef23deac..e11df75b6 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -433,23 +433,23 @@ namespace MatterHackers.MatterControl QueueData.Instance.SaveDefaultQueue(); // If we are waiting for a response and get another request, just cancel the close until we get a response. - if(closeMessageBoxIsOpen) + if(exitDialogOpen) { cancelClose = true; } - if (!closeHasBeenConfirmed - && !closeMessageBoxIsOpen + if (!ApplicationExiting + && !exitDialogOpen && ApplicationController.Instance.ActivePrinter.Connection.PrinterIsPrinting) { cancelClose = true; // Record that we are waiting for a response to the request to close - closeMessageBoxIsOpen = true; + exitDialogOpen = true; if (ApplicationController.Instance.ActivePrinter.Connection.CommunicationState != CommunicationStates.PrintingFromSd) { // Needed as we can't assign to CancelClose inside of the lambda below - StyledMessageBox.ShowMessageBox(ConditionalyCloseNow, + StyledMessageBox.ShowMessageBox(ConditionalExit, "Are you sure you want to abort the current print and close MatterControl?".Localize(), "Abort Print".Localize(), StyledMessageBox.MessageType.YES_NO); @@ -457,7 +457,7 @@ namespace MatterHackers.MatterControl else { StyledMessageBox.ShowMessageBox( - ConditionalyCloseNow, + ConditionalExit, "Are you sure you want exit while a print is running from SD Card?\n\nNote: If you exit, it is recommended you wait until the print is completed before running MatterControl again.".Localize(), "Exit while printing".Localize(), StyledMessageBox.MessageType.YES_NO); @@ -484,18 +484,19 @@ namespace MatterHackers.MatterControl } } - bool closeHasBeenConfirmed = false; - internal bool closeMessageBoxIsOpen = false; + public bool ApplicationExiting { get; private set; } = false; - private void ConditionalyCloseNow(bool continueWithShutdown) + private bool exitDialogOpen = false; + + private void ConditionalExit(bool exitConfirmed) { - // Response received, record that we are not waiting anymore. - closeMessageBoxIsOpen = false; + // Record that the exitDialog has closed + exitDialogOpen = false; - // Exit if confirmed - if (continueWithShutdown) + // Continue with shutdown if exit confirmed by user + if (exitConfirmed) { - closeHasBeenConfirmed = true; + this.ApplicationExiting = true; // Always call PrinterConnection.Disable on exit unless PrintingFromSd PrinterConnection printerConnection = ApplicationController.Instance.ActivePrinter.Connection; From f996723a4b977b45da7b0366df79ab580b495c4d Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 8 Oct 2017 07:52:58 -0700 Subject: [PATCH 07/19] Rename variable to match behavior --- Library/Widgets/ListView/ListView.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Library/Widgets/ListView/ListView.cs b/Library/Widgets/ListView/ListView.cs index 8e44e01c6..54a96345f 100644 --- a/Library/Widgets/ListView/ListView.cs +++ b/Library/Widgets/ListView/ListView.cs @@ -48,6 +48,11 @@ namespace MatterHackers.MatterControl.CustomWidgets internal GuiWidget contentView; + /// + /// The GuiWidget responsible for rendering ListViewItems + /// + private GuiWidget previousContentView = null; + private ILibraryContext LibraryContext; // Default constructor uses IconListView @@ -83,8 +88,6 @@ namespace MatterHackers.MatterControl.CustomWidgets public RGBA_Bytes ThumbnailBackground { get; } = ActiveTheme.Instance.TertiaryBackgroundColor.AdjustLightness(1.05).GetAsRGBA_Bytes(); public RGBA_Bytes ThumbnailForeground { get; set; } = ActiveTheme.Instance.PrimaryAccentColor; - private GuiWidget stashedView = null; - private void ActiveContainer_Changed(object sender, ContainerChangedEventArgs e) { var activeContainer = e.ActiveContainer; @@ -93,7 +96,7 @@ namespace MatterHackers.MatterControl.CustomWidgets if (targetType != null && targetType != this.ListContentView.GetType()) { - stashedView = this.contentView; + previousContentView = this.contentView; // If the current view doesn't match the view requested by the container, construct and switch to the requested view var targetView = Activator.CreateInstance(targetType) as GuiWidget; @@ -102,11 +105,11 @@ namespace MatterHackers.MatterControl.CustomWidgets this.SetContentView(targetView); } } - else if (stashedView != null) + else if (previousContentView != null) { // Switch back to the original view - this.SetContentView(stashedView); - stashedView = null; + this.SetContentView(previousContentView); + previousContentView = null; } DisplayContainerContent(activeContainer); From 2bbd6b5423569ab7ba3e367e2968fddaff779ad3 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 8 Oct 2017 09:21:47 -0700 Subject: [PATCH 08/19] Remove unused type --- Library/Providers/CreatorsContainer.cs | 43 -------------------------- MatterControl.csproj | 1 - 2 files changed, 44 deletions(-) delete mode 100644 Library/Providers/CreatorsContainer.cs diff --git a/Library/Providers/CreatorsContainer.cs b/Library/Providers/CreatorsContainer.cs deleted file mode 100644 index 9ee4236d0..000000000 --- a/Library/Providers/CreatorsContainer.cs +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (c) 2017, 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. -*/ - - -namespace MatterHackers.MatterControl.Library -{ - public class CreatorsContainer : LibraryContainer - { - public CreatorsContainer() - { - } - - public override void Dispose() - { - } - } -} diff --git a/MatterControl.csproj b/MatterControl.csproj index eca11cc9a..e1129cf93 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -197,7 +197,6 @@ - From 06aa27d426dbc2189979b8f5f0910bf3d4201fbc Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 8 Oct 2017 09:54:22 -0700 Subject: [PATCH 09/19] Rename HistoryRowItem -> PrintHistoryItem --- History/PrintHistoryListItem.cs | 2 +- Library/Providers/MatterControl/HistoryContainer.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/History/PrintHistoryListItem.cs b/History/PrintHistoryListItem.cs index a0b721a95..412684e69 100644 --- a/History/PrintHistoryListItem.cs +++ b/History/PrintHistoryListItem.cs @@ -53,7 +53,7 @@ namespace MatterHackers.MatterControl.PrintHistory public ListViewItemBase AddItem(ListViewItem item) { - var historyRowItem = item.Model as HistoryRowItem; + var historyRowItem = item.Model as PrintHistoryItem; var detailsView = new PrintHistoryListItem(item, this.ThumbWidth, this.ThumbHeight, historyRowItem?.PrintTask, true); this.AddChild(detailsView); diff --git a/Library/Providers/MatterControl/HistoryContainer.cs b/Library/Providers/MatterControl/HistoryContainer.cs index 8e24bf9f7..1f0d07add 100644 --- a/Library/Providers/MatterControl/HistoryContainer.cs +++ b/Library/Providers/MatterControl/HistoryContainer.cs @@ -38,9 +38,9 @@ using MatterHackers.MatterControl.PrintHistory; namespace MatterHackers.MatterControl.Library { - public class HistoryRowItem : ILibraryContentStream + public class PrintHistoryItem : ILibraryContentStream { - public HistoryRowItem(PrintTask printTask) + public PrintHistoryItem(PrintTask printTask) { this.PrintTask = printTask; } @@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.Library public bool IsVisible => true; public bool LocalContentExists => true; - + public Task GetContentStream(Action reportProgress) { throw new NotImplementedException(); @@ -81,7 +81,7 @@ namespace MatterHackers.MatterControl.Library this.DefaultView = typeof(HistoryListView); //PrintHistoryData.Instance.ItemAdded.RegisterEvent((sender, e) => OnDataReloaded(null), ref unregisterEvent); - + this.ReloadContainer(); } @@ -92,7 +92,7 @@ namespace MatterHackers.MatterControl.Library var printHistory = PrintHistoryData.Instance.GetHistoryItems(25); // PrintItems projected onto FileSystemFileItem - Items = printHistory.Select(f => new HistoryRowItem(f)).ToList(); + Items = printHistory.Select(f => new PrintHistoryItem(f)).ToList(); UiThread.RunOnIdle(this.OnReloaded); }); From 153162ac5e84b50d32af9267d6d96bd655d8fd1f Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 8 Oct 2017 09:55:41 -0700 Subject: [PATCH 10/19] Extract embedded type to new file --- .../MatterControl/HistoryContainer.cs | 35 ---------- .../MatterControl/PrintHistoryItem.cs | 68 +++++++++++++++++++ MatterControl.csproj | 1 + 3 files changed, 69 insertions(+), 35 deletions(-) create mode 100644 Library/Providers/MatterControl/PrintHistoryItem.cs diff --git a/Library/Providers/MatterControl/HistoryContainer.cs b/Library/Providers/MatterControl/HistoryContainer.cs index 1f0d07add..a1f93d085 100644 --- a/Library/Providers/MatterControl/HistoryContainer.cs +++ b/Library/Providers/MatterControl/HistoryContainer.cs @@ -27,50 +27,15 @@ 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.Linq; using System.Threading.Tasks; using MatterHackers.Agg.UI; using MatterHackers.Localizations; -using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.PrintHistory; namespace MatterHackers.MatterControl.Library { - public class PrintHistoryItem : ILibraryContentStream - { - public PrintHistoryItem(PrintTask printTask) - { - this.PrintTask = printTask; - } - - public PrintTask PrintTask { get; } - - public long FileSize => 0; - - public string ContentType => ""; - - public string FileName => ""; - - public string AssetPath => ""; - - public string ID { get; } = Guid.NewGuid().ToString(); - - public string Name => this.PrintTask.PrintName; - - public bool IsProtected => true; - - public bool IsVisible => true; - - public bool LocalContentExists => true; - - public Task GetContentStream(Action reportProgress) - { - throw new NotImplementedException(); - } - } - public class HistoryContainer : LibraryContainer { public HistoryContainer() diff --git a/Library/Providers/MatterControl/PrintHistoryItem.cs b/Library/Providers/MatterControl/PrintHistoryItem.cs new file mode 100644 index 000000000..933e09382 --- /dev/null +++ b/Library/Providers/MatterControl/PrintHistoryItem.cs @@ -0,0 +1,68 @@ +/* +Copyright (c) 2017, 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.Threading.Tasks; +using MatterHackers.MatterControl.DataStorage; + +namespace MatterHackers.MatterControl.Library +{ + public class PrintHistoryItem : ILibraryContentStream + { + public PrintHistoryItem(PrintTask printTask) + { + this.PrintTask = printTask; + } + + public PrintTask PrintTask { get; } + + public long FileSize => 0; + + public string ContentType => ""; + + public string FileName => ""; + + public string AssetPath => ""; + + public string ID { get; } = Guid.NewGuid().ToString(); + + public string Name => this.PrintTask.PrintName; + + public bool IsProtected => true; + + public bool IsVisible => true; + + public bool LocalContentExists => true; + + public Task GetContentStream(Action reportProgress) + { + throw new NotImplementedException(); + } + } +} diff --git a/MatterControl.csproj b/MatterControl.csproj index e1129cf93..83c24c150 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -150,6 +150,7 @@ + From ebdbd5b53dfeaf2cf311260d945f6cb31a99eb43 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 8 Oct 2017 10:04:18 -0700 Subject: [PATCH 11/19] Rename HistoryContainer -> PrintHistoryContainer --- .../{HistoryContainer.cs => PrintHistoryContainer.cs} | 4 ++-- MatterControl.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename Library/Providers/MatterControl/{HistoryContainer.cs => PrintHistoryContainer.cs} (96%) diff --git a/Library/Providers/MatterControl/HistoryContainer.cs b/Library/Providers/MatterControl/PrintHistoryContainer.cs similarity index 96% rename from Library/Providers/MatterControl/HistoryContainer.cs rename to Library/Providers/MatterControl/PrintHistoryContainer.cs index a1f93d085..26d7c667b 100644 --- a/Library/Providers/MatterControl/HistoryContainer.cs +++ b/Library/Providers/MatterControl/PrintHistoryContainer.cs @@ -36,9 +36,9 @@ using MatterHackers.MatterControl.PrintHistory; namespace MatterHackers.MatterControl.Library { - public class HistoryContainer : LibraryContainer + public class PrintHistoryContainer : LibraryContainer { - public HistoryContainer() + public PrintHistoryContainer() { this.ChildContainers = new List(); this.Items = new List(); diff --git a/MatterControl.csproj b/MatterControl.csproj index 83c24c150..f89fa1596 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -150,6 +150,7 @@ + @@ -206,7 +207,6 @@ - From 37b539f89d6858b51d4f94a7d9f9584be06c702c Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 8 Oct 2017 19:35:49 -0700 Subject: [PATCH 12/19] Whitespace --- Library/Providers/FileSystem/FileSystemContainer.cs | 2 +- Library/Providers/LibraryConfig.cs | 8 +------- Library/Providers/MatterControl/SqliteLibraryContainer.cs | 3 +-- Library/Providers/Zip/LocalZipContainerLink.cs | 2 +- Library/Providers/Zip/ZipMemoryItem.cs | 2 +- Library/Widgets/ListView/ListView.cs | 1 - Library/Widgets/PrintLibraryWidget.cs | 1 - .../MatterControl/SliceSettingsFieldTests.cs | 1 - 8 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Library/Providers/FileSystem/FileSystemContainer.cs b/Library/Providers/FileSystem/FileSystemContainer.cs index 7713e3465..5243b4505 100644 --- a/Library/Providers/FileSystem/FileSystemContainer.cs +++ b/Library/Providers/FileSystem/FileSystemContainer.cs @@ -176,7 +176,7 @@ namespace MatterHackers.MatterControl.Library return FileNameContainsFilter(filePath, filter) && ApplicationController.Instance.Library.IsContentFileType(fileName); }); - + UiThread.RunOnIdle(() => { // Matched containers diff --git a/Library/Providers/LibraryConfig.cs b/Library/Providers/LibraryConfig.cs index ba7267f27..58dc7bb08 100644 --- a/Library/Providers/LibraryConfig.cs +++ b/Library/Providers/LibraryConfig.cs @@ -65,7 +65,7 @@ namespace MatterHackers.MatterControl.Library private List libraryProviders; private ILibraryContainer activeContainer; - + public LibraryConfig() { libraryProviders = new List(); @@ -149,12 +149,6 @@ namespace MatterHackers.MatterControl.Library OnLibraryItemsChanged(); } - public void RegisterCreator(ILibraryContainerLink containerItem) - { - this.RootLibaryContainer.ChildContainers.Add(containerItem); - OnLibraryItemsChanged(); - } - public void RegisterCreator(ILibraryContentItem libraryItem) { this.RootLibaryContainer.Items.Add(libraryItem); diff --git a/Library/Providers/MatterControl/SqliteLibraryContainer.cs b/Library/Providers/MatterControl/SqliteLibraryContainer.cs index d74813f88..b8cfaef41 100644 --- a/Library/Providers/MatterControl/SqliteLibraryContainer.cs +++ b/Library/Providers/MatterControl/SqliteLibraryContainer.cs @@ -126,7 +126,6 @@ namespace MatterHackers.MatterControl.Library { await Task.Run(async () => { - foreach (var item in items) { switch (item) @@ -354,7 +353,7 @@ namespace MatterHackers.MatterControl.Library public bool IsProtected { get; set; } = false; public bool IsReadOnly { get; set; } = false; - + public bool IsVisible { get; set; } = true; public Task GetContainer(Action reportProgress) diff --git a/Library/Providers/Zip/LocalZipContainerLink.cs b/Library/Providers/Zip/LocalZipContainerLink.cs index efa9babe6..18260f4e5 100644 --- a/Library/Providers/Zip/LocalZipContainerLink.cs +++ b/Library/Providers/Zip/LocalZipContainerLink.cs @@ -66,7 +66,7 @@ namespace MatterHackers.MatterControl.Library this.Name = currentDirectory.Split('/').Last(); } } - + public Task GetContainer(Action reportProgress) { return Task.FromResult(new ZipMemoryContainer(this.currentDirectory, this.Path)); diff --git a/Library/Providers/Zip/ZipMemoryItem.cs b/Library/Providers/Zip/ZipMemoryItem.cs index 29e18b79b..c5051854f 100644 --- a/Library/Providers/Zip/ZipMemoryItem.cs +++ b/Library/Providers/Zip/ZipMemoryItem.cs @@ -50,7 +50,7 @@ namespace MatterHackers.MatterControl.Library public string RelativePath { get; set; } public string ContentType => System.IO.Path.GetExtension(this.Name).ToLower().Trim('.'); - + public string AssetPath { get; } = null; public string FileName => System.IO.Path.GetFileName(this.Name); diff --git a/Library/Widgets/ListView/ListView.cs b/Library/Widgets/ListView/ListView.cs index 54a96345f..e9b34d4c8 100644 --- a/Library/Widgets/ListView/ListView.cs +++ b/Library/Widgets/ListView/ListView.cs @@ -380,4 +380,3 @@ namespace MatterHackers.MatterControl.CustomWidgets } } } - \ No newline at end of file diff --git a/Library/Widgets/PrintLibraryWidget.cs b/Library/Widgets/PrintLibraryWidget.cs index cc8aad374..003cfdc89 100644 --- a/Library/Widgets/PrintLibraryWidget.cs +++ b/Library/Widgets/PrintLibraryWidget.cs @@ -241,7 +241,6 @@ namespace MatterHackers.MatterControl.PrintLibrary var activeContainer = this.libraryView.ActiveContainer; - var writableContainer = activeContainer as ILibraryWritableContainer; bool containerSupportsEdits = activeContainer is ILibraryWritableContainer; diff --git a/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs b/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs index 51df1ce25..740c6b891 100644 --- a/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs @@ -77,7 +77,6 @@ namespace MatterControl.Tests.MatterControl // Find and validate all UIField types, skipping abstract classes foreach (var fieldType in PluginFinder.FindTypes().Where(fieldType => !fieldType.IsAbstract)) { - if (fieldType.Name == "UIField") { continue; From 5bb26006c6701f9c92cde87c5f03b5e6ce3e7e78 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 07:50:47 -0700 Subject: [PATCH 13/19] Clearing model should clear associated widgets --- Library/Widgets/ListView/IconListView.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Widgets/ListView/IconListView.cs b/Library/Widgets/ListView/IconListView.cs index 8066cbf86..130c9aee9 100644 --- a/Library/Widgets/ListView/IconListView.cs +++ b/Library/Widgets/ListView/IconListView.cs @@ -150,6 +150,8 @@ namespace MatterHackers.MatterControl.CustomWidgets cellIndex = 0; rowButtonContainer = null; allIconViews.Clear(); + + this.CloseAllChildren(); } } From 0928efb72997fe71fd6e1b6493d80d7e75577b9f Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 07:55:09 -0700 Subject: [PATCH 14/19] Fix typo, account for HistoryContainer name change --- ApplicationView/ApplicationController.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 201da4d6b..3ba76f183 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -343,20 +343,18 @@ namespace MatterHackers.MatterControl var rootLibraryCollection = Datastore.Instance.dbSQLite.Table().Where(v => v.Name == "_library").Take(1).FirstOrDefault(); if (rootLibraryCollection != null) { - int rooteLibraryID = rootLibraryCollection.Id; - this.Library.RegisterRootProvider( new DynamicContainerLink( "Local Library".Localize(), LibraryProviderHelpers.LoadInvertIcon("FileDialog", "library_folder.png"), - () => new SqliteLibraryContainer(rooteLibraryID))); + () => new SqliteLibraryContainer(rootLibraryCollection.Id))); } this.Library.RegisterRootProvider( new DynamicContainerLink( "Print History".Localize(), LibraryProviderHelpers.LoadInvertIcon("FileDialog", "folder.png"), - () => new HistoryContainer()) + () => new PrintHistoryContainer()) { IsReadOnly = true }); From dd60e0320e027631cf7ab647c2228f1b6b68c946 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 07:58:32 -0700 Subject: [PATCH 15/19] Only shutdown ThumbGenerator thread on exit, release to exit gracefully --- ApplicationView/ApplicationController.cs | 21 +++++++++++++++------ MatterControlApplication.cs | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 3ba76f183..cf166e00a 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -195,8 +195,7 @@ namespace MatterHackers.MatterControl { lock(thumbsLock) { - if (thumbnailGenerator == null - || thumbnailGenerator.IsCompleted) + if (thumbnailGenerator == null) { // Spin up a new thread once needed thumbnailGenerator = Task.Run((Action)ThumbGeneration); @@ -211,7 +210,7 @@ namespace MatterHackers.MatterControl { Thread.CurrentThread.Name = $"ThumbnailGeneration"; - while(!MatterControlApplication.Instance.HasBeenClosed) + while(!MatterControlApplication.Instance.ApplicationExiting) { Thread.Sleep(100); @@ -235,13 +234,16 @@ namespace MatterHackers.MatterControl } catch (ThreadAbortException e) { - return; + Console.WriteLine("ThumbGeneration Thread abort"); } catch (Exception ex) { Console.WriteLine("Error generating thumbnail: " + ex.Message); } } + + // Null task reference on exit + thumbnailGenerator = null; } public static Func> GetPrinterProfileAsync; @@ -476,6 +478,14 @@ namespace MatterHackers.MatterControl }, ref unregisterEvents); } + internal void Shutdown() + { + // Ensure all threads shutdown gracefully on close + + // Release any waiting generator threads + thumbGenResetEvent?.Set(); + } + public void StartSignIn() { if (this.ActivePrinter.Connection.PrinterIsPrinting @@ -617,7 +627,7 @@ namespace MatterHackers.MatterControl }, "Are you sure you want to sign out? You will not have access to your printer profiles or cloud library.".Localize(), "Sign Out?".Localize(), StyledMessageBox.MessageType.YES_NO, "Sign Out".Localize(), "Cancel".Localize()); } else // just run the sign out event - { + { SignOutAction?.Invoke(); } } @@ -821,7 +831,6 @@ namespace MatterHackers.MatterControl } } - if (this.ActivePrinter.Settings.PrinterSelected && this.ActivePrinter.Settings.GetValue(SettingsKey.auto_connect)) { diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index e11df75b6..103b321e6 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -498,6 +498,8 @@ namespace MatterHackers.MatterControl { this.ApplicationExiting = true; + ApplicationController.Instance.Shutdown(); + // Always call PrinterConnection.Disable on exit unless PrintingFromSd PrinterConnection printerConnection = ApplicationController.Instance.ActivePrinter.Connection; switch(printerConnection.CommunicationState) From 593863c5089642889907398978f688618bcec6ed Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 08:22:18 -0700 Subject: [PATCH 16/19] Remove Task.Run calls, move Load processing back onto callers thread --- .../FileSystem/FileSystemContainer.cs | 92 +++++++++---------- .../CalibrationPartsContainer.cs | 52 +++++------ .../MatterControl/PrintHistoryContainer.cs | 12 +-- .../MatterControl/PrintQueueContainer.cs | 5 +- .../MatterControl/SqliteLibraryContainer.cs | 39 ++++---- Library/Providers/RootLibraryContainer.cs | 4 +- Library/Providers/Zip/ZipMemoryContainer.cs | 2 +- Library/Widgets/PrintLibraryWidget.cs | 21 ----- 8 files changed, 91 insertions(+), 136 deletions(-) diff --git a/Library/Providers/FileSystem/FileSystemContainer.cs b/Library/Providers/FileSystem/FileSystemContainer.cs index 5243b4505..63f1ced59 100644 --- a/Library/Providers/FileSystem/FileSystemContainer.cs +++ b/Library/Providers/FileSystem/FileSystemContainer.cs @@ -147,58 +147,55 @@ namespace MatterHackers.MatterControl.Library { SearchOption searchDepth = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - await Task.Run(() => + try { - try + string filter = this.KeywordFilter.Trim(); + + var allFiles = Directory.GetFiles(fullPath, "*.*", searchDepth); + + var zipFiles = allFiles.Where(f => Path.GetExtension(f).IndexOf(".zip", StringComparison.OrdinalIgnoreCase) != -1); + + var nonZipFiles = allFiles.Except(zipFiles); + + List containers; + if (filter == "") { - string filter = this.KeywordFilter.Trim(); - - var allFiles = Directory.GetFiles(fullPath, "*.*", searchDepth); - - var zipFiles = allFiles.Where(f => Path.GetExtension(f).IndexOf(".zip", StringComparison.OrdinalIgnoreCase) != -1); - - var nonZipFiles = allFiles.Except(zipFiles); - - List containers; - if (filter == "") - { - var directories = Directory.GetDirectories(fullPath, "*.*", searchDepth).Select(p => new DirectoryContainerLink(p)).ToList(); - containers = directories.Concat(zipFiles.Select(f => new LocalZipContainerLink(f))).OrderBy(d => d.Name).ToList(); - } - else - { - containers = new List(); - } - - var matchedFiles = (filter == "") ? nonZipFiles : nonZipFiles.Where(filePath => - { - string fileName = Path.GetFileName(filePath); - return FileNameContainsFilter(filePath, filter) - && ApplicationController.Instance.Library.IsContentFileType(fileName); - }); - - UiThread.RunOnIdle(() => - { - // Matched containers - this.ChildContainers = containers; - - // Matched files projected onto FileSystemFileItem - this.Items = matchedFiles.OrderBy(f => f).Select(f => new FileSystemFileItem(f)).ToList(); - - this.isDirty = false; - - this.OnReloaded(); - }); + var directories = Directory.GetDirectories(fullPath, "*.*", searchDepth).Select(p => new DirectoryContainerLink(p)).ToList(); + containers = directories.Concat(zipFiles.Select(f => new LocalZipContainerLink(f))).OrderBy(d => d.Name).ToList(); } - catch (Exception ex) + else { - this.ChildContainers = new List(); - this.Items = new List() - { - new MessageItem("Error loading container - " + ex.Message) - }; + containers = new List(); } - }); + + var matchedFiles = (filter == "") ? nonZipFiles : nonZipFiles.Where(filePath => + { + string fileName = Path.GetFileName(filePath); + return FileNameContainsFilter(filePath, filter) + && ApplicationController.Instance.Library.IsContentFileType(fileName); + }); + + UiThread.RunOnIdle(() => + { + // Matched containers + this.ChildContainers = containers; + + // Matched files projected onto FileSystemFileItem + this.Items = matchedFiles.OrderBy(f => f).Select(f => new FileSystemFileItem(f)).ToList(); + + this.isDirty = false; + + this.OnReloaded(); + }); + } + catch (Exception ex) + { + this.ChildContainers = new List(); + this.Items = new List() + { + new MessageItem("Error loading container - " + ex.Message) + }; + } } private bool FileNameContainsFilter(string filename, string filter) @@ -310,7 +307,6 @@ namespace MatterHackers.MatterControl.Library this.GetFilesAndCollectionsInCurrentDirectory(); } } - public override void Remove(IEnumerable items) { diff --git a/Library/Providers/MatterControl/CalibrationPartsContainer.cs b/Library/Providers/MatterControl/CalibrationPartsContainer.cs index 2e86b412f..ae277d77d 100644 --- a/Library/Providers/MatterControl/CalibrationPartsContainer.cs +++ b/Library/Providers/MatterControl/CalibrationPartsContainer.cs @@ -30,7 +30,6 @@ either expressed or implied, of the FreeBSD Project. using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading.Tasks; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; using MatterHackers.Localizations; @@ -50,37 +49,34 @@ namespace MatterHackers.MatterControl.Library private void ReloadContainer() { - Task.Run(() => + // TODO: Long term do we want to have multiple categories in the view - OEM parts and printer specific calibration parts? Easy to do if so + /* + IEnumerable printerFiles; + + string printerCalibrationFiles = ActiveSliceSettings.Instance.GetValue("calibration_files"); + if (string.IsNullOrEmpty(printerCalibrationFiles)) { - // TODO: Long term do we want to have multiple categories in the view - OEM parts and printer specific calibration parts? Easy to do if so - /* - IEnumerable printerFiles; + return; + } - string printerCalibrationFiles = ActiveSliceSettings.Instance.GetValue("calibration_files"); - if (string.IsNullOrEmpty(printerCalibrationFiles)) - { - return; - } + string[] calibrationPrintFileNames = printerCalibrationFiles.Split(';'); + if (calibrationPrintFileNames.Length < 0) + { + printerFiles = Enumerable.Empty(); + } + else + { + printerFiles = calibrationPrintFileNames; + } */ - string[] calibrationPrintFileNames = printerCalibrationFiles.Split(';'); - if (calibrationPrintFileNames.Length < 0) - { - printerFiles = Enumerable.Empty(); - } - else - { - printerFiles = calibrationPrintFileNames; - } */ + var oemParts = AggContext.StaticData.GetFiles(Path.Combine("OEMSettings", "SampleParts")); + Items = oemParts.Select(s => + { + // TODO: Won't work on Android - make stream based + return new FileSystemFileItem(AggContext.StaticData.MapPath(s)); + }).ToList(); - var oemParts = AggContext.StaticData.GetFiles(Path.Combine("OEMSettings", "SampleParts")); - Items = oemParts.Select(s => - { - // TODO: Won't work on Android - make stream based - return new FileSystemFileItem(AggContext.StaticData.MapPath(s)); - }).ToList(); - - UiThread.RunOnIdle(this.OnReloaded); - }); + UiThread.RunOnIdle(this.OnReloaded); } public override void Dispose() diff --git a/Library/Providers/MatterControl/PrintHistoryContainer.cs b/Library/Providers/MatterControl/PrintHistoryContainer.cs index 26d7c667b..2539a48eb 100644 --- a/Library/Providers/MatterControl/PrintHistoryContainer.cs +++ b/Library/Providers/MatterControl/PrintHistoryContainer.cs @@ -29,7 +29,6 @@ either expressed or implied, of the FreeBSD Project. using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using MatterHackers.Agg.UI; using MatterHackers.Localizations; using MatterHackers.MatterControl.PrintHistory; @@ -52,15 +51,12 @@ namespace MatterHackers.MatterControl.Library private void ReloadContainer() { - Task.Run(() => - { - var printHistory = PrintHistoryData.Instance.GetHistoryItems(25); + var printHistory = PrintHistoryData.Instance.GetHistoryItems(25); - // PrintItems projected onto FileSystemFileItem - Items = printHistory.Select(f => new PrintHistoryItem(f)).ToList(); + // PrintItems projected onto FileSystemFileItem + Items = printHistory.Select(f => new PrintHistoryItem(f)).ToList(); - UiThread.RunOnIdle(this.OnReloaded); - }); + UiThread.RunOnIdle(this.OnReloaded); } } } diff --git a/Library/Providers/MatterControl/PrintQueueContainer.cs b/Library/Providers/MatterControl/PrintQueueContainer.cs index 47a453c5e..b5a2117d6 100644 --- a/Library/Providers/MatterControl/PrintQueueContainer.cs +++ b/Library/Providers/MatterControl/PrintQueueContainer.cs @@ -47,10 +47,7 @@ namespace MatterHackers.MatterControl.Library this.Items = new List(); this.Name = "Print Queue".Localize(); - Task.Run(() => - { - this.ReloadContainer(); - }); + this.ReloadContainer(); } private void ReloadContainer() diff --git a/Library/Providers/MatterControl/SqliteLibraryContainer.cs b/Library/Providers/MatterControl/SqliteLibraryContainer.cs index b8cfaef41..e4ab0462e 100644 --- a/Library/Providers/MatterControl/SqliteLibraryContainer.cs +++ b/Library/Providers/MatterControl/SqliteLibraryContainer.cs @@ -37,14 +37,10 @@ using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MatterControl.DataStorage; -using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.PrintQueue; using MatterHackers.PolygonMesh; using MatterHackers.PolygonMesh.Processors; - - - namespace MatterHackers.MatterControl.Library { public class SqliteFileItem : FileSystemFileItem @@ -96,30 +92,27 @@ namespace MatterHackers.MatterControl.Library private void ReloadContainer() { - Task.Run(() => + childCollections = GetChildCollections(); + + this.ChildContainers = childCollections.Select(c => new SqliteLibraryContainerLink() { - childCollections = GetChildCollections(); + ContainerID = c.Id, Name = c.Name }).ToList(); // - this.ChildContainers = childCollections.Select(c => new SqliteLibraryContainerLink() + // PrintItems projected onto FileSystemFileItem + Items = GetLibraryItems(KeywordFilter).Select(printItem => + { + if (File.Exists(printItem.FileLocation)) { - ContainerID = c.Id, Name = c.Name }).ToList(); // - - // PrintItems projected onto FileSystemFileItem - Items = GetLibraryItems(KeywordFilter).Select(printItem => + return new SqliteFileItem(printItem); + } + else { - if (File.Exists(printItem.FileLocation)) - { - return new SqliteFileItem(printItem); - } - else - { - return new MessageItem($"{printItem.Name} (Missing)"); - //return new MissingFileItem() // Needs to return a content specific icon with a missing overlay - needs to lack all print operations - } - }).ToList(); + return new MessageItem($"{printItem.Name} (Missing)"); + //return new MissingFileItem() // Needs to return a content specific icon with a missing overlay - needs to lack all print operations + } + }).ToList(); - UiThread.RunOnIdle(this.OnReloaded); - }); + UiThread.RunOnIdle(this.OnReloaded); } public override async void Add(IEnumerable items) diff --git a/Library/Providers/RootLibraryContainer.cs b/Library/Providers/RootLibraryContainer.cs index a617907b3..e220683cc 100644 --- a/Library/Providers/RootLibraryContainer.cs +++ b/Library/Providers/RootLibraryContainer.cs @@ -29,14 +29,12 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using MatterHackers.Agg.Image; -using MatterHackers.Agg.UI; namespace MatterHackers.MatterControl.Library { - public partial class RootLibraryContainer : ILibraryContainer + public class RootLibraryContainer : ILibraryContainer { public event EventHandler Reloaded; diff --git a/Library/Providers/Zip/ZipMemoryContainer.cs b/Library/Providers/Zip/ZipMemoryContainer.cs index 8413e0d6d..47e244f9f 100644 --- a/Library/Providers/Zip/ZipMemoryContainer.cs +++ b/Library/Providers/Zip/ZipMemoryContainer.cs @@ -68,7 +68,7 @@ namespace MatterHackers.MatterControl.Library } } - this.Name = System.IO.Path.GetFileNameWithoutExtension(path); + this.Name = Path.GetFileNameWithoutExtension(path); this.ChildContainers = directories.Where(d => !string.IsNullOrEmpty(d)).Select(d => new LocalZipContainerLink(path) diff --git a/Library/Widgets/PrintLibraryWidget.cs b/Library/Widgets/PrintLibraryWidget.cs index 003cfdc89..639672fb7 100644 --- a/Library/Widgets/PrintLibraryWidget.cs +++ b/Library/Widgets/PrintLibraryWidget.cs @@ -744,27 +744,6 @@ namespace MatterHackers.MatterControl.PrintLibrary WizardWindow.Show(exportPage); } - /* - public async Task GetPrintItemWrapperAsync() - { - return await libraryProvider.GetPrintItemWrapperAsync(this.ItemIndex); - } */ - - // TODO: We've discussed not doing popup edit in a new window. That's what this did, not worth porting yet... - /* - private void editButton_Click(object sender, EventArgs e) - { - //Open export options - if (libraryDataView.SelectedItems.Count == 1) - { - - OpenPartViewWindow(PartPreviewWindow.View3DWidget.OpenMode.Editing); - - LibraryRowItem libraryItem = libraryDataView.SelectedItems[0]; - libraryItem.Edit(); - } - } */ - public override void OnMouseEnterBounds(MouseEventArgs mouseEvent) { if (mouseEvent.DragFiles?.Count > 0) From c674bc329c4a45575a118a54387c67664c7de499 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 13:20:56 -0700 Subject: [PATCH 17/19] Revise LibraryContainer Load events --- Library/Interfaces/ILibraryContainer.cs | 3 +- .../FileSystem/FileSystemContainer.cs | 51 +++-------- Library/Providers/LibraryConfig.cs | 12 +-- Library/Providers/LibraryContainer.cs | 8 +- .../CalibrationPartsContainer.cs | 6 +- .../MatterControl/PrintHistoryContainer.cs | 13 +-- .../MatterControl/PrintQueueContainer.cs | 11 +-- .../MatterControl/SqliteLibraryContainer.cs | 30 +++--- Library/Providers/RootLibraryContainer.cs | 4 +- Library/Providers/SDCard/SDCardContainer.cs | 37 +++++--- .../Providers/Zip/LocalZipContainerLink.cs | 7 +- Library/Providers/Zip/ZipMemoryContainer.cs | 28 ++++-- Library/Widgets/ListView/ListView.cs | 91 +++++++++++-------- Library/Widgets/PrintLibraryWidget.cs | 8 +- 14 files changed, 162 insertions(+), 147 deletions(-) diff --git a/Library/Interfaces/ILibraryContainer.cs b/Library/Interfaces/ILibraryContainer.cs index a49cc167a..6cac49ee8 100644 --- a/Library/Interfaces/ILibraryContainer.cs +++ b/Library/Interfaces/ILibraryContainer.cs @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.Library Type DefaultView { get; } - event EventHandler Reloaded; + event EventHandler ContentChanged; List ChildContainers { get; } List Items { get; } @@ -55,6 +55,7 @@ namespace MatterHackers.MatterControl.Library void Deactivate(); void Activate(); + void Load(); } public interface ILibraryWritableContainer : ILibraryContainer diff --git a/Library/Providers/FileSystem/FileSystemContainer.cs b/Library/Providers/FileSystem/FileSystemContainer.cs index 63f1ced59..fe904373e 100644 --- a/Library/Providers/FileSystem/FileSystemContainer.cs +++ b/Library/Providers/FileSystem/FileSystemContainer.cs @@ -72,7 +72,6 @@ namespace MatterHackers.MatterControl.Library directoryWatcher.EnableRaisingEvents = true; } #endif - GetFilesAndCollectionsInCurrentDirectory(); } // Indicates if the new AMF file should use the original file name incremented until no name collision occurs @@ -81,12 +80,6 @@ namespace MatterHackers.MatterControl.Library public override void Activate() { this.isActiveContainer = true; - - if (isDirty) - { - // Requires reload - GetFilesAndCollectionsInCurrentDirectory(); - } base.Activate(); } @@ -109,11 +102,6 @@ namespace MatterHackers.MatterControl.Library if (keywordFilter != value) { keywordFilter = value; - - if (isActiveContainer) - { - GetFilesAndCollectionsInCurrentDirectory(true); - } } } } @@ -139,11 +127,16 @@ namespace MatterHackers.MatterControl.Library // Only refresh content if we're the active container if (isActiveContainer) { - GetFilesAndCollectionsInCurrentDirectory(); + this.Load(false); } } - private async void GetFilesAndCollectionsInCurrentDirectory(bool recursive = false) + public override void Load() + { + this.Load(false); + } + + public void Load(bool recursive) { SearchOption searchDepth = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; @@ -175,18 +168,13 @@ namespace MatterHackers.MatterControl.Library && ApplicationController.Instance.Library.IsContentFileType(fileName); }); - UiThread.RunOnIdle(() => - { - // Matched containers - this.ChildContainers = containers; + // Matched containers + this.ChildContainers = containers; - // Matched files projected onto FileSystemFileItem - this.Items = matchedFiles.OrderBy(f => f).Select(f => new FileSystemFileItem(f)).ToList(); + // Matched files projected onto FileSystemFileItem + this.Items = matchedFiles.OrderBy(f => f).Select(f => new FileSystemFileItem(f)).ToList(); - this.isDirty = false; - - this.OnReloaded(); - }); + this.isDirty = false; } catch (Exception ex) { @@ -214,8 +202,6 @@ namespace MatterHackers.MatterControl.Library return true; } - #region Container Actions - private string GetNonCollidingName(string fileName) { string incrementedFilePath; @@ -304,7 +290,7 @@ namespace MatterHackers.MatterControl.Library if (this.isDirty) { - this.GetFilesAndCollectionsInCurrentDirectory(); + this.OnContentChanged(); } } @@ -320,12 +306,7 @@ namespace MatterHackers.MatterControl.Library { if (Directory.Exists(directoryLink.Path)) { - //string destPath = Path.Combine(Path.GetDirectoryName(fileSystemContainer.fullPath), revisedName); - //Directory.Move(fileSystemContainer.fullPath, destPath); - - //await Task.Delay(150); - - //GetFilesAndCollectionsInCurrentDirectory(); + Process.Start(this.fullPath); } } else if (item is FileSystemFileItem fileItem) @@ -341,13 +322,11 @@ namespace MatterHackers.MatterControl.Library fileItem.Path = destFile; - this.OnReloaded(); + this.OnContentChanged(); } } } - #endregion - public class DirectoryContainerLink : FileSystemItem, ILibraryContainerLink { public DirectoryContainerLink(string path) diff --git a/Library/Providers/LibraryConfig.cs b/Library/Providers/LibraryConfig.cs index 58dc7bb08..fc1c0eb32 100644 --- a/Library/Providers/LibraryConfig.cs +++ b/Library/Providers/LibraryConfig.cs @@ -39,7 +39,7 @@ namespace MatterHackers.MatterControl.Library { ILibraryContainer ActiveContainer { get; set; } event EventHandler ContainerChanged; - event EventHandler ContainerReloaded; + event EventHandler ContentChanged; } public class ContainerChangedEventArgs : EventArgs @@ -57,7 +57,7 @@ namespace MatterHackers.MatterControl.Library public class LibraryConfig : ILibraryContext { public event EventHandler ContainerChanged; - public event EventHandler ContainerReloaded; + public event EventHandler ContentChanged; // TODO: Needed? public event EventHandler LibraryItemsChanged; @@ -101,7 +101,7 @@ namespace MatterHackers.MatterControl.Library if (activeContainer != null) { activeContainer.Deactivate(); - activeContainer.Reloaded -= ActiveContainer_Reloaded; + activeContainer.ContentChanged -= ActiveContainer_ContentChanged; activeContainer.KeywordFilter = ""; // If the new container is an ancestor of the active container we need to Dispose everyone up to that point @@ -118,7 +118,7 @@ namespace MatterHackers.MatterControl.Library activeContainer = newContainer; activeContainer.Activate(); - activeContainer.Reloaded += ActiveContainer_Reloaded; + activeContainer.ContentChanged += ActiveContainer_ContentChanged; ContainerChanged?.Invoke(this, eventArgs); } @@ -166,14 +166,14 @@ namespace MatterHackers.MatterControl.Library LibraryItemsChanged?.Invoke(this, null); } - private void ActiveContainer_Reloaded(object sender, EventArgs args) + private void ActiveContainer_ContentChanged(object sender, EventArgs args) { this.OnContainerChanged(this.ActiveContainer); } private void OnContainerChanged(ILibraryContainer container) { - ContainerReloaded?.Invoke(this, new ContainerChangedEventArgs(container, null)); + ContentChanged?.Invoke(this, new ContainerChangedEventArgs(container, null)); } public bool IsContentFileType(string fileName) diff --git a/Library/Providers/LibraryContainer.cs b/Library/Providers/LibraryContainer.cs index 73d6beffe..264a5d8e9 100644 --- a/Library/Providers/LibraryContainer.cs +++ b/Library/Providers/LibraryContainer.cs @@ -36,7 +36,7 @@ namespace MatterHackers.MatterControl.Library { public abstract class LibraryContainer : ILibraryContainer { - public event EventHandler Reloaded; + public event EventHandler ContentChanged; public string ID { get; set; } public string Name { get; set; } @@ -59,11 +59,13 @@ namespace MatterHackers.MatterControl.Library public virtual string KeywordFilter { get; set; } = ""; - protected void OnReloaded() + protected void OnContentChanged() { - this.Reloaded?.Invoke(this, null); + this.ContentChanged?.Invoke(this, null); } + public abstract void Load(); + public virtual void Dispose() { } diff --git a/Library/Providers/MatterControl/CalibrationPartsContainer.cs b/Library/Providers/MatterControl/CalibrationPartsContainer.cs index ae277d77d..38a193c5e 100644 --- a/Library/Providers/MatterControl/CalibrationPartsContainer.cs +++ b/Library/Providers/MatterControl/CalibrationPartsContainer.cs @@ -43,11 +43,9 @@ namespace MatterHackers.MatterControl.Library this.ChildContainers = new List(); this.Items = new List(); this.Name = "Calibration Parts".Localize(); - - this.ReloadContainer(); } - private void ReloadContainer() + public override void Load() { // TODO: Long term do we want to have multiple categories in the view - OEM parts and printer specific calibration parts? Easy to do if so /* @@ -75,8 +73,6 @@ namespace MatterHackers.MatterControl.Library // TODO: Won't work on Android - make stream based return new FileSystemFileItem(AggContext.StaticData.MapPath(s)); }).ToList(); - - UiThread.RunOnIdle(this.OnReloaded); } public override void Dispose() diff --git a/Library/Providers/MatterControl/PrintHistoryContainer.cs b/Library/Providers/MatterControl/PrintHistoryContainer.cs index 2539a48eb..50637713b 100644 --- a/Library/Providers/MatterControl/PrintHistoryContainer.cs +++ b/Library/Providers/MatterControl/PrintHistoryContainer.cs @@ -29,7 +29,6 @@ either expressed or implied, of the FreeBSD Project. using System.Collections.Generic; using System.Linq; -using MatterHackers.Agg.UI; using MatterHackers.Localizations; using MatterHackers.MatterControl.PrintHistory; @@ -43,20 +42,12 @@ namespace MatterHackers.MatterControl.Library this.Items = new List(); this.Name = "Print History".Localize(); this.DefaultView = typeof(HistoryListView); - - //PrintHistoryData.Instance.ItemAdded.RegisterEvent((sender, e) => OnDataReloaded(null), ref unregisterEvent); - - this.ReloadContainer(); } - private void ReloadContainer() + public override void Load() { - var printHistory = PrintHistoryData.Instance.GetHistoryItems(25); - // PrintItems projected onto FileSystemFileItem - Items = printHistory.Select(f => new PrintHistoryItem(f)).ToList(); - - UiThread.RunOnIdle(this.OnReloaded); + Items = PrintHistoryData.Instance.GetHistoryItems(25).Select(f => new PrintHistoryItem(f)).ToList(); } } } diff --git a/Library/Providers/MatterControl/PrintQueueContainer.cs b/Library/Providers/MatterControl/PrintQueueContainer.cs index b5a2117d6..6add74be2 100644 --- a/Library/Providers/MatterControl/PrintQueueContainer.cs +++ b/Library/Providers/MatterControl/PrintQueueContainer.cs @@ -46,25 +46,20 @@ namespace MatterHackers.MatterControl.Library this.ChildContainers = new List(); this.Items = new List(); this.Name = "Print Queue".Localize(); - - this.ReloadContainer(); } - private void ReloadContainer() + public override void Load() { this.Items = QueueData.Instance.PrintItems.Select(p => new FileSystemFileItem(p.FileLocation) { Name = p.Name }).ToList(); - - UiThread.RunOnIdle(this.OnReloaded); } public override async void Add(IEnumerable items) { await AddAllItems(items); - - this.ReloadContainer(); + this.OnContentChanged(); } public static async Task AddAllItems(IEnumerable items) @@ -128,7 +123,7 @@ namespace MatterHackers.MatterControl.Library } } - this.ReloadContainer(); + this.OnContentChanged(); } public override bool AllowAction(ContainerActions containerActions) diff --git a/Library/Providers/MatterControl/SqliteLibraryContainer.cs b/Library/Providers/MatterControl/SqliteLibraryContainer.cs index e4ab0462e..0e492bb12 100644 --- a/Library/Providers/MatterControl/SqliteLibraryContainer.cs +++ b/Library/Providers/MatterControl/SqliteLibraryContainer.cs @@ -59,17 +59,24 @@ namespace MatterHackers.MatterControl.Library { protected List childCollections = new List(); + public SqliteLibraryContainer() + { + var rootCollection = Datastore.Instance.dbSQLite.Table().Where(v => v.Name == "_library").Take(1).FirstOrDefault(); + + this.Initialize(rootCollection?.Id ?? 0); + } + public SqliteLibraryContainer(int collectionID) + { + this.Initialize(collectionID); + } + + private void Initialize(int collectionID) { this.ChildContainers = new List(); this.Items = new List(); this.Name = "Local Library".Localize(); this.CollectionID = collectionID; - - //PrintHistoryData.Instance.ItemAdded.RegisterEvent((sender, e) => OnDataReloaded(null), ref unregisterEvent); - // ItemAdded.RegisterEvent(DatabaseFileChange, ref unregisterEvents); - - this.ReloadContainer(); } public int CollectionID { get; private set; } @@ -85,12 +92,12 @@ namespace MatterHackers.MatterControl.Library if (base.KeywordFilter != value) { base.KeywordFilter = value; - this.ReloadContainer(); + this.OnContentChanged(); } } } - private void ReloadContainer() + public override void Load() { childCollections = GetChildCollections(); @@ -111,8 +118,6 @@ namespace MatterHackers.MatterControl.Library //return new MissingFileItem() // Needs to return a content specific icon with a missing overlay - needs to lack all print operations } }).ToList(); - - UiThread.RunOnIdle(this.OnReloaded); } public override async void Add(IEnumerable items) @@ -195,8 +200,7 @@ namespace MatterHackers.MatterControl.Library } } - this.ReloadContainer(); - this.OnReloaded(); + this.OnContentChanged(); }); } @@ -229,7 +233,7 @@ namespace MatterHackers.MatterControl.Library this.Items.Remove(item); } - this.OnReloaded(); + this.OnContentChanged(); } public override void Rename(ILibraryItem selectedItem, string revisedName) @@ -251,7 +255,7 @@ namespace MatterHackers.MatterControl.Library } } - this.ReloadContainer(); + this.OnContentChanged(); } /// diff --git a/Library/Providers/RootLibraryContainer.cs b/Library/Providers/RootLibraryContainer.cs index e220683cc..f09570405 100644 --- a/Library/Providers/RootLibraryContainer.cs +++ b/Library/Providers/RootLibraryContainer.cs @@ -36,7 +36,7 @@ namespace MatterHackers.MatterControl.Library { public class RootLibraryContainer : ILibraryContainer { - public event EventHandler Reloaded; + public event EventHandler ContentChanged; public RootLibraryContainer(List items) { @@ -67,6 +67,8 @@ namespace MatterHackers.MatterControl.Library return Task.FromResult(null); } + public void Load() { } + public void Dispose() { } diff --git a/Library/Providers/SDCard/SDCardContainer.cs b/Library/Providers/SDCard/SDCardContainer.cs index 9060eaf6c..b5713932a 100644 --- a/Library/Providers/SDCard/SDCardContainer.cs +++ b/Library/Providers/SDCard/SDCardContainer.cs @@ -29,9 +29,11 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using MatterHackers.Agg; using MatterHackers.Agg.Image; +using MatterHackers.Agg.UI; using MatterHackers.Localizations; namespace MatterHackers.MatterControl.Library @@ -42,26 +44,33 @@ namespace MatterHackers.MatterControl.Library private EventHandler unregisterEvents; + private PrinterConfig printer; + + private AutoResetEvent autoResetEvent; + public SDCardContainer() { this.ChildContainers = new List(); this.Items = new List(); this.Name = "SD Card".Localize(); - LoadFilesFromSD(); + + printer = ApplicationController.Instance.ActivePrinter; } - public void LoadFilesFromSD() + public override void Load() { - var printer = ApplicationController.Instance.ActivePrinter; - if (printer.Connection.PrinterIsConnected && !(printer.Connection.PrinterIsPrinting || printer.Connection.PrinterIsPaused)) { + autoResetEvent = new AutoResetEvent(false); printer.Connection.ReadLine.RegisterEvent(Printer_LineRead, ref unregisterEvents); gotBeginFileList = false; printer.Connection.SendLineToPrinterNow("M21\r\nM20"); + + // Ask for files and wait for response + autoResetEvent.WaitOne(); } } @@ -76,8 +85,7 @@ namespace MatterHackers.MatterControl.Library private void Printer_LineRead(object sender, EventArgs e) { - var currentEvent = e as StringEventArgs; - if (currentEvent != null) + if (e is StringEventArgs currentEvent) { if (!currentEvent.Data.StartsWith("echo:")) { @@ -88,6 +96,13 @@ namespace MatterHackers.MatterControl.Library this.Items.Clear(); break; + case "End file list": + printer.Connection.ReadLine.UnregisterEvent(Printer_LineRead, ref unregisterEvents); + + // Release the Load WaitOne + autoResetEvent.Set(); + break; + default: if (gotBeginFileList) { @@ -103,11 +118,6 @@ namespace MatterHackers.MatterControl.Library } } break; - - case "End file list": - ApplicationController.Instance.ActivePrinter.Connection.ReadLine.UnregisterEvent(Printer_LineRead, ref unregisterEvents); - this.OnReloaded(); - break; } } } @@ -116,7 +126,10 @@ namespace MatterHackers.MatterControl.Library public override void Dispose() { // In case "End file list" is never received - ApplicationController.Instance.ActivePrinter.Connection.ReadLine.UnregisterEvent(Printer_LineRead, ref unregisterEvents); + printer.Connection.ReadLine.UnregisterEvent(Printer_LineRead, ref unregisterEvents); + + // Release the Load WaitOne + autoResetEvent?.Set(); } } } diff --git a/Library/Providers/Zip/LocalZipContainerLink.cs b/Library/Providers/Zip/LocalZipContainerLink.cs index 18260f4e5..e2ee5e652 100644 --- a/Library/Providers/Zip/LocalZipContainerLink.cs +++ b/Library/Providers/Zip/LocalZipContainerLink.cs @@ -69,7 +69,12 @@ namespace MatterHackers.MatterControl.Library public Task GetContainer(Action reportProgress) { - return Task.FromResult(new ZipMemoryContainer(this.currentDirectory, this.Path)); + return Task.FromResult( + new ZipMemoryContainer() + { + RelativeDirectory = this.currentDirectory, + Path = this.Path + }); } } } diff --git a/Library/Providers/Zip/ZipMemoryContainer.cs b/Library/Providers/Zip/ZipMemoryContainer.cs index 47e244f9f..667b66377 100644 --- a/Library/Providers/Zip/ZipMemoryContainer.cs +++ b/Library/Providers/Zip/ZipMemoryContainer.cs @@ -32,25 +32,35 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; +using System.Threading.Tasks; +using MatterHackers.Agg.UI; namespace MatterHackers.MatterControl.Library { public class ZipMemoryContainer : LibraryContainer { - public ZipMemoryContainer(string relativeDirectory, string path) + public ZipMemoryContainer() + { + } + + public string RelativeDirectory { get; set; } + + public string Path { get; set; } + + public override void Load() { //string hashCode = this.Url.GetHashCode().ToString(); var items = new Dictionary(); var directories = new HashSet(); - using (var file = File.OpenRead(path)) + using (var file = File.OpenRead(this.Path)) using (var zip = new ZipArchive(file, ZipArchiveMode.Read)) { foreach (var entry in zip.Entries) { - if (entry.FullName.StartsWith(relativeDirectory)) + if (entry.FullName.StartsWith(RelativeDirectory)) { - string remainingPath = entry.FullName.Substring(relativeDirectory.Length)?.Trim().TrimStart('/'); + string remainingPath = entry.FullName.Substring(RelativeDirectory.Length)?.Trim().TrimStart('/'); var segments = remainingPath.Split('/'); var firstDirectory = segments.First(); @@ -68,15 +78,15 @@ namespace MatterHackers.MatterControl.Library } } - this.Name = Path.GetFileNameWithoutExtension(path); + this.Name = System.IO.Path.GetFileNameWithoutExtension(this.Path); - this.ChildContainers = directories.Where(d => !string.IsNullOrEmpty(d)).Select(d => - new LocalZipContainerLink(path) + this.ChildContainers = directories.Where(d => !string.IsNullOrEmpty(d)).Select(d => + new LocalZipContainerLink(this.Path) { - CurrentDirectory = relativeDirectory.Length == 0 ? d : $"{relativeDirectory}/{d}" + CurrentDirectory = RelativeDirectory.Length == 0 ? d : $"{RelativeDirectory}/{d}" }).ToList(); - this.Items = items.Select(kvp => new ZipMemoryItem(path, relativeDirectory.Length == 0 ? kvp.Key : $"{relativeDirectory}/{kvp.Key}", kvp.Value)).ToList(); + this.Items = items.Select(kvp => new ZipMemoryItem(this.Path, RelativeDirectory.Length == 0 ? kvp.Key : $"{RelativeDirectory}/{kvp.Key}", kvp.Value)).ToList(); } public override void Dispose() diff --git a/Library/Widgets/ListView/ListView.cs b/Library/Widgets/ListView/ListView.cs index e9b34d4c8..e450a3f45 100644 --- a/Library/Widgets/ListView/ListView.cs +++ b/Library/Widgets/ListView/ListView.cs @@ -32,6 +32,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; +using System.Threading.Tasks; using MatterHackers.Agg; using MatterHackers.Agg.Image; using MatterHackers.Agg.Platform; @@ -46,14 +47,12 @@ namespace MatterHackers.MatterControl.CustomWidgets { private EventHandler unregisterEvents; - internal GuiWidget contentView; + private ILibraryContext LibraryContext; /// - /// The GuiWidget responsible for rendering ListViewItems + /// The original content view before it was replaced by a container default view /// - private GuiWidget previousContentView = null; - - private ILibraryContext LibraryContext; + private GuiWidget stashedContentView = new IconListView(); // Default constructor uses IconListView public ListView(ILibraryContext context) @@ -74,7 +73,7 @@ namespace MatterHackers.MatterControl.CustomWidgets this.ListContentView = libraryView; context.ContainerChanged += ActiveContainer_Changed; - context.ContainerReloaded += ActiveContainer_Reloaded; + context.ContentChanged += ActiveContainer_ContentChanged; } public bool ShowItems { get; set; } = true; @@ -88,41 +87,46 @@ namespace MatterHackers.MatterControl.CustomWidgets public RGBA_Bytes ThumbnailBackground { get; } = ActiveTheme.Instance.TertiaryBackgroundColor.AdjustLightness(1.05).GetAsRGBA_Bytes(); public RGBA_Bytes ThumbnailForeground { get; set; } = ActiveTheme.Instance.PrimaryAccentColor; - private void ActiveContainer_Changed(object sender, ContainerChangedEventArgs e) + private async void ActiveContainer_Changed(object sender, ContainerChangedEventArgs e) { var activeContainer = e.ActiveContainer; + // Anytime the container changes, Type targetType = activeContainer?.DefaultView; - if (targetType != null + if (targetType != null && targetType != this.ListContentView.GetType()) { - previousContentView = this.contentView; + // If no original view is stored in stashedContentView then store a reference before the switch + if (stashedContentView == null) + { + stashedContentView = this.ListContentView; + } // If the current view doesn't match the view requested by the container, construct and switch to the requested view var targetView = Activator.CreateInstance(targetType) as GuiWidget; if (targetView != null) { - this.SetContentView(targetView); + this.ListContentView = targetView; } } - else if (previousContentView != null) + else if (stashedContentView != null) { // Switch back to the original view - this.SetContentView(previousContentView); - previousContentView = null; + this.ListContentView = stashedContentView; + stashedContentView = null; } - DisplayContainerContent(activeContainer); + await DisplayContainerContent(activeContainer); } - public void Reload() + public async Task Reload() { - DisplayContainerContent(ActiveContainer); + await DisplayContainerContent(ActiveContainer); } - private void ActiveContainer_Reloaded(object sender, EventArgs e) + private async void ActiveContainer_ContentChanged(object sender, EventArgs e) { - DisplayContainerContent(ActiveContainer); + await DisplayContainerContent(ActiveContainer); } private List items = new List(); @@ -133,14 +137,13 @@ namespace MatterHackers.MatterControl.CustomWidgets /// Empties the list children and repopulates the list with the source container content /// /// The container to load - private void DisplayContainerContent(ILibraryContainer sourceContainer) + private async Task DisplayContainerContent(ILibraryContainer sourceContainer) { if (this.ActiveContainer is ILibraryWritableContainer activeWritable) { activeWritable.ItemContentChanged -= WritableContainer_ItemContentChanged; } - UiThread.RunOnIdle(() => { if (sourceContainer == null) { @@ -157,6 +160,12 @@ namespace MatterHackers.MatterControl.CustomWidgets var itemsContentView = contentView as IListContentView; itemsContentView.ClearItems(); + // Wait for the container to load + await Task.Run(() => + { + sourceContainer.Load(); + }); + int width = itemsContentView.ThumbWidth; int height = itemsContentView.ThumbHeight; @@ -200,7 +209,7 @@ namespace MatterHackers.MatterControl.CustomWidgets } this.Invalidate(); - }); + } } private void WritableContainer_ItemContentChanged(object sender, ItemChangedEventArgs e) @@ -219,16 +228,12 @@ namespace MatterHackers.MatterControl.CustomWidgets List } - private void SetContentView(GuiWidget contentView) - { - this.ScrollArea.CloseAllChildren(); - - this.contentView = contentView; - this.contentView.HAnchor = HAnchor.Stretch; - this.contentView.Name = "Library ListView"; - this.AddChild(this.contentView); - } + // Default to IconListView + private GuiWidget contentView = new IconListView(); + /// + /// The GuiWidget responsible for rendering ListViewItems + /// public GuiWidget ListContentView { get { return contentView; } @@ -236,13 +241,15 @@ namespace MatterHackers.MatterControl.CustomWidgets { if (value is IListContentView) { - SetContentView(value); - - // Allow some time for layout to occur and contentView to become sized before loading content - UiThread.RunOnIdle(() => + if (contentView != null) { - DisplayContainerContent(ActiveContainer); - }); + this.ScrollArea.CloseAllChildren(); + + this.contentView = value; + this.contentView.HAnchor = HAnchor.Stretch; + this.contentView.Name = "Library ListView"; + this.AddChild(this.contentView); + } } else { @@ -367,12 +374,22 @@ namespace MatterHackers.MatterControl.CustomWidgets public ListViewItem DragSourceRowItem { get; set; } + public override void OnLoad(EventArgs args) + { + if (this.ListContentView.Children.Count <= 0) + { + this.Reload(); + } + + base.OnLoad(args); + } + public override void OnClosed(ClosedEventArgs e) { if (this.LibraryContext != null) { this.LibraryContext.ContainerChanged -= this.ActiveContainer_Changed; - this.LibraryContext.ContainerReloaded -= this.ActiveContainer_Reloaded; + this.LibraryContext.ContentChanged -= this.ActiveContainer_ContentChanged; } unregisterEvents?.Invoke(this, null); diff --git a/Library/Widgets/PrintLibraryWidget.cs b/Library/Widgets/PrintLibraryWidget.cs index 639672fb7..36d424851 100644 --- a/Library/Widgets/PrintLibraryWidget.cs +++ b/Library/Widgets/PrintLibraryWidget.cs @@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl.PrintLibrary Name = "Show Folders Toggle", Checked = UserSettings.Instance.get("ShowContainers") == "1" }; - showFolders.CheckedStateChanged += (s, e) => + showFolders.CheckedStateChanged += async (s, e) => { UserSettings.Instance.set("ShowContainers", showFolders.Checked ? "1" : "0"); libraryView.Reload(); @@ -236,7 +236,7 @@ namespace MatterHackers.MatterControl.PrintLibrary // Release if (e.PreviousContainer != null) { - e.PreviousContainer.Reloaded -= UpdateStatus; + e.PreviousContainer.ContentChanged -= UpdateStatus; } var activeContainer = this.libraryView.ActiveContainer; @@ -251,7 +251,7 @@ namespace MatterHackers.MatterControl.PrintLibrary searchInput.Text = activeContainer.KeywordFilter; breadCrumbWidget.SetBreadCrumbs(activeContainer); - activeContainer.Reloaded += UpdateStatus; + activeContainer.ContentChanged += UpdateStatus; UpdateStatus(null, null); } @@ -638,7 +638,7 @@ namespace MatterHackers.MatterControl.PrintLibrary { if (libraryView?.ActiveContainer != null) { - libraryView.ActiveContainer.Reloaded -= UpdateStatus; + libraryView.ActiveContainer.ContentChanged -= UpdateStatus; ApplicationController.Instance.Library.ContainerChanged -= Library_ContainerChanged; } From 0cfe09a4fb377c914fe7915ee90e35a22330a041 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 14:28:31 -0700 Subject: [PATCH 18/19] Add LibraryContainer tests --- Library/ExtensionMethods.cs | 5 - .../FileSystem/FileSystemContainer.cs | 2 +- Submodules/agg-sharp | 2 +- .../LibraryContainerTests.cs | 261 ++++++++++++++++++ .../MatterControl.AutomationTests.csproj | 1 + 5 files changed, 264 insertions(+), 7 deletions(-) create mode 100644 Tests/MatterControl.AutomationTests/LibraryContainerTests.cs diff --git a/Library/ExtensionMethods.cs b/Library/ExtensionMethods.cs index 3586d65cd..2b81536b3 100644 --- a/Library/ExtensionMethods.cs +++ b/Library/ExtensionMethods.cs @@ -49,11 +49,6 @@ namespace MatterHackers.MatterControl.Library } } - public static void AddItem(this ILibraryContainer container, PrintItemWrapper printeItemWrapper) - { - throw new NotImplementedException("container.AddItem(PrintItemWrapper)"); - } - public static void Add(this Dictionary list, IEnumerable extensions, IContentProvider provider) { foreach (var extension in extensions) diff --git a/Library/Providers/FileSystem/FileSystemContainer.cs b/Library/Providers/FileSystem/FileSystemContainer.cs index fe904373e..12fde2c70 100644 --- a/Library/Providers/FileSystem/FileSystemContainer.cs +++ b/Library/Providers/FileSystem/FileSystemContainer.cs @@ -224,7 +224,7 @@ namespace MatterHackers.MatterControl.Library incrementedFilePath = Path.Combine(this.fullPath, $"{fileName} ({foundCount++}){fileExtension}"); // Continue incrementing while any matching file exists - } while (Directory.GetFiles(incrementedFilePath).Any()); + } while (File.Exists(incrementedFilePath)); return incrementedFilePath; } diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 3b4472353..6372949c5 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 3b447235354fa0fb63daba924b3ec42209d7bd2f +Subproject commit 6372949c59f4b355ac3744f5b0938d42d0451183 diff --git a/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs b/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs new file mode 100644 index 000000000..9c92b41df --- /dev/null +++ b/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs @@ -0,0 +1,261 @@ +/* +Copyright (c) 2017, 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.Reflection; +using System.Threading; +using System.Threading.Tasks; +using MatterHackers.Agg; +using MatterHackers.Agg.Platform; +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.Library; +using MatterHackers.MatterControl.Tests.Automation; +using NUnit.Framework; + +namespace MatterControl.Tests.MatterControl +{ + [TestFixture, Category("LibraryContainerTests"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + public class LibraryContainerTests + { + [Test] + public Task TestExistsForEachContainerType() + { + AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData")); + MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + + // Find all test methods on this test class + var thisClassMethods = this.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance); + + // Find and validate all ILibraryContainer types, skipping abstract classes + foreach (var containerType in PluginFinder.FindTypes().Where(fieldType => !fieldType.IsAbstract)) + { + string expectedTestName = $"{containerType.Name}Test"; + Assert.AreEqual( + 1, + thisClassMethods.Where(m => m.Name == expectedTestName).Count(), + "Test for LibraryContainer missing, not yet created or typo'd - Expected: " + expectedTestName); + } + + return Task.CompletedTask; + } + + [Test] + public async Task NoContentChangedOnLoad() + { + AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData")); + MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + + bool onIdlePumpActive = true; + + var uiPump = Task.Run(() => + { + while (onIdlePumpActive) + { + UiThread.InvokePendingActions(); + Thread.Sleep(10); + }; + + Console.Write("Exiting"); + }); + + // Find and validate all ILibraryContainer types, skipping abstract classes + foreach (var containerType in PluginFinder.FindTypes().Where(fieldType => !fieldType.IsAbstract)) + { + var args = new List(); + + if (containerType == typeof(FileSystemContainer)) + { + args.Add(TestContext.CurrentContext.ResolveProjectPath(4)); + } + else if (containerType == typeof(RootLibraryContainer)) + { + // TODO: Not sure how to test RootLibrary given content loads after MatterControl init is finished, skipping for now + continue; + } + + if (Activator.CreateInstance(containerType, args.ToArray()) is ILibraryContainer libraryContainer) + { + if (libraryContainer is ZipMemoryContainer zipContainer) + { + zipContainer.Path = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "Batman.zip"); + zipContainer.RelativeDirectory = Path.GetDirectoryName(zipContainer.Path); + } + + int changedCount = 0; + libraryContainer.ContentChanged += (s, e) => + { + changedCount++; + }; + + await Task.Run(() => + { + libraryContainer.Load(); + }); + + // Allow time for invalid additional reloads + await Task.Delay(300); + + // Verify Reload is called; + Assert.AreEqual(0, changedCount, "Expected reload count not hit - container should fire reload event after acquiring content"); + } + } + + onIdlePumpActive = false; + } + + [Test] + public async Task AddFiresContentChangedEvent() + { + AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData")); + MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + + string filePath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "Batman.stl"); + + bool onIdlePumpActive = true; + + var uiPump = Task.Run(() => + { + while (onIdlePumpActive) + { + UiThread.InvokePendingActions(); + Thread.Sleep(10); + }; + + Console.Write("Exiting"); + }); + + Type writable = typeof(ILibraryWritableContainer); + + // Find and validate all ILibraryContainer types, skipping abstract classes + foreach (var containerType in PluginFinder.FindTypes().Where(fieldType => !fieldType.IsAbstract)) + { + var args = new List(); + + if (containerType == typeof(FileSystemContainer)) + { + args.Add(TestContext.CurrentContext.ResolveProjectPath(4)); + } + else if (containerType == typeof(RootLibraryContainer) + || !writable.IsAssignableFrom(containerType)) + { + // TODO: Not sure how to test RootLibrary given content loads after MatterControl init is finished, skipping for now + continue; + } + + if (Activator.CreateInstance(containerType, args.ToArray()) is ILibraryWritableContainer libraryContainer) + { + if (libraryContainer is ZipMemoryContainer zipContainer) + { + zipContainer.Path = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "Batman.zip"); + zipContainer.RelativeDirectory = Path.GetDirectoryName(zipContainer.Path); + } + + int changedCount = 0; + libraryContainer.ContentChanged += (s, e) => + { + changedCount++; + }; + + var waitUntil = DateTime.Now.AddSeconds(15); + + var result = Task.Run(() => + { + libraryContainer.Load(); + libraryContainer.Add(new[] { new FileSystemFileItem(filePath) }); + }); + + // Wait for reload + while (DateTime.Now <= waitUntil) + { + if (changedCount > 0) + { + break; + } + + await Task.Delay(200); + } + + // Allow time for invalid additional reloads + await Task.Delay(300); + + Console.WriteLine($"ContentChanged for {containerType.Name}"); + + // Verify Reload is called; + Assert.AreEqual(1, changedCount, $"Expected reload count for {containerType.Name} not hit - container should fire reload event after acquiring content"); + } + } + + onIdlePumpActive = false; + } + + + [Test, Ignore("Not implemented")] + public async Task CalibrationPartsContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task PrintHistoryContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task SqliteLibraryContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task PrintQueueContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task SDCardContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task FileSystemContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task RootLibraryContainerTest() + { + } + + [Test, Ignore("Not implemented")] + public async Task ZipMemoryContainerTest() + { + } + } +} diff --git a/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj b/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj index 65af72d93..0867846cb 100644 --- a/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj +++ b/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj @@ -70,6 +70,7 @@ + From 74d3f3a839d9b5d8960cd13f0d301a69dea9547f Mon Sep 17 00:00:00 2001 From: John Lewin Date: Mon, 9 Oct 2017 14:46:43 -0700 Subject: [PATCH 19/19] Create test output in test folder --- Tests/MatterControl.AutomationTests/LibraryContainerTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs b/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs index 9c92b41df..68d62f3c6 100644 --- a/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs +++ b/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs @@ -37,6 +37,7 @@ using System.Threading.Tasks; using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.Tests.Automation; using NUnit.Framework; @@ -162,7 +163,8 @@ namespace MatterControl.Tests.MatterControl if (containerType == typeof(FileSystemContainer)) { - args.Add(TestContext.CurrentContext.ResolveProjectPath(4)); + Directory.CreateDirectory(ApplicationDataStorage.Instance.ApplicationTempDataPath); + args.Add(ApplicationDataStorage.Instance.ApplicationTempDataPath); } else if (containerType == typeof(RootLibraryContainer) || !writable.IsAssignableFrom(containerType))