2014-04-15 18:13:27 -07:00
/ *
Copyright ( c ) 2014 , Kevin Pope
All rights reserved .
Redistribution and use in source and binary forms , with or without
2015-04-08 15:20:10 -07:00
modification , are permitted provided that the following conditions are met :
2014-04-15 18:13:27 -07:00
1. Redistributions of source code must retain the above copyright notice , this
2015-04-08 15:20:10 -07:00
list of conditions and the following disclaimer .
2014-04-15 18:13:27 -07:00
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
2015-04-08 15:20:10 -07:00
and / or other materials provided with the distribution .
2014-04-15 18:13:27 -07:00
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
2015-04-08 15:20:10 -07:00
of the authors and should not be interpreted as representing official policies ,
2014-04-15 18:13:27 -07:00
either expressed or implied , of the FreeBSD Project .
* /
using MatterHackers.Agg ;
2015-04-08 15:20:10 -07:00
using MatterHackers.Agg.PlatformAbstract ;
2014-04-15 18:13:27 -07:00
using MatterHackers.Agg.UI ;
2015-04-08 15:20:10 -07:00
using MatterHackers.Localizations ;
2014-04-15 18:13:27 -07:00
using MatterHackers.MatterControl.DataStorage ;
2014-06-11 14:52:58 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2015-01-10 16:18:08 -08:00
using MatterHackers.PolygonMesh.Processors ;
2015-04-08 15:20:10 -07:00
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Text ;
2014-04-15 18:13:27 -07:00
namespace MatterHackers.MatterControl.PrintQueue
{
2015-04-08 15:20:10 -07:00
public class IndexArgs : EventArgs
{
internal int index ;
public int Index { get { return index ; } }
internal IndexArgs ( int index )
{
this . index = index ;
}
}
public class SwapIndexArgs : EventArgs
{
internal int indexA ;
internal int indexB ;
internal SwapIndexArgs ( int indexA , int indexB )
{
this . indexA = indexA ;
this . indexB = indexB ;
}
}
public class QueueData
{
public static readonly string SdCardFileName = "SD_CARD" ;
private List < PrintItemWrapper > printItems = new List < PrintItemWrapper > ( ) ;
public List < PrintItemWrapper > PrintItems
{
get { return printItems ; }
}
private int selectedIndex = - 1 ;
public int SelectedIndex
{
get { return selectedIndex ; }
set
{
selectedIndex = value ;
OnSelectedIndexChanged ( new IndexArgs ( value ) ) ;
}
}
public RootedObjectEventHandler ItemAdded = new RootedObjectEventHandler ( ) ;
public RootedObjectEventHandler ItemRemoved = new RootedObjectEventHandler ( ) ;
public RootedObjectEventHandler OrderChanged = new RootedObjectEventHandler ( ) ;
public RootedObjectEventHandler SelectedIndexChanged = new RootedObjectEventHandler ( ) ;
private static QueueData instance ;
public static QueueData Instance
{
get
{
if ( instance = = null )
{
instance = new QueueData ( ) ;
instance . LoadDefaultQueue ( ) ;
}
return instance ;
}
}
public void SwapItemsOnIdle ( int indexA , int indexB )
{
UiThread . RunOnIdle ( SwapItems , new SwapIndexArgs ( indexA , indexB ) ) ;
}
private void SwapItems ( object state )
{
int indexA = ( ( SwapIndexArgs ) state ) . indexA ;
int indexB = ( ( SwapIndexArgs ) state ) . indexB ;
if ( indexA > = 0 & & indexA < Count
& & indexB > = 0 & & indexB < Count
& & indexA ! = indexB )
{
PrintItemWrapper hold = PrintItems [ indexA ] ;
PrintItems [ indexA ] = PrintItems [ indexB ] ;
PrintItems [ indexB ] = hold ;
OnOrderChanged ( null ) ;
SaveDefaultQueue ( ) ;
}
}
public void OnOrderChanged ( EventArgs e )
{
OrderChanged . CallEvents ( this , e ) ;
}
public void RemoveIndexOnIdle ( int index )
{
UiThread . RunOnIdle ( RemoveIndex , new IndexArgs ( index ) ) ;
}
private void RemoveIndex ( object state )
{
IndexArgs removeArgs = state as IndexArgs ;
if ( removeArgs ! = null )
{
RemoveAt ( removeArgs . index ) ;
}
}
public void RemoveAt ( int index )
{
if ( index > = 0 & & index < Count )
{
bool ActiveItemMustStayInQueue = PrinterConnectionAndCommunication . Instance . PrinterIsPrinting | | PrinterConnectionAndCommunication . Instance . PrinterIsPaused ;
bool PartMustStayInQueue = ActiveItemMustStayInQueue & & PrintItems [ index ] = = PrinterConnectionAndCommunication . Instance . ActivePrintItem ;
if ( ! PartMustStayInQueue )
{
PrintItems . RemoveAt ( index ) ;
OnItemRemoved ( new IndexArgs ( index ) ) ;
SaveDefaultQueue ( ) ;
}
}
}
public void OnItemRemoved ( EventArgs e )
{
ItemRemoved . CallEvents ( this , e ) ;
}
public void OnSelectedIndexChanged ( EventArgs e )
{
SelectedIndexChanged . CallEvents ( this , e ) ;
}
public PrintItemWrapper GetPrintItemWrapper ( int index )
{
if ( index > = 0 & & index < PrintItems . Count )
{
return PrintItems [ index ] ;
}
return null ;
}
public int GetIndex ( PrintItemWrapper printItem )
{
return PrintItems . IndexOf ( printItem ) ;
}
public string [ ] GetItemNames ( )
{
2016-12-01 15:14:53 -08:00
List < string > itemNames = new List < string > ( ) ;
2015-04-08 15:20:10 -07:00
for ( int i = 0 ; i < PrintItems . Count ; i + + )
{
itemNames . Add ( PrintItems [ i ] . Name ) ;
}
return itemNames . ToArray ( ) ;
}
2015-07-27 19:03:54 -07:00
public string GetItemName ( int itemIndex )
{
return PrintItems [ itemIndex ] . Name ;
}
2015-04-08 15:20:10 -07:00
private bool gotBeginFileList = false ;
private event EventHandler unregisterEvents ;
public void LoadFilesFromSD ( )
{
if ( PrinterConnectionAndCommunication . Instance . PrinterIsConnected
& & ! ( PrinterConnectionAndCommunication . Instance . PrinterIsPrinting
| | PrinterConnectionAndCommunication . Instance . PrinterIsPaused ) )
{
gotBeginFileList = false ;
PrinterConnectionAndCommunication . Instance . ReadLine . RegisterEvent ( GetSdCardList , ref unregisterEvents ) ;
StringBuilder commands = new StringBuilder ( ) ;
commands . AppendLine ( "M21" ) ; // Init SD card
commands . AppendLine ( "M20" ) ; // List SD card
PrinterConnectionAndCommunication . Instance . SendLineToPrinterNow ( commands . ToString ( ) ) ;
}
}
private void GetSdCardList ( object sender , EventArgs e )
{
StringEventArgs currentEvent = e as StringEventArgs ;
if ( currentEvent ! = null )
{
if ( ! currentEvent . Data . StartsWith ( "echo:" ) )
{
switch ( currentEvent . Data )
{
case "Begin file list" :
gotBeginFileList = true ;
break ;
default :
if ( gotBeginFileList )
{
bool sdCardItemInQueue = false ;
bool validSdCardItem = false ;
2016-10-06 14:31:52 -07:00
foreach ( PrintItem item in CreateReadOnlyPartList ( false ) )
2015-04-08 15:20:10 -07:00
{
if ( item . FileLocation = = QueueData . SdCardFileName
& & item . Name = = currentEvent . Data )
{
sdCardItemInQueue = true ;
break ;
}
}
string sdCardFileExtension = currentEvent . Data . ToUpper ( ) ;
if ( sdCardFileExtension . Contains ( ".GCO" )
| | sdCardFileExtension . Contains ( ".GCODE" ) )
{
validSdCardItem = true ;
}
if ( ! sdCardItemInQueue & & validSdCardItem )
{
// If there is not alread an sd card item in the queue with this name then add it.
2015-01-14 11:51:53 -08:00
AddItem ( new PrintItemWrapper ( new PrintItem ( currentEvent . Data , QueueData . SdCardFileName ) ) ) ;
2015-04-08 15:20:10 -07:00
}
}
break ;
case "End file list" :
PrinterConnectionAndCommunication . Instance . ReadLine . UnregisterEvent ( GetSdCardList , ref unregisterEvents ) ;
break ;
}
}
}
}
2016-10-06 14:31:52 -07:00
public List < PrintItem > CreateReadOnlyPartList ( bool includeProtectedItems )
2015-04-08 15:20:10 -07:00
{
List < PrintItem > listToReturn = new List < PrintItem > ( ) ;
for ( int i = 0 ; i < Count ; i + + )
{
2016-10-06 14:31:52 -07:00
var printItem = GetPrintItemWrapper ( i ) . PrintItem ;
if ( includeProtectedItems
| | ! printItem . Protected )
{
listToReturn . Add ( printItem ) ;
}
2015-04-08 15:20:10 -07:00
}
return listToReturn ;
}
private static bool Is32Bit ( )
{
2015-01-10 16:18:08 -08:00
if ( IntPtr . Size = = 4 )
{
return true ;
}
return false ;
2015-04-08 15:20:10 -07:00
}
private PrintItemWrapper partUnderConsideration = null ;
2014-04-15 18:13:27 -07:00
2015-01-10 16:18:08 -08:00
public enum ValidateSizeOn32BitSystems { Required , Skip }
2015-04-08 15:20:10 -07:00
2015-07-20 16:09:52 -07:00
public void AddItem ( PrintItemWrapper item , int indexToInsert = - 1 , ValidateSizeOn32BitSystems checkSize = ValidateSizeOn32BitSystems . Required )
2015-04-08 15:20:10 -07:00
{
2015-01-10 16:18:08 -08:00
if ( Is32Bit ( ) )
{
2015-04-08 15:20:10 -07:00
// Check if the part we are adding is BIG. If it is warn the user and
2015-01-10 16:18:08 -08:00
// possibly don't add it
2015-01-14 11:51:53 -08:00
bool warnAboutFileSize = false ;
2015-02-18 08:10:33 -08:00
long estimatedMemoryUse = 0 ;
2015-02-18 12:20:58 -08:00
if ( File . Exists ( item . FileLocation )
& & checkSize = = ValidateSizeOn32BitSystems . Required )
2015-01-10 16:18:08 -08:00
{
2015-05-05 16:59:03 -07:00
estimatedMemoryUse = MeshFileIo . GetEstimatedMemoryUse ( item . FileLocation ) ;
2015-02-18 08:10:33 -08:00
2015-04-08 15:20:10 -07:00
if ( OsInformation . OperatingSystem = = OSType . Android )
2015-02-18 08:10:33 -08:00
{
if ( estimatedMemoryUse > 100000000 )
{
warnAboutFileSize = true ;
}
}
else
{
if ( estimatedMemoryUse > 500000000 )
{
warnAboutFileSize = true ;
}
}
2015-01-14 11:51:53 -08:00
}
2015-01-10 16:18:08 -08:00
2015-01-14 11:51:53 -08:00
if ( warnAboutFileSize )
{
partUnderConsideration = item ;
// Show a dialog and only load the part to the queue if the user clicks yes.
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-01-10 16:18:08 -08:00
{
2015-02-18 12:20:58 -08:00
string memoryWarningMessage = "Are you sure you want to add this part ({0}) to the Queue?\nThe 3D part you are trying to load may be too complicated and cause performance or stability problems.\n\nConsider reducing the geometry before proceeding." . Localize ( ) . FormatWith ( item . Name ) ;
2015-01-14 11:51:53 -08:00
StyledMessageBox . ShowMessageBox ( UserSaidToAllowAddToQueue , memoryWarningMessage , "File May Cause Problems" . Localize ( ) , StyledMessageBox . MessageType . YES_NO , "Add To Queue" , "Do Not Add" ) ;
// show a dialog to tell the user there is an update
} ) ;
return ;
}
else
{
DoAddItem ( item , indexToInsert ) ;
2015-01-10 16:18:08 -08:00
}
}
else
{
DoAddItem ( item , indexToInsert ) ;
}
2015-04-08 15:20:10 -07:00
}
2015-01-10 16:18:08 -08:00
2015-04-08 15:20:10 -07:00
private void UserSaidToAllowAddToQueue ( bool messageBoxResponse )
2015-01-10 16:18:08 -08:00
{
if ( messageBoxResponse )
{
DoAddItem ( partUnderConsideration , - 1 ) ;
}
}
2015-09-03 09:26:54 -07:00
2015-01-10 16:18:08 -08:00
private void DoAddItem ( PrintItemWrapper item , int indexToInsert )
{
if ( indexToInsert = = - 1 )
{
indexToInsert = PrintItems . Count ;
}
PrintItems . Insert ( indexToInsert , item ) ;
OnItemAdded ( new IndexArgs ( indexToInsert ) ) ;
SaveDefaultQueue ( ) ;
}
2015-04-08 15:20:10 -07:00
public void LoadDefaultQueue ( )
{
RemoveAll ( ) ;
ManifestFileHandler manifest = new ManifestFileHandler ( null ) ;
List < PrintItem > partFiles = manifest . ImportFromJson ( ) ;
if ( partFiles ! = null )
{
foreach ( PrintItem item in partFiles )
{
2015-07-20 16:09:52 -07:00
AddItem ( new PrintItemWrapper ( item ) , - 1 , QueueData . ValidateSizeOn32BitSystems . Skip ) ;
2015-04-08 15:20:10 -07:00
}
}
RemoveAllSdCardFiles ( ) ;
}
public void RemoveAllSdCardFiles ( )
{
for ( int i = Count - 1 ; i > = 0 ; i - - )
{
PrintItem printItem = PrintItems [ i ] . PrintItem ;
if ( printItem . FileLocation = = QueueData . SdCardFileName )
{
RemoveAt ( i ) ;
}
}
}
public void OnItemAdded ( EventArgs e )
{
ItemAdded . CallEvents ( this , e ) ;
}
public void SaveDefaultQueue ( )
{
2016-10-06 14:31:52 -07:00
List < PrintItem > partList = CreateReadOnlyPartList ( true ) ;
2015-04-08 15:20:10 -07:00
ManifestFileHandler manifest = new ManifestFileHandler ( partList ) ;
manifest . ExportToJson ( ) ;
}
public int Count
{
get
{
return PrintItems . Count ;
}
}
public void RemoveAll ( )
{
for ( int i = PrintItems . Count - 1 ; i > = 0 ; i - - )
{
RemoveAt ( i ) ;
}
}
}
2014-04-15 18:13:27 -07:00
}