home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / TextEditor / source / WindowStuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-24  |  33.3 KB  |  1,311 lines  |  [TEXT/KAHL]

  1. /* WindowStuff.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Stupid Fred's Text Editor                                              */
  5. /*    Written by Thomas R. Lawrence, 1993 - 1994.                            */
  6. /*                                                                           */
  7. /*    This software is Public Domain; it may be used for any purpose         */
  8. /*    whatsoever without restriction.                                        */
  9. /*                                                                           */
  10. /*    This package is distributed in the hope that it will be useful,        */
  11. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  12. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   */
  13. /*                                                                           */
  14. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  15. /*                                                                           */
  16. /*****************************************************************************/
  17.  
  18. #include "MiscInfo.h"
  19. #include "Audit.h"
  20. #include "Debug.h"
  21. #include "Definitions.h"
  22.  
  23. #include "WindowStuff.h"
  24. #include "WindowDispatcher.h"
  25. #include "TextEdit.h"
  26. #include "Files.h"
  27. #include "Array.h"
  28. #include "Memory.h"
  29. #include "Alert.h"
  30. #include "Menus.h"
  31. #include "DataMunging.h"
  32. #include "Main.h"
  33. #include "GrowIcon.h"
  34. #include "Numbers.h"
  35. #include "NumberDialog.h"
  36. #include "FindDialog.h"
  37. #include "StringDialog.h"
  38.  
  39.  
  40. #define MINTABCOUNT (1)
  41. #define MAXTABCOUNT (255)
  42.  
  43. #define WindowOverlayCycle (5)
  44. #define WindowDownOffset (20)
  45. #define WindowRightOffset (6)
  46. #define WindowScreenBorder (1)
  47.  
  48. #define DEFAULTFONTSIZE (9)
  49.  
  50. typedef enum {eMacLF EXECUTE(= -23767), eDosLF, eUnixLF} LineFeedTypes;
  51.  
  52.  
  53. struct MyWinRec
  54.     {
  55.         WinType*                        ScreenID;
  56.         TextEditRec*                TheEdit;
  57.         MenuItemType*                WindowMenuEntry;
  58.         GenericWindowRec*        GenericWindow;
  59.         MyBoolean                        NeedsToBeSaved;
  60.  
  61.         FontType                        TheFont;
  62.         FontSizeType                FontSize;
  63.  
  64.         MyBoolean                        EverSaved;
  65.         FileSpec*                        FileLocation; /* valid only if EverSaved == True */
  66.         FileType*                        TheFile; /* valid only if EverSaved == True */
  67.         LineFeedTypes                LineFeed;
  68.     };
  69.  
  70.  
  71. static ArrayRec*                    MasterWindowList;
  72.  
  73. static char*                            SearchKey;
  74. static char*                            ReplaceThang;
  75. static char*                            PrefixPtr;
  76.  
  77.  
  78. MyBoolean                        InitWindowStuff(void)
  79.     {
  80.         MasterWindowList = NewArray();
  81.         if (MasterWindowList == NIL)
  82.             {
  83.              FailurePoint1:
  84.                 return False;
  85.             }
  86.         SearchKey = AllocPtrCanFail(0,"SearchKey");
  87.         if (SearchKey == NIL)
  88.             {
  89.              FailurePoint2:
  90.                 DisposeArray(MasterWindowList);
  91.                 goto FailurePoint1;
  92.             }
  93.         ReplaceThang = AllocPtrCanFail(0,"ReplaceText");
  94.         if (ReplaceThang == NIL)
  95.             {
  96.              FailurePoint3:
  97.                 ReleasePtr(SearchKey);
  98.                 goto FailurePoint2;
  99.             }
  100.         PrefixPtr = AllocPtrCanFail(0,"PrefixPtr");
  101.         if (PrefixPtr == NIL)
  102.             {
  103.              FailurePoint4:
  104.                 ReleasePtr(ReplaceThang);
  105.                 goto FailurePoint3;
  106.             }
  107.         return True;
  108.     }
  109.  
  110.  
  111. void                                KillWindowStuff(void)
  112.     {
  113.         DisposeArray(MasterWindowList);
  114.         ReleasePtr(SearchKey);
  115.         ReleasePtr(ReplaceThang);
  116.         ReleasePtr(PrefixPtr);
  117.     }
  118.  
  119.  
  120. static LineFeedTypes    IdentifyLineFeed(char* String)
  121.     {
  122.         if (String[0] == 0x0a)
  123.             {
  124.                 return eUnixLF;
  125.             }
  126.         if (String[0] == 0x0d)
  127.             {
  128.                 if (String[1] == 0x0a)
  129.                     {
  130.                         return eDosLF;
  131.                     }
  132.                  else
  133.                     {
  134.                         return eMacLF;
  135.                     }
  136.             }
  137.         EXECUTE(PRERR(AllowResume,"IdentifyLineFeed:  couldn't identify line feed"));
  138.         return eDosLF; /* default to MS-DOS */
  139.     }
  140.  
  141.  
  142. static void                    CalculateProperLineFeed(MyWinRec* Window, char* RawBlock)
  143.     {
  144.         long                            Scan;
  145.         long                            Limit;
  146.  
  147.         CheckPtrExistence(Window);
  148.         CheckPtrExistence(RawBlock);
  149.         Limit = PtrSize(RawBlock);
  150.         Scan = 0;
  151.         while (Scan < Limit)
  152.             {
  153.                 if ((RawBlock[Scan] == 0x0a) || (RawBlock[Scan] == 0x0d))
  154.                     {
  155.                         char                        Buffer[3];
  156.  
  157.                         Buffer[0] = RawBlock[Scan];
  158.                         if (Scan + 1 < Limit)
  159.                             {
  160.                                 Buffer[1] = RawBlock[Scan + 1];
  161.                                 Buffer[2] = 0;
  162.                             }
  163.                          else
  164.                             {
  165.                                 Buffer[2] = 0;
  166.                             }
  167.                         Window->LineFeed = IdentifyLineFeed(Buffer);
  168.                         return;
  169.                     }
  170.                 Scan += 1;
  171.             }
  172.         Window->LineFeed = IdentifyLineFeed(SYSTEMLINEFEED);
  173.     }
  174.  
  175.  
  176. char*                                GetProperStaticLineFeed(MyWinRec* Window)
  177.     {
  178.         CheckPtrExistence(Window);
  179.         switch (Window->LineFeed)
  180.             {
  181.                 default:
  182.                     EXECUTE(PRERR(ForceAbort,"GetProperStaticLineFeed:  unknown line feed type"));
  183.                     break;
  184.                 case eMacLF:
  185.                     return "\x0d";
  186.                 case eUnixLF:
  187.                     return "\x0a";
  188.                 case eDosLF:
  189.                     return "\x0d\x0a";
  190.             }
  191.     }
  192.  
  193.  
  194. MyWinRec*                        OpenDocument(struct FileSpec* Where)
  195.     {
  196.         MyWinRec*                    Window;
  197.         long                            Limit;
  198.         long                            Scan;
  199.         OrdType                        X;
  200.         OrdType                        Y;
  201.         MyBoolean                    MemoryFailure EXECUTE(= -999);
  202.         char*                            FilenameNull;
  203.         char                            MenuShortcut;
  204.  
  205.         /* allocate the window record */
  206.         Window = (MyWinRec*)AllocPtrCanFail(sizeof(MyWinRec),"MyWinRec");
  207.         if (Window == NIL)
  208.             {
  209.                 MemoryFailure = True;
  210.              FailurePoint1:
  211.                 ERROR((MemoryFailure != True) && (MemoryFailure != False),PRERR(ForceAbort,
  212.                     "OpenDocument:  forgot to set MemoryFailure"));
  213.                 if (Where != NIL)
  214.                     {
  215.                         DisposeFileSpec(Where);
  216.                     }
  217.                 if (MemoryFailure)
  218.                     {
  219.                         AlertHalt("There is not enough memory available to open a new window.",NIL);
  220.                     }
  221.                 return NIL;
  222.             }
  223.  
  224.         /* search for a hole in the window list so that we can add windows */
  225.         /* in the holes to get a nice stacking effect on the screen. */
  226.         Limit = ArrayGetLength(MasterWindowList);
  227.         Scan = 0;
  228.         while (Scan < Limit)
  229.             {
  230.                 if (ArrayGetElement(MasterWindowList,Scan) == NIL)
  231.                     {
  232.                         goto FoundAHolePoint;
  233.                     }
  234.                 Scan += 1;
  235.             }
  236.         ERROR(Scan != Limit,PRERR(ForceAbort,"OpenDocument:  loop invariant error"));
  237.         if (!ArrayAppendElement(MasterWindowList,NIL))
  238.             {
  239.                 MemoryFailure = True;
  240.              FailurePoint2:
  241.                 ReleasePtr((char*)Window);
  242.                 goto FailurePoint1;
  243.             }
  244.         /* fallthrough:  Scan is still a proper index since we appended NIL. */
  245.         /* in event of errors, we don't have to delete from array since we appended */
  246.         /* NIL instead of the window pointer */
  247.      FoundAHolePoint:
  248.         ArraySetElement(MasterWindowList,Window,Scan);
  249.  
  250.         /* create the new window */
  251.         X = WindowScreenBorder + (WindowOverlayCycle - (Scan % WindowOverlayCycle))
  252.             * WindowRightOffset;
  253.         Y = WindowTitleBarHeight(eDocumentWindow) + WindowScreenBorder
  254.             + (Scan % WindowOverlayCycle) * WindowDownOffset;
  255.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,eWindowZoomable,
  256.             eWindowResizable,X,Y,GetScreenWidth() - X - WindowScreenBorder
  257.             - WindowOtherEdgeWidths(eDocumentWindow),GetScreenHeight() - Y
  258.             - WindowScreenBorder - WindowOtherEdgeWidths(eDocumentWindow),
  259.             (void (*)(void*))&WindowUpdate,Window);
  260.         if (Window->ScreenID == NIL)
  261.             {
  262.                 MemoryFailure = True;
  263.              FailurePoint3:
  264.                 ArraySetElement(MasterWindowList,NIL,Scan);
  265.                 goto FailurePoint2;
  266.             }
  267.  
  268.         Window->TheFont = GetMonospacedFont();
  269.         Window->FontSize = DEFAULTFONTSIZE;
  270.         Window->TheEdit = NewTextEdit(Window->ScreenID,eTEVScrollBar | eTEHScrollBar,
  271.             Window->TheFont,Window->FontSize,-1,-1,GetWindowWidth(Window->ScreenID) + 2,
  272.             GetWindowHeight(Window->ScreenID) + 2);
  273.         if (Window->TheEdit == NIL)
  274.             {
  275.                 MemoryFailure = True;
  276.              FailurePoint4:
  277.                 KillWindow(Window->ScreenID);
  278.                 goto FailurePoint3;
  279.             }
  280.  
  281.         /* register window with window handler */
  282.         Window->GenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  283.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&WindowDoIdle,
  284.             (void (*)(void*))&WindowBecomeActive,
  285.             (void (*)(void*))&WindowBecomeInactive,
  286.             (void (*)(void*))&WindowResized,
  287.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&WindowDoMouseDown,
  288.             (void (*)(unsigned char,ModifierFlags,void*))&WindowDoKeyDown,
  289.             (void (*)(void*))&WindowClose,
  290.             (void (*)(void*))&WindowMenuSetup,
  291.             (void (*)(void*,MenuItemType*))&WindowDoMenuCommand);
  292.         if (Window->GenericWindow == NIL)
  293.             {
  294.                 MemoryFailure = True;
  295.              FailurePoint5:
  296.                 DisposeTextEdit(Window->TheEdit);
  297.                 goto FailurePoint4;
  298.             }
  299.  
  300.         /* figure out what the filename is */
  301.         if (Where != NIL)
  302.             {
  303.                 char*                            Filename;
  304.  
  305.                 Filename = ExtractFileName(Where);
  306.                 if (Filename == NIL)
  307.                     {
  308.                         MemoryFailure = True;
  309.                      FailurePoint6:
  310.                         CheckOutDyingWindow(Window->GenericWindow);
  311.                         goto FailurePoint5;
  312.                     }
  313.                 FilenameNull = BlockToStringCopy(Filename);
  314.                 ReleasePtr(Filename);
  315.             }
  316.          else
  317.             {
  318.                 FilenameNull = StringFromRaw("Untitled");
  319.             }
  320.         if (FilenameNull == NIL)
  321.             {
  322.                 MemoryFailure = True;
  323.                 goto FailurePoint6;
  324.             }
  325.  
  326.         /* set the name of the window */
  327.         SetWindowName(Window->ScreenID,FilenameNull);
  328.  
  329.         /* create a menu item */
  330.         /* we assign the keyboard shortcuts '1'..'9' to the first 9 files, and */
  331.         /* '0' for the 10th. */
  332.         if ((Scan >= 0) && (Scan <= 8))
  333.             {
  334.                 MenuShortcut = Scan + '1';
  335.             }
  336.         else if (Scan == 9)
  337.             {
  338.                 MenuShortcut = '0';
  339.             }
  340.         else
  341.             {
  342.                 MenuShortcut = 0;
  343.             }
  344.         Window->WindowMenuEntry = MakeNewMenuItem(mmWindowsMenu,FilenameNull,MenuShortcut);
  345.         if (Window->WindowMenuEntry == NIL)
  346.             {
  347.                 MemoryFailure = True;
  348.              FailurePoint7:
  349.                 ReleasePtr(FilenameNull);
  350.                 goto FailurePoint6;
  351.             }
  352.  
  353.         /* set the flag that knows if the file has ever been saved */
  354.         Window->EverSaved = (Where != NIL);
  355.         Window->FileLocation = Where;
  356.  
  357.         Window->LineFeed = IdentifyLineFeed(SYSTEMLINEFEED);
  358.  
  359.         /* if the file is a real file, then read the data in */
  360.         if (Where != NIL)
  361.             {
  362.                 long                            FileLength;
  363.                 char*                            RawBlock;
  364.                 MyBoolean                    SucceedFlag;
  365.  
  366.                 /* open the file */
  367.                 if (!OpenFile(Where,&(Window->TheFile),eReadAndWrite))
  368.                     {
  369.                         MemoryFailure = False; /* we have our own error message */
  370.                      FailurePoint8:
  371.                         KillMenuItem(Window->WindowMenuEntry);
  372.                         if (!MemoryFailure)
  373.                             {
  374.                                 AlertHalt("A disk error occurred and the file '_' "
  375.                                     "couldn't be opened.",FilenameNull);
  376.                             }
  377.                         goto FailurePoint7;
  378.                     }
  379.                 /* find out how long the file is and try to allocate a block for it */
  380.                 FileLength = GetFileLength(Window->TheFile);
  381.                 RawBlock = AllocPtrCanFail(FileLength,"RawFileData");
  382.                 if (RawBlock == NIL)
  383.                     {
  384.                         MemoryFailure = True;
  385.                      FailurePoint9:
  386.                         CloseFile(Window->TheFile);
  387.                         goto FailurePoint8;
  388.                     }
  389.                 /* try to read all the data in.  failing to read all the data is not */
  390.                 /* considered a fatal error, but warrents a notification. */
  391.                 SetFilePosition(Window->TheFile,0);
  392.                 if (0 != ReadFromFile(Window->TheFile,&(RawBlock[0]),FileLength))
  393.                     {
  394.                         AlertWarning("A disk error occurred andt he file '_' couldn't be "
  395.                             "completely loaded.",FilenameNull);
  396.                     }
  397.                 /* figure out what linefeed was used */
  398.                 CalculateProperLineFeed(Window,RawBlock);
  399.                 /* now, try to put the data block into the text edit object */
  400.                 SucceedFlag = TextEditNewRawData(Window->TheEdit,RawBlock,
  401.                     GetProperStaticLineFeed(Window));
  402.                 /* dump the raw block */
  403.                 ReleasePtr(RawBlock);
  404.                 if (!SucceedFlag)
  405.                     {
  406.                         MemoryFailure = True;
  407.                      FailurePoint10:
  408.                         goto FailurePoint9;
  409.                     }
  410.                 /* indicate that it has been saved (since no changes have been made) */
  411.                 TextEditHasBeenSaved(Window->TheEdit);
  412.             }
  413.         SetTextEditAutoIndent(Window->TheEdit,True); /* default to auto-indent */
  414.         Window->NeedsToBeSaved = False;
  415.  
  416.         ReleasePtr(FilenameNull);
  417.         return Window;
  418.     }
  419.  
  420.  
  421. MyBoolean                        CloseDocument(MyWinRec* Window)
  422.     {
  423.         CheckPtrExistence(Window);
  424.         if (Window->NeedsToBeSaved || TextEditDoesItNeedToBeSaved(Window->TheEdit))
  425.             {
  426.                 char*                            FilenameNull;
  427.                 YesNoCancelType        Options;
  428.  
  429.                 if (Window->EverSaved)
  430.                     {
  431.                         char*                            Filename;
  432.  
  433.                         Filename = ExtractFileName(Window->FileLocation);
  434.                         if (Filename == NIL)
  435.                             {
  436.                                 /* I sure hope this sort of thing never happens */
  437.                              FailurePoint1:
  438.                                 AlertHalt("There is not enough memory to close the document.",NIL);
  439.                                 return False;
  440.                             }
  441.                         FilenameNull = BlockToStringCopy(Filename);
  442.                         ReleasePtr(Filename);
  443.                     }
  444.                  else
  445.                     {
  446.                         FilenameNull = StringFromRaw("Untitled");
  447.                     }
  448.                 if (FilenameNull == NIL)
  449.                     {
  450.                         goto FailurePoint1;
  451.                     }
  452.                 Options = AskYesNoCancel("The document '_' has not been saved.  Do you "
  453.                     "want to save your changes?",FilenameNull,"Save","Don't Save","Cancel");
  454.                 ReleasePtr(FilenameNull);
  455.                 switch (Options)
  456.                     {
  457.                         default:
  458.                             EXECUTE(PRERR(ForceAbort,"CloseDocument:  bad value from AskYesNoCancel"));
  459.                             break;
  460.                         case eYes:
  461.                             if (!Save(Window))
  462.                                 {
  463.                                     return False; /* save was cancelled or failed */
  464.                                 }
  465.                             break;
  466.                         case eCancel:
  467.                             return False; /* user cancelled */
  468.                         case eNo:
  469.                             /* fall through to deletion point */
  470.                             break;
  471.                     }
  472.             }
  473.         /* remove window from master array */
  474.         ArraySetElement(MasterWindowList,NIL,ArrayFindElement(MasterWindowList,Window));
  475.         CheckOutDyingWindow(Window->GenericWindow);
  476.         if (Window->EverSaved)
  477.             {
  478.                 CloseFile(Window->TheFile);
  479.                 DisposeFileSpec(Window->FileLocation);
  480.             }
  481.         DisposeTextEdit(Window->TheEdit);
  482.         KillMenuItem(Window->WindowMenuEntry);
  483.         KillWindow(Window->ScreenID);
  484.         ReleasePtr((char*)Window);
  485.         return True;
  486.     }
  487.  
  488.  
  489. MyBoolean                        DoCloseAllQuitPending(void)
  490.     {
  491.         long                            Scan;
  492.         long                            Limit;
  493.  
  494.         Limit = ArrayGetLength(MasterWindowList);
  495.         for (Scan = 0; Scan < Limit; Scan += 1)
  496.             {
  497.                 MyWinRec*                    Window;
  498.  
  499.                 Window = ArrayGetElement(MasterWindowList,Scan);
  500.                 if (Window != NIL)
  501.                     {
  502.                         /* bring window to the top */
  503.                         ActivateThisWindow(Window->ScreenID);
  504.                         WindowUpdate(Window);
  505.                         /* try to close it */
  506.                         if (!CloseDocument(Window))
  507.                             {
  508.                                 /* if it refused to close, then we have to stop. */
  509.                                 return False;
  510.                             }
  511.                     }
  512.             }
  513.         return True;
  514.     }
  515.  
  516.  
  517. MyBoolean                        Save(MyWinRec* Window)
  518.     {
  519.         CheckPtrExistence(Window);
  520.         if (!Window->EverSaved)
  521.             {
  522.                 return SaveAs(Window);
  523.             }
  524.          else
  525.             {
  526.                 FileType*                    TempFile;
  527.                 FileSpec*                    TempFileLocation;
  528.  
  529.                 /* create a temporary file in the same directory */
  530.                 TempFileLocation = NewTempFileInTheSameDirectory(Window->FileLocation);
  531.                 if (TempFileLocation == NIL)
  532.                     {
  533.                         char*                            Filename;
  534.                         char*                            FilenameNull;
  535.  
  536.                      FailurePoint1:
  537.                         Filename = ExtractFileName(Window->FileLocation);
  538.                         if (Filename == NIL)
  539.                             {
  540.                                 AlertHalt("Unable to save file.  Old contents lost.",NIL);
  541.                                 return False;
  542.                             }
  543.                         FilenameNull = BlockToStringCopy(Filename);
  544.                         ReleasePtr(Filename);
  545.                         if (FilenameNull == NIL)
  546.                             {
  547.                                 goto FailurePoint1;
  548.                             }
  549.                         AlertHalt("The file '_' could not be written to.",FilenameNull);
  550.                         ReleasePtr(FilenameNull);
  551.                         return False;
  552.                     }
  553.                 /* open the file */
  554.                 if (!OpenFile(TempFileLocation,&TempFile,eReadAndWrite))
  555.                     {
  556.                      FailurePoint2:
  557.                         DisposeFileSpec(TempFileLocation);
  558.                         goto FailurePoint1;
  559.                     }
  560.                 /* write data to the file */
  561.                 if (!TestEditWriteDataToFile(Window->TheEdit,TempFile,
  562.                     GetProperStaticLineFeed(Window)))
  563.                     {
  564.                      FailurePoint3:
  565.                         CloseFile(TempFile);
  566.                         DeleteFile(TempFileLocation);
  567.                         goto FailurePoint2;
  568.                     }
  569.                 FlushLocalBuffers(TempFile);
  570.                 /* swap the files on the disk */
  571.                 if (!SwapFileDataForks(TempFileLocation,Window->FileLocation,TempFile,
  572.                     &(Window->TheFile)))
  573.                     {
  574.                         /* if this fails, then the parameters are unaltered */
  575.                         goto FailurePoint3;
  576.                     }
  577.                 /* at this point, Window->TheFile has been fixed up, TempFile is closed, */
  578.                 /* and we need to dispose TempFileLocation */
  579.                 DisposeFileSpec(TempFileLocation);
  580.                 /* mark it saved */
  581.                 TextEditHasBeenSaved(Window->TheEdit);
  582.                 Window->NeedsToBeSaved = False;
  583.             }
  584.         return True;
  585.     }
  586.  
  587.  
  588. MyBoolean                        SaveAs(MyWinRec* Window)
  589.     {
  590.         FileSpec*                    NewWhere;
  591.         char*                            FilenameNull;
  592.  
  593.         if (Window->EverSaved)
  594.             {
  595.                 char*                            Filename;
  596.  
  597.                 Filename = ExtractFileName(Window->FileLocation);
  598.                 if (Filename == NIL)
  599.                     {
  600.                      FailurePoint1:
  601.                         AlertHalt("There is not enough memory to save the document.",NIL);
  602.                         return False;
  603.                     }
  604.                 FilenameNull = BlockToStringCopy(Filename);
  605.                 ReleasePtr(Filename);
  606.             }
  607.          else
  608.             {
  609.                 FilenameNull = StringFromRaw("Untitled");
  610.             }
  611.         if (FilenameNull == NIL)
  612.             {
  613.                 goto FailurePoint1;
  614.             }
  615.         NewWhere = PutFile(FilenameNull);
  616.         ReleasePtr(FilenameNull);
  617.         if (NewWhere != NIL)
  618.             {
  619.                 FileType*                    NewFile;
  620.                 char*                            XFilename;
  621.  
  622.                 XFilename = ExtractFileName(NewWhere);
  623.                 if (XFilename == NIL)
  624.                     {
  625.                         goto FailurePoint1;
  626.                     }
  627.                 FilenameNull = BlockToStringCopy(XFilename);
  628.                 ReleasePtr(XFilename);
  629.                 if (FilenameNull == NIL)
  630.                     {
  631.                         goto FailurePoint1;
  632.                     }
  633.                 if (!CreateFile(NewWhere,ApplicationCreator,CODE4BYTES('T','E','X','T')))
  634.                     {
  635.                         AlertHalt("Couldn't create the file '_'.",FilenameNull);
  636.                         ReleasePtr(FilenameNull);
  637.                         return False;
  638.                     }
  639.                 if (!OpenFile(NewWhere,&NewFile,eReadAndWrite))
  640.                     {
  641.                         AlertHalt("Couldn't open the file '_'.",FilenameNull);
  642.                         ReleasePtr(FilenameNull);
  643.                         return False;
  644.                     }
  645.                 if (Window->EverSaved)
  646.                     {
  647.                         CloseFile(Window->TheFile);
  648.                         DisposeFileSpec(Window->FileLocation);
  649.                     }
  650.                 Window->EverSaved = True;
  651.                 Window->FileLocation = NewWhere;
  652.                 Window->TheFile = NewFile;
  653.                 SetWindowName(Window->ScreenID,FilenameNull);
  654.                 ChangeItemName(Window->WindowMenuEntry,FilenameNull);
  655.                 ReleasePtr(FilenameNull);
  656.                 return Save(Window);
  657.             }
  658.          else
  659.             {
  660.                 return False;
  661.             }
  662.         EXECUTE(PRERR(ForceAbort,"SaveAs:  Not Reached"));
  663.     }
  664.  
  665.  
  666. void                                WindowDoIdle(MyWinRec* Window, MyBoolean CheckCursorFlag,
  667.                                             OrdType XLoc, OrdType YLoc, ModifierFlags Modifiers)
  668.     {
  669.         CheckPtrExistence(Window);
  670.         TextEditUpdateCursor(Window->TheEdit);
  671.         if (CheckCursorFlag)
  672.             {
  673.                 if (TextEditIBeamTest(Window->TheEdit,XLoc,YLoc))
  674.                     {
  675.                         SetIBeamCursor();
  676.                     }
  677.                  else
  678.                     {
  679.                         SetArrowCursor();
  680.                     }
  681.             }
  682.     }
  683.  
  684.  
  685. void                                WindowBecomeActive(MyWinRec* Window)
  686.     {
  687.         CheckPtrExistence(Window);
  688.         EnableTextEditSelection(Window->TheEdit);
  689.         SetClipRect(Window->ScreenID,0,0,GetWindowWidth(Window->ScreenID),
  690.             GetWindowHeight(Window->ScreenID));
  691.         DrawBitmap(Window->ScreenID,GetWindowWidth(Window->ScreenID) - 15,
  692.             GetWindowHeight(Window->ScreenID) - 15,GetGrowIcon(True/*enablegrowicon*/));
  693.     }
  694.  
  695.  
  696. void                                WindowBecomeInactive(MyWinRec* Window)
  697.     {
  698.         CheckPtrExistence(Window);
  699.         DisableTextEditSelection(Window->TheEdit);
  700.         SetClipRect(Window->ScreenID,0,0,GetWindowWidth(Window->ScreenID),
  701.             GetWindowHeight(Window->ScreenID));
  702.         DrawBitmap(Window->ScreenID,GetWindowWidth(Window->ScreenID) - 15,
  703.             GetWindowHeight(Window->ScreenID) - 15,GetGrowIcon(False/*disablegrowicon*/));
  704.     }
  705.  
  706.  
  707. void                                WindowResized(MyWinRec* Window)
  708.     {
  709.         CheckPtrExistence(Window);
  710.         SetTextEditPosition(Window->TheEdit,-1,-1,GetWindowWidth(Window->ScreenID) + 2,
  711.             GetWindowHeight(Window->ScreenID) + 2);
  712.     }
  713.  
  714.  
  715. void                                WindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  716.                                             ModifierFlags Modifiers, MyWinRec* Window)
  717.     {
  718.         OrdType                        WinHeight;
  719.         OrdType                        WinWidth;
  720.  
  721.         CheckPtrExistence(Window);
  722.         WinWidth = GetWindowWidth(Window->ScreenID);
  723.         WinHeight = GetWindowHeight(Window->ScreenID);
  724.         if ((XLoc >= WinWidth - 15) && (XLoc < WinWidth)
  725.             && (YLoc >= WinHeight - 15) && (YLoc < WinHeight))
  726.             {
  727.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  728.                 WindowResized(Window);
  729.             }
  730.          else
  731.             {
  732.                 TextEditDoMouseDown(Window->TheEdit,XLoc,YLoc,Modifiers);
  733.             }
  734.     }
  735.  
  736.  
  737. void                                WindowDoKeyDown(unsigned char KeyCode,
  738.                                             ModifierFlags Modifiers, MyWinRec* Window)
  739.     {
  740.         CheckPtrExistence(Window);
  741.         if (KeyCode == 3)
  742.             {
  743.                 TextEditShowSelection(Window->TheEdit);
  744.             }
  745.         else if (((KeyCode >= 32) && ((Modifiers & eCommandKey) == 0)) || (KeyCode == 13)
  746.             || (KeyCode == eLeftArrow) || (KeyCode == eRightArrow) || (KeyCode == eUpArrow)
  747.             || (KeyCode == eDownArrow) || (KeyCode == 8) || (KeyCode == 9))
  748.             {
  749.                 TextEditDoKeyPressed(Window->TheEdit,KeyCode,Modifiers);
  750.             }
  751.     }
  752.  
  753.  
  754. void                                WindowClose(MyWinRec* Window)
  755.     {
  756.         CheckPtrExistence(Window);
  757.         CloseDocument(Window);
  758.     }
  759.  
  760.  
  761. void                                WindowUpdate(MyWinRec* Window)
  762.     {
  763.         CheckPtrExistence(Window);
  764.         TextEditFullRedraw(Window->TheEdit);
  765.         SetClipRect(Window->ScreenID,0,0,GetWindowWidth(Window->ScreenID),
  766.             GetWindowHeight(Window->ScreenID));
  767.         DrawBitmap(Window->ScreenID,GetWindowWidth(Window->ScreenID) - 15,
  768.             GetWindowHeight(Window->ScreenID) - 15,
  769.             GetGrowIcon(Window->GenericWindow == GetCurrentWindowID()));
  770.     }
  771.  
  772.  
  773. void                                WindowMenuSetup(MyWinRec* Window)
  774.     {
  775.         char*                            StrNumber;
  776.         long                            Scan;
  777.         long                            Limit;
  778.  
  779.         CheckPtrExistence(Window);
  780.         ChangeItemName(mCloseFile,"Close File");
  781.         EnableMenuItem(mCloseFile);
  782.         EnableMenuItem(mSaveAs);
  783.         if (Window->NeedsToBeSaved || TextEditDoesItNeedToBeSaved(Window->TheEdit))
  784.             {
  785.                 EnableMenuItem(mSaveFile);
  786.             }
  787.         EnableMenuItem(mSetTabSize);
  788.         EnableMenuItem(mMacintoshLineFeeds);
  789.         EnableMenuItem(mUnixLineFeeds);
  790.         EnableMenuItem(mMsDosLineFeeds);
  791.         switch (Window->LineFeed)
  792.             {
  793.                 default:
  794.                     EXECUTE(PRERR(AllowResume,"WindowMenuSetup:  unknown line feed type"));
  795.                     break;
  796.                 case eMacLF:
  797.                     SetItemCheckmark(mMacintoshLineFeeds);
  798.                     break;
  799.                 case eUnixLF:
  800.                     SetItemCheckmark(mUnixLineFeeds);
  801.                     break;
  802.                 case eDosLF:
  803.                     SetItemCheckmark(mMsDosLineFeeds);
  804.                     break;
  805.             }
  806.  
  807.         StrNumber = IntegerToString(GetTextEditSpacesPerTab(Window->TheEdit));
  808.         if (StrNumber != NIL)
  809.             {
  810.                 char*                            StrKey;
  811.  
  812.                 StrKey = StringToBlockCopy("_");
  813.                 if (StrKey != NIL)
  814.                     {
  815.                         char*                            StrValue;
  816.  
  817.                         StrValue = StringToBlockCopy("Set Tab Size... (_)");
  818.                         if (StrValue != NIL)
  819.                             {
  820.                                 char*                            StrResult;
  821.  
  822.                                 StrResult = ReplaceBlockCopy(StrValue,StrKey,StrNumber);
  823.                                 if (StrResult != NIL)
  824.                                     {
  825.                                         char*                            Temp;
  826.  
  827.                                         Temp = BlockToStringCopy(StrResult);
  828.                                         if (Temp != NIL)
  829.                                             {
  830.                                                 ReleasePtr(StrResult);
  831.                                                 StrResult = Temp;
  832.                                                 ChangeItemName(mSetTabSize,StrResult);
  833.                                             }
  834.                                         ReleasePtr(StrResult);
  835.                                     }
  836.                                 ReleasePtr(StrValue);
  837.                             }
  838.                         ReleasePtr(StrKey);
  839.                     }
  840.                 ReleasePtr(StrNumber);
  841.             }
  842.  
  843.         EnableMenuItem(mConvertTabsToSpaces);
  844.         EnableMenuItem(mPaste);
  845.         EnableMenuItem(mAutoIndent);
  846.         if (TextEditIsAutoIndentEnabled(Window->TheEdit))
  847.             {
  848.                 SetItemCheckmark(mAutoIndent);
  849.             }
  850.         if (TextEditIsThereValidSelection(Window->TheEdit))
  851.             {
  852.                 EnableMenuItem(mCut);
  853.                 EnableMenuItem(mCopy);
  854.                 EnableMenuItem(mClear);
  855.                 EnableMenuItem(mEnterSelection);
  856.                 EnableMenuItem(mReplace);
  857.                 if (PtrSize(SearchKey) != 0)
  858.                     {
  859.                         EnableMenuItem(mReplaceAndFindAgain);
  860.                     }
  861.             }
  862.         EnableMenuItem(mShiftLeft);
  863.         EnableMenuItem(mShiftRight);
  864.         EnableMenuItem(mBalanceParens);
  865.         EnableMenuItem(mSelectAll);
  866.         EnableMenuItem(mFind);
  867.         if (PtrSize(SearchKey) != 0)
  868.             {
  869.                 EnableMenuItem(mFindAgain);
  870.             }
  871.         EnableMenuItem(mShowSelection);
  872.         Limit = PtrSize((char*)mFontItemList) / sizeof(MenuToFont);
  873.         for (Scan = 0; Scan < Limit; Scan += 1)
  874.             {
  875.                 EnableMenuItem(mFontItemList[Scan].MenuItemID);
  876.                 if (mFontItemList[Scan].FontID == Window->TheFont)
  877.                     {
  878.                         SetItemCheckmark(mFontItemList[Scan].MenuItemID);
  879.                     }
  880.             }
  881.         EnableMenuItem(m9Points);
  882.         EnableMenuItem(m10Points);
  883.         EnableMenuItem(m12Points);
  884.         EnableMenuItem(m14Points);
  885.         EnableMenuItem(m18Points);
  886.         EnableMenuItem(m24Points);
  887.         EnableMenuItem(m30Points);
  888.         EnableMenuItem(m36Points);
  889.         EnableMenuItem(mOtherPoints);
  890.  
  891.         StrNumber = IntegerToString(Window->FontSize);
  892.         if (StrNumber != NIL)
  893.             {
  894.                 char*                            StrKey;
  895.  
  896.                 StrKey = StringToBlockCopy("_");
  897.                 if (StrKey != NIL)
  898.                     {
  899.                         char*                            StrValue;
  900.  
  901.                         StrValue = StringToBlockCopy("Other Point Size... (_)");
  902.                         if (StrValue != NIL)
  903.                             {
  904.                                 char*                            StrResult;
  905.  
  906.                                 StrResult = ReplaceBlockCopy(StrValue,StrKey,StrNumber);
  907.                                 if (StrResult != NIL)
  908.                                     {
  909.                                         char*                            Temp;
  910.  
  911.                                         Temp = BlockToStringCopy(StrResult);
  912.                                         if (Temp != NIL)
  913.                                             {
  914.                                                 ReleasePtr(StrResult);
  915.                                                 StrResult = Temp;
  916.                                                 ChangeItemName(mOtherPoints,StrResult);
  917.                                             }
  918.                                         ReleasePtr(StrResult);
  919.                                     }
  920.                                 ReleasePtr(StrValue);
  921.                             }
  922.                         ReleasePtr(StrKey);
  923.                     }
  924.                 ReleasePtr(StrNumber);
  925.             }
  926.  
  927.         switch (Window->FontSize)
  928.             {
  929.                 case 9:  SetItemCheckmark(m9Points); break;
  930.                 case 10:  SetItemCheckmark(m10Points); break;
  931.                 case 12:  SetItemCheckmark(m12Points); break;
  932.                 case 14:  SetItemCheckmark(m14Points); break;
  933.                 case 18:  SetItemCheckmark(m18Points); break;
  934.                 case 24:  SetItemCheckmark(m24Points); break;
  935.                 case 30:  SetItemCheckmark(m30Points); break;
  936.                 case 36:  SetItemCheckmark(m36Points); break;
  937.                 default:  SetItemCheckmark(mOtherPoints); break;
  938.             }
  939.         Limit = ArrayGetLength(MasterWindowList);
  940.         for (Scan = 0; Scan < Limit; Scan += 1)
  941.             {
  942.                 MyWinRec*                    OtherWindow;
  943.  
  944.                 OtherWindow = ArrayGetElement(MasterWindowList,Scan);
  945.                 if (OtherWindow != NIL)
  946.                     {
  947.                         EnableMenuItem(OtherWindow->WindowMenuEntry);
  948.                         if (OtherWindow == Window)
  949.                             {
  950.                                 SetItemCheckmark(OtherWindow->WindowMenuEntry);
  951.                             }
  952.                     }
  953.             }
  954.         EnableMenuItem(mGotoLine);
  955.  
  956.         StrNumber = IntegerToString(GetTextEditSelectStartLine(Window->TheEdit) + 1);
  957.         if (StrNumber != NIL)
  958.             {
  959.                 char*                            StrKey;
  960.  
  961.                 StrKey = StringToBlockCopy("_");
  962.                 if (StrKey != NIL)
  963.                     {
  964.                         char*                            StrValue;
  965.  
  966.                         StrValue = StringToBlockCopy("Goto Line... (_)");
  967.                         if (StrValue != NIL)
  968.                             {
  969.                                 char*                            StrResult;
  970.  
  971.                                 StrResult = ReplaceBlockCopy(StrValue,StrKey,StrNumber);
  972.                                 if (StrResult != NIL)
  973.                                     {
  974.                                         char*                            Temp;
  975.  
  976.                                         Temp = BlockToStringCopy(StrResult);
  977.                                         if (Temp != NIL)
  978.                                             {
  979.                                                 ReleasePtr(StrResult);
  980.                                                 StrResult = Temp;
  981.                                                 ChangeItemName(mGotoLine,StrResult);
  982.                                             }
  983.                                         ReleasePtr(StrResult);
  984.                                     }
  985.                                 ReleasePtr(StrValue);
  986.                             }
  987.                         ReleasePtr(StrKey);
  988.                     }
  989.                 ReleasePtr(StrNumber);
  990.             }
  991.  
  992.         EnableMenuItem(mPrefixSelection);
  993.         if (TextEditCanWeUndo(Window->TheEdit))
  994.             {
  995.                 EnableMenuItem(mUndo);
  996.             }
  997.     }
  998.  
  999.  
  1000. void                                WindowDoMenuCommand(MyWinRec* Window, MenuItemType* MenuItem)
  1001.     {
  1002.         CheckPtrExistence(Window);
  1003.         CheckPtrExistence(MenuItem);
  1004.         if (MenuItem == mCloseFile)
  1005.             {
  1006.                 WindowClose(Window);
  1007.             }
  1008.         else if (MenuItem == mSaveFile)
  1009.             {
  1010.                 Save(Window);
  1011.             }
  1012.         else if (MenuItem == mSaveAs)
  1013.             {
  1014.                 SaveAs(Window);
  1015.             }
  1016.         else if (MenuItem == mSetTabSize)
  1017.             {
  1018.                 long                        NewTabCount;
  1019.  
  1020.                 NewTabCount = DoNumberDialog("Enter new tab size:",
  1021.                     GetTextEditSpacesPerTab(Window->TheEdit),mCut,mPaste,mCopy,mUndo,
  1022.                     mSelectAll,mClear);
  1023.                 if (NewTabCount < MINTABCOUNT)
  1024.                     {
  1025.                         NewTabCount = MINTABCOUNT;
  1026.                     }
  1027.                 if (NewTabCount > MAXTABCOUNT)
  1028.                     {
  1029.                         NewTabCount = MAXTABCOUNT;
  1030.                     }
  1031.                 SetTextEditTabSize(Window->TheEdit,NewTabCount);
  1032.                 TextEditFullRedraw(Window->TheEdit);
  1033.             }
  1034.         else if (MenuItem == mConvertTabsToSpaces)
  1035.             {
  1036.                 TextEditConvertTabsToSpaces(Window->TheEdit);
  1037.             }
  1038.         else if (MenuItem == mMacintoshLineFeeds)
  1039.             {
  1040.                 Window->LineFeed = eMacLF;
  1041.                 Window->NeedsToBeSaved = True;
  1042.             }
  1043.         else if (MenuItem == mUnixLineFeeds)
  1044.             {
  1045.                 Window->LineFeed = eUnixLF;
  1046.                 Window->NeedsToBeSaved = True;
  1047.             }
  1048.         else if (MenuItem == mMsDosLineFeeds)
  1049.             {
  1050.                 Window->LineFeed = eDosLF;
  1051.                 Window->NeedsToBeSaved = True;
  1052.             }
  1053.         else if (MenuItem == mUndo)
  1054.             {
  1055.                 TextEditDoMenuUndo(Window->TheEdit);
  1056.                 TextEditShowSelection(Window->TheEdit);
  1057.             }
  1058.         else if (MenuItem == mCut)
  1059.             {
  1060.                 TextEditDoMenuCut(Window->TheEdit);
  1061.             }
  1062.         else if (MenuItem == mCopy)
  1063.             {
  1064.                 TextEditDoMenuCopy(Window->TheEdit);
  1065.             }
  1066.         else if (MenuItem == mPaste)
  1067.             {
  1068.                 TextEditDoMenuPaste(Window->TheEdit);
  1069.             }
  1070.         else if (MenuItem == mClear)
  1071.             {
  1072.                 TextEditDoMenuClear(Window->TheEdit);
  1073.             }
  1074.         else if (MenuItem == mSelectAll)
  1075.             {
  1076.                 TextEditDoMenuSelectAll(Window->TheEdit);
  1077.             }
  1078.         else if (MenuItem == mEnterSelection)
  1079.             {
  1080.                 char*                        NewString;
  1081.  
  1082.                 NewString = TextEditGetSelection(Window->TheEdit);
  1083.                 if (NewString != NIL)
  1084.                     {
  1085.                         ReleasePtr(SearchKey);
  1086.                         SearchKey = NewString;
  1087.                     }
  1088.             }
  1089.         else if (MenuItem == mFind)
  1090.             {
  1091.                 switch (DoFindDialog(&SearchKey,&ReplaceThang,mCut,mPaste,mCopy,mUndo,
  1092.                     mSelectAll,mClear))
  1093.                     {
  1094.                         case eFindCancel:
  1095.                             break;
  1096.                         case eFindFromStart:
  1097.                             SetTextEditInsertionPoint(Window->TheEdit,0,0); /* reset selection */
  1098.                             FindAgain(Window);
  1099.                             break;
  1100.                         case eFindAgain:
  1101.                             FindAgain(Window);
  1102.                             break;
  1103.                         case eDontFind:
  1104.                             break;
  1105.                         default:
  1106.                             EXECUTE(PRERR(AllowResume,"FindSomething: Unknown find opcode"));
  1107.                             break;
  1108.                     }
  1109.             }
  1110.         else if (MenuItem == mFindAgain)
  1111.             {
  1112.                 FindAgain(Window);
  1113.             }
  1114.         else if (MenuItem == mReplace)
  1115.             {
  1116.                 Replace(Window);
  1117.             }
  1118.         else if (MenuItem == mReplaceAndFindAgain)
  1119.             {
  1120.                 if (Replace(Window))
  1121.                     {
  1122.                         FindAgain(Window);
  1123.                     }
  1124.             }
  1125.         else if (MenuItem == mShiftLeft)
  1126.             {
  1127.                 TextEditShiftSelectionLeftOneTab(Window->TheEdit);
  1128.             }
  1129.         else if (MenuItem == mShiftRight)
  1130.             {
  1131.                 TextEditShiftSelectionRightOneTab(Window->TheEdit);
  1132.             }
  1133.         else if (MenuItem == mShowSelection)
  1134.             {
  1135.                 TextEditShowSelection(Window->TheEdit);
  1136.             }
  1137.         else if (ItsInTheFontList(MenuItem))
  1138.             {
  1139.                 Window->TheFont = GetFontFromMenuItem(MenuItem);
  1140.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1141.             }
  1142.         else if (MenuItem == m9Points)
  1143.             {
  1144.                 Window->FontSize = 9;
  1145.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1146.             }
  1147.         else if (MenuItem == m10Points)
  1148.             {
  1149.                 Window->FontSize = 10;
  1150.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1151.             }
  1152.         else if (MenuItem == m12Points)
  1153.             {
  1154.                 Window->FontSize = 12;
  1155.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1156.             }
  1157.         else if (MenuItem == m14Points)
  1158.             {
  1159.                 Window->FontSize = 14;
  1160.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1161.             }
  1162.         else if (MenuItem == m18Points)
  1163.             {
  1164.                 Window->FontSize = 18;
  1165.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1166.             }
  1167.         else if (MenuItem == m24Points)
  1168.             {
  1169.                 Window->FontSize = 24;
  1170.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1171.             }
  1172.         else if (MenuItem == m30Points)
  1173.             {
  1174.                 Window->FontSize = 30;
  1175.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1176.             }
  1177.         else if (MenuItem == m36Points)
  1178.             {
  1179.                 Window->FontSize = 36;
  1180.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1181.             }
  1182.         else if (MenuItem == mOtherPoints)
  1183.             {
  1184.                 Window->FontSize = DoNumberDialog("Enter new point size:",Window->FontSize,
  1185.                     mCut,mPaste,mCopy,mUndo,mSelectAll,mClear);
  1186.                 if (Window->FontSize < 4)
  1187.                     {
  1188.                         Window->FontSize = 4;
  1189.                     }
  1190.                 if (Window->FontSize > 127)
  1191.                     {
  1192.                         Window->FontSize = 127;
  1193.                     }
  1194.                 SetTextEditFontStuff(Window->TheEdit,Window->TheFont,Window->FontSize);
  1195.             }
  1196.         else if (mAutoIndent == MenuItem)
  1197.             {
  1198.                 SetTextEditAutoIndent(Window->TheEdit,
  1199.                     !TextEditIsAutoIndentEnabled(Window->TheEdit));
  1200.             }
  1201.         else if (mBalanceParens == MenuItem)
  1202.             {
  1203.                 TextEditBalanceParens(Window->TheEdit);
  1204.             }
  1205.         else if (mGotoLine == MenuItem)
  1206.             {
  1207.                 long                        Line;
  1208.  
  1209.                 Line = DoNumberDialog("Goto Line:",GetTextEditSelectStartLine(
  1210.                     Window->TheEdit) + 1,mCut,mPaste,mCopy,mUndo,mSelectAll,mClear);
  1211.                 Line -= 1;
  1212.                 if (Line < 0)
  1213.                     {
  1214.                         Line = 0;
  1215.                     }
  1216.                 if (Line > GetTextEditNumLines(Window->TheEdit) - 1)
  1217.                     {
  1218.                         Line = GetTextEditNumLines(Window->TheEdit) - 1;
  1219.                     }
  1220.                 SetTextEditInsertionPoint(Window->TheEdit,Line,0);
  1221.                 TextEditShowSelection(Window->TheEdit);
  1222.             }
  1223.         else if (mPrefixSelection == MenuItem)
  1224.             {
  1225.                 if (DoStringDialog("Enter line prefix:",&PrefixPtr,
  1226.                     mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
  1227.                     {
  1228.                         long                        Scan;
  1229.                         long                        Limit;
  1230.                         long                        PrefixLen;
  1231.  
  1232.                         Limit = GetTextEditSelectEndLine(Window->TheEdit);
  1233.                         if (GetTextEditSelectEndCharPlusOne(Window->TheEdit) == 0)
  1234.                             {
  1235.                                 Limit -= 1;
  1236.                             }
  1237.                         PrefixLen = PtrSize(PrefixPtr);
  1238.                         for (Scan = GetTextEditSelectStartLine(Window->TheEdit);
  1239.                             Scan <= Limit; Scan += 1)
  1240.                             {
  1241.                                 char*                        Line;
  1242.                                 char*                        LineCopy;
  1243.                                 long                        LineLen;
  1244.  
  1245.                                 Line = GetTextEditLine(Window->TheEdit,Scan);
  1246.                                 if (Line != NIL)
  1247.                                     {
  1248.                                         LineLen = PtrSize(PrefixPtr);
  1249.                                         LineCopy = InsertBlockIntoBlockCopy(Line,PrefixPtr,0,LineLen);
  1250.                                         if (LineCopy != NIL)
  1251.                                             {
  1252.                                                 SetTextEditLine(Window->TheEdit,Scan,LineCopy);
  1253.                                                 ReleasePtr(LineCopy);
  1254.                                             }
  1255.                                         ReleasePtr(Line);
  1256.                                     }
  1257.                             }
  1258.                     }
  1259.             }
  1260.         else if (NIL != WhichWindowMenuItem(MenuItem))
  1261.             {
  1262.                 ActivateThisWindow((WhichWindowMenuItem(MenuItem))->ScreenID);
  1263.             }
  1264.         else
  1265.             {
  1266.                 EXECUTE(PRERR(AllowResume,"Unimplemented menu command chosen"));
  1267.             }
  1268.     }
  1269.  
  1270.  
  1271. void                                FindAgain(MyWinRec* Window)
  1272.     {
  1273.         CheckPtrExistence(Window);
  1274.         TextEditFindAgain(Window->TheEdit,SearchKey);
  1275.         TextEditShowSelection(Window->TheEdit);
  1276.     }
  1277.  
  1278.  
  1279. MyBoolean                        Replace(MyWinRec* Window)
  1280.     {
  1281.         if (TextEditIsThereValidSelection(Window->TheEdit))
  1282.             {
  1283.                 TextEditInsertRawData(Window->TheEdit,ReplaceThang,SYSTEMLINEFEED);
  1284.                 return True;
  1285.             }
  1286.          else
  1287.             {
  1288.                 return False;
  1289.             }
  1290.     }
  1291.  
  1292.  
  1293. MyWinRec*                        WhichWindowMenuItem(MenuItemType* TheItem)
  1294.     {
  1295.         long                            Scan;
  1296.         long                            Limit;
  1297.  
  1298.         Limit = ArrayGetLength(MasterWindowList);
  1299.         for (Scan = 0; Scan < Limit; Scan += 1)
  1300.             {
  1301.                 MyWinRec*                    WinTemp;
  1302.  
  1303.                 WinTemp = ArrayGetElement(MasterWindowList,Scan);
  1304.                 if ((WinTemp != NIL) && (WinTemp->WindowMenuEntry == TheItem))
  1305.                     {
  1306.                         return WinTemp;
  1307.                     }
  1308.             }
  1309.         return NIL;
  1310.     }
  1311.