home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / AlgoSampList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  25.3 KB  |  847 lines  |  [TEXT/KAHL]

  1. /* AlgoSampList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "AlgoSampList.h"
  31. #include "StringList.h"
  32. #include "Array.h"
  33. #include "Memory.h"
  34. #include "AlgoSampObject.h"
  35. #include "Alert.h"
  36. #include "DataMunging.h"
  37. #include "BufferedFileInput.h"
  38. #include "BufferedFileOutput.h"
  39. #include "Files.h"
  40. #include "Scrap.h"
  41.  
  42.  
  43. struct AlgoSampListRec
  44.     {
  45.         StringListRec*                    List;
  46.         struct CodeCenterRec*        CodeCenter;
  47.         struct MainWindowRec*        MainWindow;
  48.         ArrayRec*                                AlgoSampArray;
  49.         MyBoolean                                AlgoSampListChanged;
  50.     };
  51.  
  52.  
  53. #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe AlgoSampObjectScrap")
  54.  
  55.  
  56. /* create a new algorithmic sample list */
  57. AlgoSampListRec*        NewAlgoSampList(struct MainWindowRec* MainWindow,
  58.                                             struct CodeCenterRec* CodeCenter, WinType* ScreenID,
  59.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  60.     {
  61.         AlgoSampListRec*    AlgoSampList;
  62.  
  63.         AlgoSampList = (AlgoSampListRec*)AllocPtrCanFail(sizeof(AlgoSampListRec),
  64.             "AlgoSampListRec");
  65.         if (AlgoSampList == NIL)
  66.             {
  67.              FailurePoint1:
  68.                 return NIL;
  69.             }
  70.         AlgoSampList->AlgoSampArray = NewArray();
  71.         if (AlgoSampList->AlgoSampArray == NIL)
  72.             {
  73.              FailurePoint2:
  74.                 ReleasePtr((char*)AlgoSampList);
  75.                 goto FailurePoint1;
  76.             }
  77.         AlgoSampList->List = NewStringList(ScreenID,XLoc,YLoc,Width,Height,
  78.             GetScreenFont(),9,StringListDontAllowMultipleSelection,"Algorithmic Samples");
  79.         if (AlgoSampList->List == NIL)
  80.             {
  81.              FailurePoint3:
  82.                 DisposeArray(AlgoSampList->AlgoSampArray);
  83.                 goto FailurePoint2;
  84.             }
  85.         AlgoSampList->CodeCenter = CodeCenter;
  86.         AlgoSampList->MainWindow = MainWindow;
  87.         AlgoSampList->AlgoSampListChanged = False;
  88.         return AlgoSampList;
  89.     }
  90.  
  91.  
  92. /* delete the algorithmic sample list and all of the samples it contains */
  93. void                                DisposeAlgoSampList(AlgoSampListRec* AlgoSampList)
  94.     {
  95.         long                            Scan;
  96.         long                            Limit;
  97.  
  98.         CheckPtrExistence(AlgoSampList);
  99.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  100.         for (Scan = 0; Scan < Limit; Scan += 1)
  101.             {
  102.                 AlgoSampObjectRec*    AlgoSampTemp;
  103.  
  104.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  105.                     AlgoSampList->AlgoSampArray,Scan);
  106.                 DisposeAlgoSampObject(AlgoSampTemp);
  107.             }
  108.         DisposeArray(AlgoSampList->AlgoSampArray);
  109.         DisposeStringList(AlgoSampList->List);
  110.         ReleasePtr((char*)AlgoSampList);
  111.     }
  112.  
  113.  
  114. /* change the location of the algorithmic sample list in the window */
  115. void                                SetAlgoSampListLocation(AlgoSampListRec* AlgoSampList,
  116.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  117.     {
  118.         CheckPtrExistence(AlgoSampList);
  119.         SetStringListLoc(AlgoSampList->List,XLoc,YLoc,Width,Height);
  120.     }
  121.  
  122.  
  123. /* redraw the list */
  124. void                                AlgoSampListRedraw(AlgoSampListRec* AlgoSampList)
  125.     {
  126.         CheckPtrExistence(AlgoSampList);
  127.         RedrawStringList(AlgoSampList->List);
  128.     }
  129.  
  130.  
  131. /* see if the specified coordinates falls inside the sample list rectangle */
  132. MyBoolean                        AlgoSampListHitTest(AlgoSampListRec* AlgoSampList,
  133.                                             OrdType XLoc, OrdType YLoc)
  134.     {
  135.         CheckPtrExistence(AlgoSampList);
  136.         return StringListHitTest(AlgoSampList->List,XLoc,YLoc);
  137.     }
  138.  
  139.  
  140. /* handle a mouse down event for the algorithmic sample list */
  141. void                                AlgoSampListDoMouseDown(AlgoSampListRec* AlgoSampList,
  142.                                             OrdType XLoc, OrdType YLoc, ModifierFlags Modifiers)
  143.     {
  144.         CheckPtrExistence(AlgoSampList);
  145.         if (StringListMouseDown(AlgoSampList->List,XLoc,YLoc,Modifiers))
  146.             {
  147.                 /* if it returns true, then it was a double click */
  148.                 AlgoSampListOpenSelection(AlgoSampList);
  149.             }
  150.     }
  151.  
  152.  
  153. /* called when the window becomes active */
  154. void                                AlgoSampListBecomeActive(AlgoSampListRec* AlgoSampList)
  155.     {
  156.         CheckPtrExistence(AlgoSampList);
  157.         EnableStringList(AlgoSampList->List);
  158.     }
  159.  
  160.  
  161. /* called when the window becomes inactive */
  162. void                                AlgoSampListBecomeInactive(AlgoSampListRec* AlgoSampList)
  163.     {
  164.         CheckPtrExistence(AlgoSampList);
  165.         DisableStringList(AlgoSampList->List);
  166.     }
  167.  
  168.  
  169. /* called when a selection is made in another list, so that this list */
  170. /* is deselected */
  171. void                                AlgoSampListDeselect(AlgoSampListRec* AlgoSampList)
  172.     {
  173.         CheckPtrExistence(AlgoSampList);
  174.         DeselectAllStringListElements(AlgoSampList->List);
  175.     }
  176.  
  177.  
  178. /* check to see if there is a selection in this list */
  179. MyBoolean                        AlgoSampListIsThereSelection(AlgoSampListRec* AlgoSampList)
  180.     {
  181.         CheckPtrExistence(AlgoSampList);
  182.         return (GetStringListHowManySelectedItems(AlgoSampList->List) > 0);
  183.     }
  184.  
  185.  
  186. /* check to see if any of the algo samples contained in this list need */
  187. /* to be saved */
  188. MyBoolean                        DoesAlgoSampListNeedToBeSaved(AlgoSampListRec* AlgoSampList)
  189.     {
  190.         long                            Scan;
  191.         long                            Limit;
  192.         MyBoolean                    Flag;
  193.  
  194.         CheckPtrExistence(AlgoSampList);
  195.         Flag = AlgoSampList->AlgoSampListChanged;
  196.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  197.         for (Scan = 0; (Scan < Limit) && !Flag; Scan += 1)
  198.             {
  199.                 AlgoSampObjectRec*    AlgoSampTemp;
  200.  
  201.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  202.                     AlgoSampList->AlgoSampArray,Scan);
  203.                 if (HasAlgoSampObjectBeenModified(AlgoSampTemp))
  204.                     {
  205.                         Flag = True;
  206.                     }
  207.             }
  208.         return Flag;
  209.     }
  210.  
  211.  
  212. /* open an edit window for the selected algorithmic sample */
  213. void                                AlgoSampListOpenSelection(AlgoSampListRec* AlgoSampList)
  214.     {
  215.         ArrayRec*                    ListOfSelections;
  216.  
  217.         CheckPtrExistence(AlgoSampList);
  218.         ListOfSelections = GetListOfSelectedItems(AlgoSampList->List);
  219.         if (ListOfSelections != NIL)
  220.             {
  221.                 long                            Scan;
  222.                 long                            Limit;
  223.  
  224.                 Limit = ArrayGetLength(ListOfSelections);
  225.                 for (Scan = 0; Scan < Limit; Scan += 1)
  226.                     {
  227.                         AlgoSampObjectRec*    AlgoSampTemp;
  228.  
  229.                         AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  230.                         AlgoSampObjectOpenWindow(AlgoSampTemp);
  231.                     }
  232.                 DisposeArray(ListOfSelections);
  233.             }
  234.     }
  235.  
  236.  
  237. /* create a new algorithmic sample and open a window for it */
  238. void                                AlgoSampListNewAlgoSamp(AlgoSampListRec* AlgoSampList)
  239.     {
  240.         AlgoSampObjectRec*    AlgoSamp;
  241.  
  242.         CheckPtrExistence(AlgoSampList);
  243.         /* create the object */
  244.         AlgoSamp = NewAlgoSampObject(AlgoSampList->CodeCenter,AlgoSampList->MainWindow,
  245.             AlgoSampList);
  246.         if (AlgoSamp == NIL)
  247.             {
  248.              FailurePoint1:
  249.                 AlertHalt("There is not enough memory available to create a new "
  250.                     "algorithmic sample.",NIL);
  251.                 return;
  252.             }
  253.         /* add it to the string list */
  254.         if (!InsertStringListElement(AlgoSampList->List,NIL,NIL,AlgoSamp,True))
  255.             {
  256.              FailurePoint2:
  257.                 DisposeAlgoSampObject(AlgoSamp);
  258.                 goto FailurePoint1;
  259.             }
  260.         MainWindowDeselectAllOtherStringLists(AlgoSampList->MainWindow,AlgoSampList);
  261.         SelectStringListElement(AlgoSampList->List,AlgoSamp);
  262.         MakeStringListSelectionVisible(AlgoSampList->List);
  263.         /* add it to the array */
  264.         if (!ArrayAppendElement(AlgoSampList->AlgoSampArray,AlgoSamp))
  265.             {
  266.              FailurePoint3:
  267.                 RemoveStringListElement(AlgoSampList->List,AlgoSamp,True);
  268.                 goto FailurePoint2;
  269.             }
  270.         /* update our internal flags */
  271.         AlgoSampList->AlgoSampListChanged = True;
  272.         /* change the name in the list */
  273.         AlgoSampListAlgoSampNameChanged(AlgoSampList,AlgoSamp);
  274.         /* show the window */
  275.         AlgoSampObjectOpenWindow(AlgoSamp);
  276.     }
  277.  
  278.  
  279. /* delete the selected algorithmic sample */
  280. void                                AlgoSampListDeleteSelection(AlgoSampListRec* AlgoSampList)
  281.     {
  282.         ArrayRec*                    ListOfSelections;
  283.  
  284.         CheckPtrExistence(AlgoSampList);
  285.         ListOfSelections = GetListOfSelectedItems(AlgoSampList->List);
  286.         if (ListOfSelections != NIL)
  287.             {
  288.                 long                                Scan;
  289.                 long                                Limit;
  290.  
  291.                 Limit = ArrayGetLength(ListOfSelections);
  292.                 for (Scan = 0; Scan < Limit; Scan += 1)
  293.                     {
  294.                         AlgoSampObjectRec*    OneToZap;
  295.  
  296.                         OneToZap = (AlgoSampObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  297.                         AlgoSampListDeleteAlgoSamp(AlgoSampList,OneToZap);
  298.                     }
  299.                 DisposeArray(ListOfSelections);
  300.             }
  301.     }
  302.  
  303.  
  304. /* delete the explicitly specified algorithmic sample */
  305. void                                AlgoSampListDeleteAlgoSamp(AlgoSampListRec* AlgoSampList,
  306.                                             struct AlgoSampObjectRec* TheAlgoSamp)
  307.     {
  308.         long                                Scan;
  309.         long                                Limit;
  310.  
  311.         CheckPtrExistence(AlgoSampList);
  312.         MainWindowClearInstrObjects(AlgoSampList->MainWindow);
  313.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  314.         for (Scan = 0; Scan < Limit; Scan += 1)
  315.             {
  316.                 AlgoSampObjectRec*    AlgoSampTemp;
  317.  
  318.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  319.                     AlgoSampList->AlgoSampArray,Scan);
  320.                 if (TheAlgoSamp == AlgoSampTemp)
  321.                     {
  322.                         FileSpec*                    BackupFileWhere;
  323.                         FileType*                    BackupFile;
  324.                         MyBoolean                    Success = False;
  325.  
  326.                         BackupFileWhere = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
  327.                             CODE4BYTES('?','?','?','?'));
  328.                         if (BackupFileWhere != NIL)
  329.                             {
  330.                                 if (OpenFile(BackupFileWhere,&BackupFile,eReadAndWrite))
  331.                                     {
  332.                                         BufferedOutputRec*    Output;
  333.  
  334.                                         Output = NewBufferedOutput(BackupFile);
  335.                                         if (Output != NIL)
  336.                                             {
  337.                                                 if (WriteBufferedOutput(Output,sizeof(MAGICSCRAPSTRING),
  338.                                                     MAGICSCRAPSTRING))
  339.                                                     {
  340.                                                         if (AlgoSampObjectWriteOutData(TheAlgoSamp,Output)
  341.                                                             == eFileLoadNoError)
  342.                                                             {
  343.                                                                 Success = True;
  344.                                                             }
  345.                                                     }
  346.                                                 if (!EndBufferedOutput(Output))
  347.                                                     {
  348.                                                         Success = False;
  349.                                                     }
  350.                                             }
  351.                                          else
  352.                                             {
  353.                                                 CloseFile(BackupFile);
  354.                                             }
  355.                                     }
  356.                                  else
  357.                                     {
  358.                                         DeleteFile(BackupFileWhere);
  359.                                         DisposeFileSpec(BackupFileWhere);
  360.                                     }
  361.                             }
  362.                         if (Success)
  363.                             {
  364.                                 MainWindowNewDeleteUndoInfo(AlgoSampList->MainWindow,BackupFileWhere,
  365.                                     BackupFile);
  366.                                 DisposeAlgoSampObject(AlgoSampTemp);
  367.                                 RemoveStringListElement(AlgoSampList->List,AlgoSampTemp,True);
  368.                                 ArrayDeleteElement(AlgoSampList->AlgoSampArray,Scan);
  369.                                 AlgoSampList->AlgoSampListChanged = True;
  370.                             }
  371.                          else
  372.                             {
  373.                                 YesNoCancelType        Decision;
  374.  
  375.                                 Decision = AskYesNoCancel("Unable to save undo information for object.  "
  376.                                     "Delete object anyway?",NIL,"Delete","Cancel",NIL/*nothirdbutton*/);
  377.                                 if (Decision == eYes)
  378.                                     {
  379.                                         DisposeAlgoSampObject(AlgoSampTemp);
  380.                                         RemoveStringListElement(AlgoSampList->List,AlgoSampTemp,True);
  381.                                         ArrayDeleteElement(AlgoSampList->AlgoSampArray,Scan);
  382.                                         AlgoSampList->AlgoSampListChanged = True;
  383.                                     }
  384.                             }
  385.                         return;
  386.                     }
  387.             }
  388.         EXECUTE(PRERR(AllowResume,"AlgoSampListDeleteAlgoSamp:  couldn't find object"));
  389.     }
  390.  
  391.  
  392. /* the name of a algorithmic sample has changed, so the name in the scrolling */
  393. /* list must also be changed */
  394. void                                AlgoSampListAlgoSampNameChanged(AlgoSampListRec* AlgoSampList,
  395.                                             struct AlgoSampObjectRec* TheAlgoSamp)
  396.     {
  397.         char*                            AlgoSampName;
  398.  
  399.         CheckPtrExistence(AlgoSampList);
  400.         CheckPtrExistence(TheAlgoSamp);
  401.         ERROR(ArrayFindElement(AlgoSampList->AlgoSampArray,TheAlgoSamp) < 0,
  402.             PRERR(ForceAbort,"AlgoSampListAlgoSampNameChanged:  unknown algosamp"));
  403.         AlgoSampName = AlgoSampObjectGetNameCopy(TheAlgoSamp);
  404.         if (AlgoSampName != NIL)
  405.             {
  406.                 char*                            AlgoSampNameNullTerminated;
  407.  
  408.                 AlgoSampNameNullTerminated = BlockToStringCopy(AlgoSampName);
  409.                 if (AlgoSampNameNullTerminated != NIL)
  410.                     {
  411.                         ChangeStringListElementName(AlgoSampList->List,
  412.                             AlgoSampNameNullTerminated,TheAlgoSamp);
  413.                         ReleasePtr(AlgoSampNameNullTerminated);
  414.                     }
  415.                 ReleasePtr(AlgoSampName);
  416.             }
  417.     }
  418.  
  419.  
  420. /* look for a specified algorithmic sample.  returns NIL if not found.  the name is */
  421. /* NOT null terminated */
  422. AlgoSampObjectRec*    AlgoSampListLookupNamedAlgoSamp(
  423.                                             AlgoSampListRec* AlgoSampList, char* Name)
  424.     {
  425.         long                            Scan;
  426.         long                            Limit;
  427.  
  428.         CheckPtrExistence(AlgoSampList);
  429.         CheckPtrExistence(Name);
  430.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  431.         for (Scan = 0; Scan < Limit; Scan += 1)
  432.             {
  433.                 AlgoSampObjectRec*    AlgoSamp;
  434.                 char*                                NameCopy;
  435.  
  436.                 AlgoSamp = (AlgoSampObjectRec*)ArrayGetElement(AlgoSampList->AlgoSampArray,Scan);
  437.                 NameCopy = AlgoSampObjectGetNameCopy(AlgoSamp);
  438.                 if (NameCopy != NIL)
  439.                     {
  440.                         if (PtrSize(Name) == PtrSize(NameCopy))
  441.                             {
  442.                                 if (MemEqu(Name,NameCopy,PtrSize(Name)))
  443.                                     {
  444.                                         ReleasePtr(NameCopy);
  445.                                         return AlgoSamp;
  446.                                     }
  447.                             }
  448.                         ReleasePtr(NameCopy);
  449.                     }
  450.             }
  451.         return NIL;
  452.     }
  453.  
  454.  
  455. /* remove all data arrays for all algorithmic samples */
  456. void                                AlgoSampListUnbuildAll(AlgoSampListRec* AlgoSampList)
  457.     {
  458.         long                            Scan;
  459.         long                            Limit;
  460.  
  461.         CheckPtrExistence(AlgoSampList);
  462.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  463.         for (Scan = 0; Scan < Limit; Scan += 1)
  464.             {
  465.                 AlgoSampObjectRec*    AlgoSampTemp;
  466.  
  467.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  468.                     AlgoSampList->AlgoSampArray,Scan);
  469.                 AlgoSampObjectUnbuild(AlgoSampTemp);
  470.             }
  471.     }
  472.  
  473.  
  474. /* build all algorithmic sample tables.  returns True if successful. */
  475. MyBoolean                        AlgoSampListMakeUpToDate(AlgoSampListRec* AlgoSampList)
  476.     {
  477.         long                            Scan;
  478.         long                            Limit;
  479.  
  480.         CheckPtrExistence(AlgoSampList);
  481.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  482.         for (Scan = 0; Scan < Limit; Scan += 1)
  483.             {
  484.                 AlgoSampObjectRec*    AlgoSampTemp;
  485.  
  486.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  487.                     AlgoSampList->AlgoSampArray,Scan);
  488.                 if (!AlgoSampObjectMakeUpToDate(AlgoSampTemp))
  489.                     {
  490.                         return False;
  491.                     }
  492.             }
  493.         return True;
  494.     }
  495.  
  496.  
  497. /* document's name changed, so we have to update the windows */
  498. void                                AlgoSampListGlobalNameChange(AlgoSampListRec* AlgoSampList,
  499.                                             char* NewFilename)
  500.     {
  501.         long                            Scan;
  502.         long                            Limit;
  503.  
  504.         CheckPtrExistence(AlgoSampList);
  505.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  506.         for (Scan = 0; Scan < Limit; Scan += 1)
  507.             {
  508.                 AlgoSampObjectRec*    AlgoSampTemp;
  509.  
  510.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  511.                     AlgoSampList->AlgoSampArray,Scan);
  512.                 AlgoSampObjectGlobalNameChange(AlgoSampTemp,NewFilename);
  513.             }
  514.     }
  515.  
  516.  
  517. /*   4-byte little endian number of algorithmic sample objects (positive 2s complement) */
  518. /*   n-byte data for the algorithmic sample objects */
  519.  
  520.  
  521. /* read algorithmic sample objects from a file.  returns True if completely successful. */
  522. FileLoadingErrors        AlgoSampListReadData(AlgoSampListRec* AlgoSampList,
  523.                                             struct BufferedInputRec* Input)
  524.     {
  525.         signed long                NumSampleObjects;
  526.         long                            Scan;
  527.  
  528.         CheckPtrExistence(AlgoSampList);
  529.         CheckPtrExistence(Input);
  530.  
  531.         /*   4-byte little endian number of objects (positive 2s complement) */
  532.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumSampleObjects))
  533.             {
  534.                 return eFileLoadDiskError;
  535.             }
  536.         if (NumSampleObjects < 0)
  537.             {
  538.                 return eFileLoadBadFormat;
  539.             }
  540.  
  541.         /* load things from the file */
  542.         for (Scan = 0; Scan < NumSampleObjects; Scan += 1)
  543.             {
  544.                 AlgoSampObjectRec*    AlgoSampTemp EXECUTE(= (AlgoSampObjectRec*)0x81818181);
  545.                 FileLoadingErrors        Error;
  546.  
  547.                 /* read in the object */
  548.                 Error = AlgoSampObjectNewFromFile(&AlgoSampTemp,Input,AlgoSampList->CodeCenter,
  549.                     AlgoSampList->MainWindow,AlgoSampList);
  550.                 if (Error != eFileLoadNoError)
  551.                     {
  552.                      FailurePoint1:
  553.                         return Error;
  554.                     }
  555.                 CheckPtrExistence(AlgoSampTemp);
  556.                 /* add it to the string list */
  557.                 if (!InsertStringListElement(AlgoSampList->List,NIL,NIL,AlgoSampTemp,True))
  558.                     {
  559.                      FailurePoint2:
  560.                         DisposeAlgoSampObject(AlgoSampTemp);
  561.                         Error = eFileLoadOutOfMemory;
  562.                         goto FailurePoint1;
  563.                     }
  564.                 /* add it to the array */
  565.                 if (!ArrayAppendElement(AlgoSampList->AlgoSampArray,AlgoSampTemp))
  566.                     {
  567.                      FailurePoint3:
  568.                         RemoveStringListElement(AlgoSampList->List,AlgoSampTemp,True);
  569.                         goto FailurePoint2;
  570.                     }
  571.                 /* change the name in the list */
  572.                 AlgoSampListAlgoSampNameChanged(AlgoSampList,AlgoSampTemp);
  573.             }
  574.  
  575.         return eFileLoadNoError;
  576.     }
  577.  
  578.  
  579. /* write algorithmic sample objects to a file.  returns True if completely successful. */
  580. FileLoadingErrors        AlgoSampListWriteData(AlgoSampListRec* AlgoSampList,
  581.                                             struct BufferedOutputRec* Output)
  582.     {
  583.         long                            NumberOfObjects;
  584.         long                            Scan;
  585.  
  586.         CheckPtrExistence(AlgoSampList);
  587.         CheckPtrExistence(Output);
  588.  
  589.         /*   4-byte little endian number of objects (positive 2s complement) */
  590.         NumberOfObjects = ArrayGetLength(AlgoSampList->AlgoSampArray);
  591.         if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfObjects))
  592.             {
  593.                 return eFileLoadDiskError;
  594.             }
  595.  
  596.         /* write out the objects */
  597.         for (Scan = 0; Scan < NumberOfObjects; Scan += 1)
  598.             {
  599.                 AlgoSampObjectRec*    AlgoSampTemp;
  600.                 FileLoadingErrors        Error;
  601.  
  602.                 /* get the object */
  603.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  604.                     AlgoSampList->AlgoSampArray,Scan);
  605.                 /* write it out */
  606.                 Error = AlgoSampObjectWriteOutData(AlgoSampTemp,Output);
  607.                 /* handle any errors */
  608.                 if (Error != eFileLoadNoError)
  609.                     {
  610.                         return Error;
  611.                     }
  612.             }
  613.  
  614.         return eFileLoadNoError;
  615.     }
  616.  
  617.  
  618. /* after a file has been saved, this is called to mark all objects as not modified. */
  619. void                                AlgoSampListMarkAllObjectsSaved(AlgoSampListRec* AlgoSampList)
  620.     {
  621.         long                            Scan;
  622.         long                            Limit;
  623.  
  624.         CheckPtrExistence(AlgoSampList);
  625.         Limit = ArrayGetLength(AlgoSampList->AlgoSampArray);
  626.         for (Scan = 0; Scan < Limit; Scan += 1)
  627.             {
  628.                 AlgoSampObjectRec*    AlgoSampTemp;
  629.  
  630.                 AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(
  631.                     AlgoSampList->AlgoSampArray,Scan);
  632.                 AlgoSampObjectMarkAsSaved(AlgoSampTemp);
  633.             }
  634.         AlgoSampList->AlgoSampListChanged = False;
  635.     }
  636.  
  637.  
  638. /* copy the selected object in the list to the clipboard.  return False if failed. */
  639. MyBoolean                        AlgoSampListCopyObject(AlgoSampListRec* AlgoSampList)
  640.     {
  641.         ArrayRec*                            ListOfSelections;
  642.         MyBoolean                            TotalSuccessFlag = False;
  643.  
  644.         CheckPtrExistence(AlgoSampList);
  645.         ListOfSelections = GetListOfSelectedItems(AlgoSampList->List);
  646.         if (ListOfSelections != NIL)
  647.             {
  648.                 if (ArrayGetLength(ListOfSelections) >= 1)
  649.                     {
  650.                         AlgoSampObjectRec*    AlgoSampTemp;
  651.                         FileSpec*                        TempFileLocation;
  652.  
  653.                         AlgoSampTemp = (AlgoSampObjectRec*)ArrayGetElement(ListOfSelections,0);
  654.                         /* open the temporary file */
  655.                         TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  656.                             CODE4BYTES('\?','\?','\?','\?'));
  657.                         if (TempFileLocation != NIL)
  658.                             {
  659.                                 FileType*                            FileDescriptor;
  660.  
  661.                                 if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  662.                                     {
  663.                                         BufferedOutputRec*        BufferedFile;
  664.  
  665.                                         BufferedFile = NewBufferedOutput(FileDescriptor);
  666.                                         if (BufferedFile != NIL)
  667.                                             {
  668.                                                 MyBoolean                            WriteSucceeded = False;
  669.  
  670.                                                 if (WriteBufferedOutput(BufferedFile,sizeof(MAGICSCRAPSTRING),
  671.                                                     MAGICSCRAPSTRING))
  672.                                                     {
  673.                                                         if (AlgoSampObjectWriteOutData(AlgoSampTemp,BufferedFile)
  674.                                                             == eFileLoadNoError)
  675.                                                             {
  676.                                                                 WriteSucceeded = True;
  677.                                                             }
  678.                                                     }
  679.                                                 if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  680.                                                     {
  681.                                                         char*                            Buffer;
  682.                                                         long                            NumberOfBytes;
  683.  
  684.                                                         NumberOfBytes = GetFileLength(FileDescriptor);
  685.                                                         Buffer = AllocPtrCanFail(NumberOfBytes,
  686.                                                             "AlgoSampListCopyObject:  scrap buffer");
  687.                                                         if (Buffer != NIL)
  688.                                                             {
  689.                                                                 if (SetFilePosition(FileDescriptor,0))
  690.                                                                     {
  691.                                                                         if (0 == ReadFromFile(FileDescriptor,
  692.                                                                             Buffer,NumberOfBytes))
  693.                                                                             {
  694.                                                                                 if (SetScrapToThis(Buffer))
  695.                                                                                     {
  696.                                                                                         TotalSuccessFlag = True;
  697.                                                                                     }
  698.                                                                             }
  699.                                                                     }
  700.                                                                 ReleasePtr(Buffer);
  701.                                                             }
  702.                                                     }
  703.                                             }
  704.                                         CloseFile(FileDescriptor);
  705.                                     }
  706.                                 DeleteFile(TempFileLocation);
  707.                                 DisposeFileSpec(TempFileLocation);
  708.                             }
  709.                     }
  710.                 DisposeArray(ListOfSelections);
  711.             }
  712.         return TotalSuccessFlag;
  713.     }
  714.  
  715.  
  716. /* try to paste the clipboard in as an algorithmic sample object.  returns False if */
  717. /* it failed or the clipboard did not contain an algorithmic sample object. */
  718. MyBoolean                        AlgoSampListPasteObject(AlgoSampListRec* AlgoSampList)
  719.     {
  720.         MyBoolean                    TotalSuccessFlag = False;
  721.         char*                            Scrap;
  722.  
  723.         CheckPtrExistence(AlgoSampList);
  724.         Scrap = GetCopyOfScrap();
  725.         if (Scrap != NIL)
  726.             {
  727.                 FileSpec*                    TempFileLocation;
  728.  
  729.                 TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  730.                     CODE4BYTES('\?','\?','\?','\?'));
  731.                 if (TempFileLocation != NIL)
  732.                     {
  733.                         FileType*                            FileDescriptor;
  734.  
  735.                         if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  736.                             {
  737.                                 BufferedOutputRec*        BufferedFile;
  738.  
  739.                                 BufferedFile = NewBufferedOutput(FileDescriptor);
  740.                                 if (BufferedFile != NIL)
  741.                                     {
  742.                                         MyBoolean                            WriteSucceeded = False;
  743.  
  744.                                         if (WriteBufferedOutput(BufferedFile,PtrSize(Scrap),Scrap))
  745.                                             {
  746.                                                 WriteSucceeded = True;
  747.                                             }
  748.                                         if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  749.                                             {
  750.                                                 TotalSuccessFlag = AlgoSampListPasteFromFile(
  751.                                                     AlgoSampList,FileDescriptor);
  752.                                             }
  753.                                     }
  754.                                 CloseFile(FileDescriptor);
  755.                             }
  756.                         DeleteFile(TempFileLocation);
  757.                         DisposeFileSpec(TempFileLocation);
  758.                     }
  759.                 ReleasePtr(Scrap);
  760.             }
  761.         return TotalSuccessFlag;
  762.     }
  763.  
  764.  
  765. /* try to paste an algorithmic sample object from the file */
  766. MyBoolean                        AlgoSampListPasteFromFile(AlgoSampListRec* AlgoSampList,
  767.                                             struct FileType* File)
  768.     {
  769.         MyBoolean                    TotalSuccessFlag = False;
  770.  
  771.         CheckPtrExistence(AlgoSampList);
  772.         if (SetFilePosition(File,0))
  773.             {
  774.                 BufferedInputRec*    InputFile;
  775.  
  776.                 InputFile = NewBufferedInput(File);
  777.                 if (InputFile != NIL)
  778.                     {
  779.                         char                            HeaderTest[sizeof(MAGICSCRAPSTRING)];
  780.  
  781.                         if (ReadBufferedInput(InputFile,sizeof(MAGICSCRAPSTRING),HeaderTest))
  782.                             {
  783.                                 if (MemEqu(MAGICSCRAPSTRING,HeaderTest,sizeof(MAGICSCRAPSTRING)))
  784.                                     {
  785.                                         AlgoSampObjectRec*        AlgoSampTemp EXECUTE(= (AlgoSampObjectRec*)0x81818181);
  786.  
  787.                                         if (eFileLoadNoError == AlgoSampObjectNewFromFile(&AlgoSampTemp,InputFile,
  788.                                             AlgoSampList->CodeCenter,AlgoSampList->MainWindow,AlgoSampList))
  789.                                             {
  790.                                                 CheckPtrExistence(AlgoSampTemp);
  791.                                                 /* add it to the scrolling object list */
  792.                                                 if (!InsertStringListElement(AlgoSampList->List,NIL,NIL,AlgoSampTemp,True))
  793.                                                     {
  794.                                                      FailurePoint:
  795.                                                         DisposeAlgoSampObject(AlgoSampTemp);
  796.                                                     }
  797.                                                  else
  798.                                                     {
  799.                                                         MainWindowDeselectAllOtherStringLists(AlgoSampList->MainWindow,AlgoSampList);
  800.                                                         SelectStringListElement(AlgoSampList->List,AlgoSampTemp);
  801.                                                         MakeStringListSelectionVisible(AlgoSampList->List);
  802.                                                         /* add it to the array */
  803.                                                         if (!ArrayAppendElement(AlgoSampList->AlgoSampArray,AlgoSampTemp))
  804.                                                             {
  805.                                                                 RemoveStringListElement(AlgoSampList->List,AlgoSampTemp,True);
  806.                                                                 goto FailurePoint;
  807.                                                             }
  808.                                                          else
  809.                                                             {
  810.                                                                 /* change the name in the list */
  811.                                                                 AlgoSampListAlgoSampNameChanged(AlgoSampList,AlgoSampTemp);
  812.                                                                 TotalSuccessFlag = True;
  813.                                                                 AlgoSampList->AlgoSampListChanged = True;
  814.                                                             }
  815.                                                     }
  816.                                             }
  817.                                     }
  818.                             }
  819.                         EndBufferedInput(InputFile);
  820.                     }
  821.             }
  822.         return TotalSuccessFlag;
  823.     }
  824.  
  825.  
  826. /* find out how many algorithmic samples there are in this list */
  827. long                                AlgoSampListHowMany(AlgoSampListRec* AlgoSampList)
  828.     {
  829.         CheckPtrExistence(AlgoSampList);
  830.         return ArrayGetLength(AlgoSampList->AlgoSampArray);
  831.     }
  832.  
  833.  
  834. /* get an indexed algorithmic sample from the list */
  835. struct AlgoSampObjectRec*    AlgoSampListGetIndexedAlgoSamp(AlgoSampListRec* AlgoSampList,
  836.                                             long Index)
  837.     {
  838.         AlgoSampObjectRec*    AlgoSamp;
  839.  
  840.         CheckPtrExistence(AlgoSampList);
  841.         ERROR((Index < 0) || (Index >= AlgoSampListHowMany(AlgoSampList)),PRERR(ForceAbort,
  842.             "AlgoSampListGetIndexedAlgoSamp:  index out of range"));
  843.         AlgoSamp = (AlgoSampObjectRec*)ArrayGetElement(AlgoSampList->AlgoSampArray,Index);
  844.         CheckPtrExistence(AlgoSamp);
  845.         return AlgoSamp;
  846.     }
  847.