2014-04-19 14:02:51 -07:00
/ *
Copyright ( c ) 2014 , Kevin Pope
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 ;
2014-10-24 14:55:27 -07:00
using System.ComponentModel ;
2014-04-19 14:02:51 -07:00
using System.IO ;
2014-12-02 10:28:49 -08:00
using System.Linq ;
2014-04-19 14:02:51 -07:00
using MatterHackers.Agg ;
2014-10-24 14:55:27 -07:00
using MatterHackers.Localizations ;
2014-04-19 14:02:51 -07:00
using MatterHackers.MatterControl.DataStorage ;
using MatterHackers.MatterControl.PrintQueue ;
2014-05-12 18:30:35 -07:00
using MatterHackers.MatterControl.SettingsManagement ;
2014-10-24 14:55:27 -07:00
using MatterHackers.PolygonMesh ;
using MatterHackers.Agg.UI ;
using MatterHackers.PolygonMesh.Processors ;
2014-12-02 10:28:49 -08:00
using MatterHackers.Agg.PlatformAbstract ;
2014-04-19 14:02:51 -07:00
namespace MatterHackers.MatterControl.PrintLibrary
{
public class LibraryData
{
private List < PrintItemWrapper > printItems = new List < PrintItemWrapper > ( ) ;
private List < PrintItemWrapper > PrintItems
{
get { return printItems ; }
}
2014-05-07 15:59:10 -07:00
public RootedObjectEventHandler DataReloaded = new RootedObjectEventHandler ( ) ;
2014-04-19 14:02:51 -07:00
public RootedObjectEventHandler ItemAdded = new RootedObjectEventHandler ( ) ;
public RootedObjectEventHandler ItemRemoved = new RootedObjectEventHandler ( ) ;
public RootedObjectEventHandler OrderChanged = new RootedObjectEventHandler ( ) ;
private DataStorage . PrintItemCollection libraryCollection ;
static LibraryData instance ;
public static LibraryData Instance
{
get
{
if ( instance = = null )
{
instance = new LibraryData ( ) ;
instance . LoadLibraryItems ( ) ;
}
return instance ;
}
}
2014-10-24 15:37:03 -07:00
static public void SaveToLibraryFolder ( PrintItemWrapper printItemWrapper , List < MeshGroup > meshGroups )
2014-10-24 14:55:27 -07:00
{
if ( printItemWrapper . FileLocation . Contains ( ApplicationDataStorage . Instance . ApplicationLibraryDataPath ) )
{
MeshOutputSettings outputInfo = new MeshOutputSettings ( MeshOutputSettings . OutputType . Binary , new string [ ] { "Created By" , "MatterControl" } ) ;
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 , new string [ ] { "Created By" , "MatterControl" } ) ;
MeshFileIo . Save ( meshGroups , printItemWrapper . FileLocation , outputInfo ) ;
printItemWrapper . PrintItem . Commit ( ) ;
}
printItemWrapper . OnFileHasChanged ( ) ;
}
2014-04-19 14:02:51 -07:00
string keywordFilter = "" ;
public string KeywordFilter
{
get { return keywordFilter ; }
set
{
if ( this . keywordFilter ! = value )
{
this . keywordFilter = value ;
LoadLibraryItems ( ) ;
}
}
}
public void AddItem ( PrintItemWrapper item , int indexToInsert = - 1 )
{
if ( indexToInsert = = - 1 )
{
indexToInsert = PrintItems . Count ;
}
PrintItems . Insert ( indexToInsert , item ) ;
OnItemAdded ( new IndexArgs ( indexToInsert ) ) ;
}
2014-04-19 14:44:59 -07:00
public void RemoveItem ( PrintItemWrapper printItemWrapper )
{
int index = PrintItems . IndexOf ( printItemWrapper ) ;
if ( index < 0 )
{
2014-04-19 14:57:30 -07:00
// It may be possible to have the same item in the remove list twice.
// so if it is not in the PrintItems then ignore it.
return ;
2014-04-19 14:44:59 -07:00
}
PrintItems . RemoveAt ( index ) ;
// and remove it from the data base
printItemWrapper . Delete ( ) ;
OnItemRemoved ( new IndexArgs ( index ) ) ;
}
2014-04-19 14:02:51 -07:00
public PrintItemWrapper GetPrintItemWrapper ( int index )
{
if ( index > = 0 & & index < Count )
{
return PrintItems [ index ] ;
}
return null ;
}
public List < PrintItem > CreateReadOnlyPartList ( )
{
List < PrintItem > listToReturn = new List < PrintItem > ( ) ;
for ( int i = 0 ; i < Count ; i + + )
{
listToReturn . Add ( GetPrintItemWrapper ( i ) . PrintItem ) ;
}
return listToReturn ;
}
public DataStorage . PrintItemCollection LibraryCollection
{
get
{
2014-12-02 10:28:49 -08:00
// Attempt to initialize the library from the Datastore if null
2014-04-19 14:02:51 -07:00
if ( libraryCollection = = null )
{
libraryCollection = DataStorage . Datastore . Instance . dbSQLite . Table < DataStorage . PrintItemCollection > ( ) . Where ( v = > v . Name = = "_library" ) . Take ( 1 ) . FirstOrDefault ( ) ;
}
2014-12-02 10:28:49 -08:00
// If the _library collection is still missing, create and populate it with default content
2014-04-19 14:02:51 -07:00
if ( libraryCollection = = null )
{
libraryCollection = new PrintItemCollection ( ) ;
libraryCollection . Name = "_library" ;
libraryCollection . Commit ( ) ;
2014-12-02 10:28:49 -08:00
// Preload library with Oem supplied list of default parts
string [ ] itemsToAdd = LibraryData . SyncCalibrationFilesToDisk ( OemSettings . Instance . PreloadedLibraryFiles ) ;
if ( itemsToAdd . Length > 0 )
{
// Import any files sync'd to disk into the library, then add them to the queue
LibraryData . Instance . LoadFilesIntoLibrary ( itemsToAdd ) ;
}
2014-04-19 14:02:51 -07:00
}
return libraryCollection ;
}
}
2014-12-02 10:28:49 -08:00
internal static string [ ] SyncCalibrationFilesToDisk ( List < string > calibrationPrintFileNames )
2014-04-19 14:02:51 -07:00
{
2014-12-02 10:28:49 -08:00
// Ensure the CalibrationParts directory exists to store/import the files from disk
string tempPath = Path . Combine ( ApplicationDataStorage . Instance . ApplicationUserDataPath , "data" , "temp" , "calibration-parts" ) ;
Directory . CreateDirectory ( tempPath ) ;
// Build a list of temporary files that should be imported into the library
return calibrationPrintFileNames . Where ( fileName = >
2014-04-19 14:02:51 -07:00
{
2014-12-02 10:28:49 -08:00
// Filter out items that already exist in the library
return LibraryData . Instance . GetLibraryItems ( Path . GetFileNameWithoutExtension ( fileName ) ) . Count ( ) < = 0 ;
} ) . Select ( fileName = >
{
// Copy calibration prints from StaticData to the filesystem before importing into the library
string tempFile = Path . Combine ( tempPath , Path . GetFileName ( fileName ) ) ;
using ( FileStream outstream = File . OpenWrite ( tempFile ) )
using ( Stream instream = StaticData . Instance . OpenSteam ( Path . Combine ( "OEMSettings" , "SampleParts" , fileName ) ) )
2014-04-19 14:02:51 -07:00
{
2014-12-02 10:28:49 -08:00
instream . CopyTo ( outstream ) ;
2014-04-19 14:02:51 -07:00
}
2014-12-02 10:28:49 -08:00
// Project the new filename to the output
return tempFile ;
} ) . ToArray ( ) ;
2014-04-19 14:02:51 -07:00
}
2014-12-02 10:28:49 -08:00
internal IEnumerable < DataStorage . PrintItem > GetLibraryItems ( string keyphrase = null )
2014-04-19 14:02:51 -07:00
{
if ( LibraryCollection = = null )
{
return null ;
}
else
{
string query ;
if ( keyphrase = = null )
{
query = string . Format ( "SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} ORDER BY Name ASC;" , libraryCollection . Id ) ;
}
else
{
query = string . Format ( "SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} AND Name LIKE '%{1}%' ORDER BY Name ASC;" , libraryCollection . Id , keyphrase ) ;
}
IEnumerable < DataStorage . PrintItem > result = ( IEnumerable < DataStorage . PrintItem > ) DataStorage . Datastore . Instance . dbSQLite . Query < DataStorage . PrintItem > ( query ) ;
return result ;
}
}
public void LoadLibraryItems ( )
{
PrintItems . Clear ( ) ;
IEnumerable < DataStorage . PrintItem > partFiles = GetLibraryItems ( keywordFilter ) ;
if ( partFiles ! = null )
{
foreach ( PrintItem part in partFiles )
{
PrintItems . Add ( new PrintItemWrapper ( part ) ) ;
}
}
2014-05-07 15:59:10 -07:00
OnDataReloaded ( null ) ;
}
public void OnDataReloaded ( EventArgs e )
{
DataReloaded . CallEvents ( this , e ) ;
2014-04-19 14:02:51 -07:00
}
public void OnItemAdded ( EventArgs e )
{
ItemAdded . CallEvents ( this , e ) ;
}
2014-04-19 14:44:59 -07:00
public void OnItemRemoved ( EventArgs e )
{
ItemRemoved . CallEvents ( this , e ) ;
}
2014-04-19 14:02:51 -07:00
public void SaveLibraryItems ( )
{
//
}
public int Count
{
get
{
return PrintItems . Count ;
}
}
2014-10-24 14:55:27 -07:00
2014-10-26 18:08:03 -07:00
ReportProgressRatio fileLoadReportProgress = null ;
2014-12-11 17:19:32 -08:00
public void LoadFilesIntoLibrary ( IList < string > files , ReportProgressRatio reportProgress = null , RunWorkerCompletedEventHandler callback = null )
2014-10-24 14:55:27 -07:00
{
this . fileLoadReportProgress = reportProgress ;
2014-12-11 17:19:32 -08:00
if ( files ! = null & & files . Count > 0 )
2014-10-24 14:55:27 -07:00
{
BackgroundWorker mergeAndSavePartsBackgroundWorker = new BackgroundWorker ( ) ;
mergeAndSavePartsBackgroundWorker . WorkerReportsProgress = true ;
mergeAndSavePartsBackgroundWorker . DoWork + = new DoWorkEventHandler ( mergeAndSavePartsBackgroundWorker_DoWork ) ;
mergeAndSavePartsBackgroundWorker . RunWorkerCompleted + = new RunWorkerCompletedEventHandler ( mergeAndSavePartsBackgroundWorker_RunWorkerCompleted ) ;
2014-12-02 10:28:49 -08:00
if ( callback ! = null )
{
mergeAndSavePartsBackgroundWorker . RunWorkerCompleted + = callback ;
}
2014-10-24 14:55:27 -07:00
mergeAndSavePartsBackgroundWorker . RunWorkerAsync ( files ) ;
}
}
void mergeAndSavePartsBackgroundWorker_DoWork ( object sender , DoWorkEventArgs e )
{
2014-12-11 17:19:32 -08:00
IList < string > fileList = e . Argument as IList < string > ;
2014-10-24 14:55:27 -07:00
foreach ( string loadedFileName in fileList )
{
2014-12-11 17:19:32 -08:00
string extension = Path . GetExtension ( loadedFileName ) . ToUpper ( ) ;
if ( MeshFileIo . ValidFileExtensions ( ) . Contains ( extension )
| | extension = = ".GCODE" )
2014-10-24 14:55:27 -07:00
{
2014-12-11 17:19:32 -08:00
PrintItem printItem = new PrintItem ( ) ;
printItem . Name = Path . GetFileNameWithoutExtension ( loadedFileName ) ;
printItem . FileLocation = Path . GetFullPath ( loadedFileName ) ;
printItem . PrintItemCollectionID = LibraryData . Instance . LibraryCollection . Id ;
printItem . Commit ( ) ;
if ( MeshFileIo . ValidFileExtensions ( ) . Contains ( extension ) )
2014-10-24 15:37:03 -07:00
{
2014-12-11 17:19:32 -08:00
List < MeshGroup > meshToConvertAndSave = MeshFileIo . Load ( loadedFileName ) ;
try
{
PrintItemWrapper printItemWrapper = new PrintItemWrapper ( printItem ) ;
LibraryData . SaveToLibraryFolder ( printItemWrapper , meshToConvertAndSave ) ;
LibraryData . Instance . AddItem ( printItemWrapper ) ;
}
catch ( System . UnauthorizedAccessException )
{
UiThread . RunOnIdle ( ( state ) = >
{
//Do something special when unauthorized?
StyledMessageBox . ShowMessageBox ( null , "Oops! Unable to save changes, unauthorized access" , "Unable to save" ) ;
} ) ;
}
catch
{
UiThread . RunOnIdle ( ( state ) = >
{
StyledMessageBox . ShowMessageBox ( null , "Oops! Unable to save changes." , "Unable to save" ) ;
} ) ;
}
}
else // it is not a mesh so just add it
2014-10-24 15:37:03 -07:00
{
2014-12-11 17:19:32 -08:00
PrintItemWrapper printItemWrapper = new PrintItemWrapper ( printItem ) ;
LibraryData . Instance . AddItem ( printItemWrapper ) ;
}
2014-10-24 15:37:03 -07:00
}
2014-10-24 14:55:27 -07:00
}
}
void mergeAndSavePartsBackgroundWorker_RunWorkerCompleted ( object sender , RunWorkerCompletedEventArgs e )
{
}
}
2014-04-19 14:02:51 -07:00
}