home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / MacPerl5 / MPAppleEvents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-28  |  147.2 KB  |  5,794 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Real Perl Application
  3. File        :    MPAppleEvents.c    -
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPAppleEvents.c,v $
  12. Revision 1.2  1994/05/04  02:48:27  neeri
  13. Inline input.
  14. Fix deletions.
  15.  
  16. Revision 1.1  1994/02/27  22:59:44  neeri
  17. Initial revision
  18.  
  19. Revision 0.4  1993/08/28  00:00:00  neeri
  20. FormatCommand
  21.  
  22. Revision 0.3  1993/08/16  00:00:00  neeri
  23. DoScript
  24.  
  25. Revision 0.2  1993/05/30  00:00:00  neeri
  26. Support console Windows
  27.  
  28. Revision 0.1  1993/05/29  00:00:00  neeri
  29. Compiles correctly
  30.  
  31. *********************************************************************/
  32.  
  33. #include <AppleEvents.h>
  34. #include <LowMem.h>
  35. #include <Menus.h>
  36. #include <PLStringFuncs.h>
  37. #include <Scrap.h>
  38. #include <TextEdit.h>
  39. #include <AEObjects.h>
  40. #include <AEPackObject.h>
  41. #include <AERegistry.h>
  42. #include <AEStream.h>
  43. #include <AEBuild.h>
  44. #include <Resources.h>
  45. #include <String.h>
  46. #include <TFileSpec.h>
  47.  
  48. #include "MPGlobals.h"
  49. #include "MPUtils.h"
  50. #include "MPAEUtils.h"
  51. #include "MPWindow.h"
  52. #include "MPFile.h"
  53. #include "MPAppleEvents.h"
  54. #include "MPScript.h"
  55. #include "MPSave.h"
  56. #include "MPPreferences.h"
  57. #include "MPAEVTStream.h"
  58.  
  59. /* these should come from the registry */
  60.  
  61. #define         kAEStartedRecording  'rec1'
  62. #define         kAEStoppedRecording    'rec0'
  63. #define         kAEDontExecute         0x00002000
  64.  
  65. #define         pText                     'TEXT'
  66. #define     cSpot                 'cspt'
  67.  
  68. /*
  69.     Text Properties
  70. */
  71.  
  72. #define         pStringWidth            'pwid'
  73.  
  74. /*
  75.     Window Properties - See the Registry for Details
  76. */
  77.  
  78. #define     pPosition               'ppos'
  79. #define         pPageSetup                'PSET' /* One of ours - Not in registry */
  80. #define         pShowBorders            'PBOR' /* Another of ours */
  81.  
  82. #define         typeTPrint                'TPNT' /* A raw TPrint record - also one of ours */
  83.  
  84. /*
  85.     Error Codes
  86. */
  87.  
  88. #define         kAEGenericErr    -1799
  89.  
  90. static short   gBigBrother;
  91. static char    *gTypingBuffer;
  92. static short   gCharsInBuffer;
  93. static AEDesc  gTypingTargetObject;
  94.  
  95. pascal Boolean AllSelected(TEHandle te)
  96. {
  97.     return ((*te)->selStart == 0 && (*te)->selEnd == (*te)->teLength);
  98. }
  99.  
  100. /*-----------------------------------------------------------------------*/
  101. /**----------                         APPLE EVENT HANDLING         ---------------**/
  102. /*-----------------------------------------------------------------------*/
  103.  
  104. pascal OSErr GetTHPrintFromDescriptor(const AEDesc *sourceDesc, THPrint *result)
  105. {
  106.     OSErr   myErr;
  107.     Size    ptSize;
  108.     AEDesc  resultDesc;
  109.  
  110.     *result = nil;
  111.  
  112.     if (myErr = AECoerceDesc(sourceDesc,typeTPrint,&resultDesc))
  113.         return myErr;
  114.  
  115.     *result = (THPrint)NewHandle(sizeof(TPrint));
  116.  
  117.     PrOpen();
  118.     PrintDefault(*result);
  119.  
  120.     HLock((Handle)*result);
  121.  
  122.     GetRawDataFromDescriptor(&resultDesc, (Ptr)**result, sizeof(TPrint), &ptSize);
  123.  
  124.     HUnlock((Handle)*result);
  125.  
  126.     if ((ptSize<sizeof(TPrint)) || (PrValidate(*result))) {
  127.         myErr = errAECoercionFail;
  128.         DisposHandle((Handle)*result);
  129.         *result = nil;
  130.     }
  131.  
  132.     PrClose();
  133.  
  134.     if (resultDesc.dataHandle)
  135.         AEDisposeDesc(&resultDesc);
  136.  
  137.     return myErr;
  138. } /*GetTHPrintFromDescriptor*/
  139.  
  140. /*******************************************************************************/
  141. /*
  142.     Object Accessors - Utility Routines
  143. */
  144.  
  145. #if !defined(powerc) && !defined(__powerc)
  146. #pragma segment ObjectAccessors
  147. #endif
  148.  
  149. /*
  150.     Returns the WindowPtr of the window with title nameStr
  151.     or nil if there is no matching window.
  152. */
  153. pascal WindowPtr WindowNameToWindowPtr(StringPtr nameStr)
  154. {
  155.     WindowPtr theWindow;
  156.     Str255    windTitle;
  157.  
  158.     theWindow = (WindowPtr)LMGetWindowList();
  159.     /*
  160.         iterate through windows - we use WindowList 'cos we could
  161.         have made the window invisible and  we lose it - so we
  162.         can't set it back to visible!!
  163.     */
  164.     while (theWindow) {
  165.         GetWTitle(theWindow, windTitle);
  166.         if (EqualString(windTitle,
  167.                              nameStr,
  168.                                         false,
  169.                                         true))     /* ignore case, don't ignore diacriticals */
  170.             return theWindow;
  171.       theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  172.     }
  173.  
  174.     return theWindow;
  175. }    /* WindowNameToWindowPtr */
  176.  
  177. pascal WindowPtr GetWindowPtrOfNthWindow(short index)
  178. /* returns a ptr to the window with the given index
  179.   (front window is 1, behind that is 2, etc.).  if
  180.   there's no window with that index (inc. no windows
  181.   at all), returns nil.
  182. */
  183. {
  184.   WindowPtr theWindow;
  185.  
  186.     theWindow = (WindowPtr)LMGetWindowList();
  187.  
  188.     /* iterate through windows */
  189.  
  190.     while (theWindow) {
  191.         if (--index <= 0)
  192.             return theWindow;
  193.  
  194.       theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  195.     }
  196.  
  197.     return nil;
  198. }    /* GetWindowPtrOfNthWindow */
  199.  
  200. pascal short CountWindows(void)
  201. {
  202.     WindowPtr theWindow;
  203.     short     index;
  204.  
  205.     index = 0;
  206.     theWindow = (WindowPtr)LMGetWindowList();
  207.  
  208.     /* iterate through windows */
  209.  
  210.     while (theWindow) {
  211.         index++;
  212.         theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  213.     }
  214.  
  215.     return index;
  216. } /*CountWindows*/
  217.  
  218. /**-----------------------------------------------------------------------
  219.         Name:         DoOpenApp
  220.         Purpose:        Called on startup, creates a new document.
  221.     -----------------------------------------------------------------------**/
  222.  
  223. #if !defined(powerc) && !defined(__powerc)
  224. #pragma segment Main
  225. #endif
  226.  
  227. pascal OSErr DoOpenApp(const AppleEvent *message, AppleEvent *reply, long refcon)
  228. {
  229.     if (gRuntimeScript)
  230.         return DoScript(message, reply, refcon);
  231.  
  232.     return noErr;
  233. }
  234.  
  235. /**-----------------------------------------------------------------------
  236.         Name:         DoOpenDocument
  237.         Purpose:        Open all the documents passed in the Open AppleEvent.
  238. -----------------------------------------------------------------------**/
  239.  
  240. #if !defined(powerc) && !defined(__powerc)
  241. #pragma segment Main
  242. #endif
  243.  
  244. pascal OSErr DoOpenDocument(const AppleEvent *message, AppleEvent *reply, long refcon)
  245. {
  246.     long        index;
  247.     long        itemsInList;
  248.     AEKeyword   keywd;
  249.     OSErr       err;
  250.     OSErr       ignoreErr;
  251.     AEDescList  docList;
  252.     long        actSize;
  253.     DescType    typeCode;
  254.     FSSpec      theFSSpec;
  255.     EventRecord    ev;
  256.     DocType        type;
  257.  
  258.     if (gRuntimeScript)
  259.         return DoScript(message, reply, refcon);
  260.     
  261.     /* open the specified documents */
  262.  
  263.     docList.dataHandle = nil;
  264.  
  265.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  266.  
  267.     if (err==noErr)
  268.         err = AECountItems( &docList, &itemsInList) ;
  269.     else
  270.       itemsInList = 0;
  271.  
  272.     if (itemsInList) {
  273.         err =
  274.             AEGetNthPtr(&docList, 1, typeFSS, &keywd, &typeCode, (Ptr)&theFSSpec, sizeof(theFSSpec), &actSize);
  275.         
  276.         if (!err) {
  277.             type = GetDocType(&theFSSpec);
  278.             
  279.             GetNextEvent(0, &ev);
  280.         
  281.             switch (type) {
  282.             case kPlainTextDoc:
  283.             case kOldRuntime6Doc:
  284.             case kRuntime7Doc:
  285.                 if (!(ev.modifiers & optionKey) != gPerlPrefs.runFinderOpens)
  286.                     break;
  287.                 if (refcon != -1)
  288.                     break;
  289.                     
  290.                 err = DoScript(message, reply, 0);
  291.                     
  292.                 goto done;
  293.             }
  294.         }
  295.     }
  296.  
  297.     for (index = 1; index <= itemsInList; index++)
  298.         if (err==noErr) {
  299.             err = AEGetNthPtr( &docList, index, typeFSS, &keywd, &typeCode,
  300.                                                  (Ptr)&theFSSpec, sizeof(theFSSpec), &actSize ) ;
  301.             if (err==noErr)
  302.                 switch (type = GetDocType(&theFSSpec)) {
  303.                 case kUnknownDoc:
  304.                     break;
  305.                 case kPreferenceDoc:
  306.                     OpenPreferenceFile(&theFSSpec);
  307.                     break;
  308.                 case kPlainTextDoc:
  309.                 case kOldRuntime6Doc:
  310.                 case kScriptDoc:
  311.                 case kRuntime7Doc:
  312.                 default:
  313.                       err = OpenOld(theFSSpec, type);
  314.                     break;
  315.                 }
  316.         }
  317.  
  318. done:    
  319.   if (docList.dataHandle)
  320.         ignoreErr = AEDisposeDesc(&docList);
  321.  
  322.     return err;
  323. }
  324.  
  325. /**-----------------------------------------------------------------------
  326.         Name:         MyQuit
  327.         Purpose:        Quit event received- exit the program.
  328.     -----------------------------------------------------------------------**/
  329.  
  330. #if !defined(powerc) && !defined(__powerc)
  331. #pragma segment Main
  332. #endif
  333.  
  334. pascal OSErr MyQuit(const AppleEvent *message, const AppleEvent *reply, long refcon)
  335. {
  336. #if !defined(powerc) && !defined(__powerc)
  337. #pragma unused (reply,refcon)
  338. #endif
  339.  
  340.     DescType saveOpt;
  341.     OSErr    tempErr;
  342.     OSErr    myErr;
  343.     DescType returnedType;
  344.     long     actSize;
  345.  
  346.     saveOpt = kAEAsk; /* the default */
  347.     tempErr = AEGetParamPtr(message,
  348.                                     keyAESaveOptions,
  349.                                     typeEnumerated,
  350.                                     &returnedType,
  351.                                     (Ptr)&saveOpt,
  352.                                     sizeof(saveOpt),
  353.                                     &actSize);
  354.  
  355.     if (saveOpt != kAENo)
  356.         myErr = AEInteractWithUser(kAEDefaultTimeout, nil, nil);
  357.  
  358.     if (myErr == noErr)
  359.         DoQuit(saveOpt);
  360.  
  361.     return myErr;
  362. }
  363.  
  364. /**-----------------------------------------------------------------------
  365.         Name:         DoAppleEvent
  366.         Purpose:        Process and despatch the AppleEvent
  367.     -----------------------------------------------------------------------**/
  368.  
  369. #if !defined(powerc) && !defined(__powerc)
  370. #pragma segment Main
  371. #endif
  372.  
  373. pascal void DoAppleEvent(EventRecord theEvent)
  374. {
  375.   OSErr err;
  376.  
  377.   /*should check for your own event message types here - if you have any*/
  378.  
  379.     err = AEProcessAppleEvent(&theEvent);
  380. }
  381.  
  382. /**-----------------------------------------------------------------------
  383.         Name:         MakeSelfAddress
  384.         Purpose:        Builds an AEAddressDesc for the current process
  385.     -----------------------------------------------------------------------**/
  386.  
  387. pascal OSErr MakeSelfPSN(ProcessSerialNumber *selfPSN)
  388. {
  389.     selfPSN->highLongOfPSN = 0;
  390.     selfPSN->lowLongOfPSN  = kCurrentProcess;
  391.     
  392.     return noErr;
  393. }
  394.  
  395. pascal OSErr MakeSelfAddress(AEAddressDesc *selfAddress)
  396. {
  397.       ProcessSerialNumber procSerNum;
  398.  
  399.     MakeSelfPSN(&procSerNum);
  400.  
  401.     return
  402.         AECreateDesc(
  403.             typeProcessSerialNumber,
  404.             (Ptr)&procSerNum,
  405.             sizeof(procSerNum),
  406.             selfAddress);
  407. } /* MakeSelfAddress */
  408.  
  409. /**--------------------------------------------------------------------
  410.     Name :         SendAESetObjProp
  411.     Function :     Creates a property object from an object,
  412.                     a property type and its data and sends it to
  413.                     the requested address, and cleans up zapping params too
  414.     --------------------------------------------------------------------**/
  415.  
  416. pascal OSErr SendAESetObjProp(
  417.     AEDesc        *theObj,
  418.     DescType      theProp,
  419.     AEDesc        *theData,
  420.     AEAddressDesc *toWhom)
  421. {
  422.     AEDesc     propObjSpec;
  423.     AppleEvent myAppleEvent;
  424.     AppleEvent defReply;
  425.     OSErr      myErr;
  426.     OSErr      ignoreErr;
  427.     AEDesc     theProperty;
  428.  
  429.     /* create an object spec that represents the property of the given object */
  430.  
  431.     myErr = AECreateDesc(typeType, (Ptr)&theProp, sizeof(theProp), &theProperty);
  432.     if (myErr==noErr)
  433.         myErr =
  434.             CreateObjSpecifier(
  435.                 cProperty,
  436.                 theObj,
  437.                 formPropertyID,
  438.                 &theProperty,
  439.                 true,
  440.                 &propObjSpec);
  441.  
  442.     /* create event */
  443.  
  444.     if (myErr==noErr)
  445.         myErr =
  446.             AECreateAppleEvent(
  447.                 kAECoreSuite,
  448.                 kAESetData,
  449.                 toWhom,
  450.                 0,
  451.                 0,
  452.                 &myAppleEvent);
  453.  
  454.     /* add prop obj spec to the event */
  455.  
  456.     if (myErr==noErr)
  457.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &propObjSpec);
  458.  
  459.     /* add prop data to the event */
  460.  
  461.     if (myErr==noErr)
  462.         myErr = AEPutParamDesc(&myAppleEvent, keyAEData, theData);
  463.  
  464.     /* send event */
  465.  
  466.     if (myErr==noErr)
  467.         myErr =
  468.             AESend(
  469.                 &myAppleEvent,
  470.                 &defReply,
  471.                 kAENoReply+kAEAlwaysInteract,
  472.                 kAENormalPriority,
  473.                 kAEDefaultTimeout,
  474.                 nil,
  475.                 nil);
  476.  
  477.     if (myAppleEvent.dataHandle)
  478.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  479.  
  480.     if (&propObjSpec.dataHandle)
  481.       ignoreErr = AEDisposeDesc(&propObjSpec);
  482.  
  483.     if (theData->dataHandle)
  484.         ignoreErr = AEDisposeDesc(theData);
  485.  
  486.     if (toWhom->dataHandle)
  487.         ignoreErr = AEDisposeDesc(toWhom);
  488.  
  489.     return myErr;
  490. }    /* SendAESetObjProp */
  491.  
  492. /*----------------------------------------------------------------------------------------------*/
  493. /*
  494.     Private AEObject definitions
  495. */
  496. #if !defined(powerc) && !defined(__powerc)
  497. #pragma segment AECommandHandlers
  498. #endif
  499.  
  500. #define typeMyAppl       'BAPP'    /* sig of my private token type for the app     - appToken   */
  501. #define typeMyWndw         'BWIN'    /* sig of my private token type for windows     - windowToken   */
  502. #define typeMyText           'BTXT'    /* sig of my private token type for text        - textToken     */
  503. #define typeMyTextProp   'BPRP'    /* sig of my private token type for text properties    - textPropToken */
  504. #define typeMyWindowProp 'WPRP'    /* sig of my private token type for window properties  - windowPropToken */
  505. #define typeMyApplProp   'APRP'    /* sig of my private token type for appl properties    - applPropToken */
  506. #define typeMyMenu       'MTKN'    /* sig of my private token type for menus       - menuToken  */
  507. #define typeMyMenuItem   'ITKN'    /* sig of my private token type for menus       - menuItemToken  */
  508. #define typeMyMenuProp   'MPRP'    /* sig of my private token type for menu properties - menuPropToken  */
  509. #define typeMyItemProp   'IPRP'    /* sig of my private token type for menu item properties  - menuItemPropToken  */
  510.  
  511. /* These are entirely private to our app - used only when resolving the object specifier */
  512.  
  513. typedef    ProcessSerialNumber appToken;
  514.  
  515. struct applPropToken{
  516.     appToken tokenApplToken;
  517.     DescType tokenApplProperty;
  518. };
  519.  
  520. typedef struct applPropToken applPropToken;
  521.  
  522. typedef    WindowPtr WindowToken;
  523.  
  524. struct windowPropToken{
  525.         WindowToken tokenWindowToken;
  526.         DescType    tokenProperty;
  527.     };
  528.  
  529. typedef struct windowPropToken windowPropToken;
  530.  
  531. struct TextToken{
  532.         WindowPtr tokenWindow;
  533.         short     tokenOffset;
  534.         short     tokenLength;
  535.     };
  536.  
  537. typedef struct TextToken TextToken;
  538.  
  539. struct textPropToken{
  540.         TextToken propertyTextToken;
  541.         DescType  propertyProperty;
  542.     };
  543.  
  544. typedef struct textPropToken textPropToken;
  545.  
  546. /* Tokens related to menus */
  547.  
  548. struct MenuToken {
  549.     MenuHandle theTokenMenu;
  550.     short      theTokenID;
  551. };
  552.  
  553. typedef struct MenuToken MenuToken;
  554.  
  555. struct MenuItemToken {
  556.     MenuToken  theMenuToken;
  557.     short      theTokenItem;
  558. };
  559.  
  560. typedef struct MenuItemToken MenuItemToken;
  561.  
  562. struct MenuPropToken {
  563.     MenuToken  theMenuToken;
  564.     DescType   theMenuProp;
  565. };
  566.  
  567. typedef struct MenuPropToken MenuPropToken;
  568.  
  569. struct MenuItemPropToken {
  570.     MenuItemToken  theItemToken;
  571.     DescType       theItemProp;
  572. };
  573.  
  574. typedef struct MenuItemPropToken MenuItemPropToken;
  575.  
  576. /*
  577.     Name: GotRequiredParams
  578.     Function: Checks all parameters defined as 'required' have been read
  579. */
  580. pascal OSErr GotRequiredParams(const AppleEvent *theAppleEvent)
  581. {
  582.     OSErr    myErr;
  583.     DescType returnedType;
  584.     Size     actSize;
  585.  
  586.     /* look for the keyMissedKeywordAttr, just to see if it's there */
  587.  
  588.     myErr =
  589.         AEGetAttributePtr(
  590.             theAppleEvent,
  591.             keyMissedKeywordAttr,
  592.             typeWildCard,
  593.             &returnedType,
  594.             nil,
  595.             0,
  596.             &actSize);
  597.  
  598.     if (myErr == errAEDescNotFound)
  599.         return noErr;            /* attribute not there means we got all req params */
  600.     else
  601.         if (myErr == noErr)
  602.             return errAEParamMissed;        /* attribute there means missed at least one */
  603.         else
  604.             return myErr;        /* some unexpected arror in looking for the attribute */
  605. }    /* GotReqiredParams */
  606.  
  607. /**--------------------------------------------------------------------
  608.     Name : SetSelectionOfAppleEventDirectObject
  609.     Function : Resolves the Direct Object into a text token and
  610.                          sets the selection of the specified document to that
  611.                          specified in the direct object.
  612.                          Returns the doc and TEHandle chosen.
  613.     --------------------------------------------------------------------**/
  614.  
  615. pascal OSErr SetSelectionOfAppleEventDirectObject(
  616.     const AppleEvent *theAppleEvent,
  617.     DPtr             *theDocument,
  618.     TEHandle         *theHTE)
  619. {
  620.     OSErr     myErr;
  621.     DescType  returnedType;
  622.     long      actSize;
  623.     TextToken myTextToken;
  624.     OSErr     paramErr;
  625.     WindowPtr fWin;
  626.  
  627.     paramErr =
  628.         AEGetParamPtr(
  629.             theAppleEvent,
  630.             keyDirectObject,
  631.             typeMyText,
  632.             &returnedType,
  633.             (Ptr)&myTextToken,
  634.             sizeof(myTextToken),
  635.             &actSize);
  636.  
  637.     myErr = GotRequiredParams(theAppleEvent);
  638.  
  639.     /* now let's work on the direct object, if any */
  640.  
  641.     if (paramErr == errAEDescNotFound) {
  642.         /* no direct object; check we have a window */
  643.  
  644.         fWin = FrontWindow();
  645.  
  646.         if (fWin == nil)
  647.             return -1700; /* Generic Err */
  648.  
  649.         *theDocument = DPtrFromWindowPtr(fWin);
  650.         *theHTE      = (*theDocument)->theText;
  651.     }
  652.  
  653.     if (paramErr == noErr)  {
  654.         /* got a text token */
  655.  
  656.         *theDocument = DPtrFromWindowPtr(myTextToken.tokenWindow);
  657.         *theHTE      = (*theDocument)->theText;
  658.  
  659.         TESetSelect(
  660.             myTextToken.tokenOffset-1,
  661.             myTextToken.tokenOffset+myTextToken.tokenLength-1,
  662.             *theHTE);
  663.  
  664.     }
  665.  
  666.     if ((paramErr!=noErr) &&
  667.          (paramErr!=errAEDescNotFound)
  668.     ) {
  669.          *theDocument = DPtrFromWindowPtr(FrontWindow());
  670.          *theHTE      = (*theDocument)->theText;
  671.      }
  672.  
  673.     return myErr;
  674.  
  675. } /* SetSelectionOfAppleEventDirectObject */
  676.  
  677. /**--------------------------------------------------------------------
  678.     Name             : SetSelectionOfAppleEventObject
  679.     Function     : Resolves the whatObject type of the AppleEvent into a text
  680.                       token and sets the selection to be that specified in the
  681.                       text token.
  682.                       Returns the doc and TEHandle chosen.
  683.     --------------------------------------------------------------------**/
  684.  
  685. pascal OSErr SetSelectionOfAppleEventObject(
  686.     OSType            whatObject,
  687.     const AppleEvent *theAppleEvent,
  688.     DPtr             *theDocument,
  689.     TEHandle         *theHTE)
  690. {
  691.     DescType   returnedType;
  692.     long       actSize;
  693.     TextToken  myTextToken;
  694.     OSErr      paramErr;
  695.  
  696.     paramErr  =
  697.         AEGetParamPtr(
  698.             theAppleEvent,
  699.             whatObject,
  700.             typeMyText,
  701.             &returnedType,
  702.             (Ptr)&myTextToken,
  703.             sizeof(myTextToken),
  704.             &actSize);
  705.  
  706.     if (paramErr == noErr) {
  707.         /* got a text token */
  708.  
  709.         *theDocument = DPtrFromWindowPtr(myTextToken.tokenWindow);
  710.         *theHTE      = (*theDocument)->theText;
  711.  
  712.         TESetSelect(
  713.             myTextToken.tokenOffset-1,
  714.             myTextToken.tokenOffset+myTextToken.tokenLength-1,
  715.             *theHTE);
  716.     }
  717.  
  718.     return paramErr;
  719. } /* SetSelectionOfAppleEventObject */
  720.  
  721. pascal void EnforceMemory(DPtr theDocument, TEHandle theHTE)
  722. {
  723.     if (theDocument->kind != kDocumentWindow && (*theHTE)->teLength > theDocument->u.cons.memory) {
  724.         short    obulus =    (*theHTE)->teLength - theDocument->u.cons.memory;
  725.         short saveStart;
  726.         short    saveEnd;
  727.         Ptr    search = *(*theHTE)->hText;
  728.         short rest   = theDocument->u.cons.memory;
  729.         
  730.         while (search[obulus-1] != '\n' && rest--)
  731.             ++obulus;
  732.             
  733.         saveStart    =    (*theHTE)->selStart - obulus;
  734.         saveEnd        =    (*theHTE)->selEnd      - obulus;
  735.         
  736.         TESetSelect(0, obulus, theHTE);
  737.         TEDelete(theHTE);
  738.         TESetSelect(saveStart < 0 ? 0 : saveStart, saveEnd < 0 ? 0 : saveEnd, theHTE);
  739.         
  740.         if (theDocument->u.cons.fence < 32767)
  741.             theDocument->u.cons.fence    -=    obulus;
  742.     }
  743. }
  744.  
  745. /* -----------------------------------------------------------------------
  746.         Name:         DoCopyEdit
  747.         Purpose:        Performs a copy text operation on the text selection specified
  748.                         by the appleEvent direct object (if any)
  749.      -----------------------------------------------------------------------**/
  750.  
  751. pascal OSErr DoCopyEdit(const AppleEvent *theAppleEvent,AppleEvent *reply, long refCon)
  752. {
  753. #if !defined(powerc) && !defined(__powerc)
  754. #pragma unused (reply,refCon)
  755. #endif
  756.  
  757.     OSErr    myErr;
  758.     TEHandle theHTE;
  759.     DPtr     theDocument;
  760.  
  761.     /*
  762.             Here we extract the information about what to copy from the
  763.             directObject - if any
  764.     */
  765.  
  766.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent,&theDocument,&theHTE))
  767.         return myErr;
  768.  
  769.     myErr = (OSErr) ZeroScrap();
  770.     TECopy(theHTE);
  771.     TEToScrap();
  772.  
  773.     if (myErr)
  774.         return myErr;
  775.  
  776.     if (!SetSelectionOfAppleEventObject(
  777.         keyAEContainer,
  778.         theAppleEvent,
  779.         &theDocument,
  780.         &theHTE)
  781.     ) {
  782.         if (theDocument->kind == kDocumentWindow) {
  783.             DoTEPasteSectionRecalc(theDocument);
  784.         } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  785.             SysBeep(1);
  786.             
  787.             return errAEEventNotHandled;
  788.         }
  789.             
  790.         TEFromScrap();
  791.         TEPaste(theHTE);
  792.         EnforceMemory(theDocument, theHTE);
  793.         AdjustScrollbars(theDocument, false);
  794.         DrawPageExtras(theDocument);
  795.             
  796.         theDocument->dirty = true;
  797.     }
  798.  
  799.     return noErr;
  800. } /* DoCopyEdit */
  801.  
  802. /* -----------------------------------------------------------------------
  803.         Name:             DoCutEdit
  804.         Purpose:        Performs a cut text operation on the current text selection
  805.      -----------------------------------------------------------------------**/
  806.  
  807. pascal OSErr DoCutEdit(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  808. {
  809. #if !defined(powerc) && !defined(__powerc)
  810. #pragma unused (reply,refCon)
  811. #endif
  812.  
  813.     OSErr    myErr;
  814.     TEHandle theHTE;
  815.     DPtr     theDocument;
  816.  
  817.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent,&theDocument,&theHTE))
  818.         return myErr;
  819.  
  820.     if (theDocument->kind == kDocumentWindow) {
  821.         DoTECutSectionRecalc(theDocument);
  822.         
  823.         theDocument->dirty = true;
  824.     } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  825.         if (AllSelected(theHTE)) {
  826.             if (theDocument->u.cons.fence < 32767)
  827.                 theDocument->u.cons.fence = 0;
  828.         } else {
  829.             SysBeep(1);
  830.         
  831.             return DoCopyEdit(theAppleEvent, reply, refCon);
  832.         }
  833.     }
  834.  
  835.     myErr = (OSErr) ZeroScrap();
  836.     TECut(theHTE);
  837.     TEToScrap();
  838.     AdjustScrollbars(theDocument, false);
  839.     DrawPageExtras(theDocument);
  840.  
  841.     return myErr;
  842. } /* DoCutEdit */
  843.  
  844. /* -----------------------------------------------------------------------
  845.         Name:         DoPasteEdit
  846.         Purpose:        Performs a paste text operation on the text selection specified
  847.                         by the appleEvent direct object (if any)
  848.      -----------------------------------------------------------------------**/
  849.  
  850. pascal OSErr DoPasteEdit(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  851. {
  852. #if !defined(powerc) && !defined(__powerc)
  853. #pragma unused (reply,refCon)
  854. #endif
  855.  
  856.     OSErr    myErr;
  857.     TEHandle theHTE;
  858.     DPtr     theDocument;
  859.  
  860.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent, &theDocument, &theHTE))
  861.         return myErr;
  862.  
  863.     if (theDocument->kind == kDocumentWindow) {
  864.         DoTEPasteSectionRecalc(theDocument);
  865.     } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  866.         SysBeep(1);
  867.             
  868.         return errAEEventNotHandled;
  869.     }
  870.     
  871.     TEFromScrap();
  872.     TEPaste(theHTE);
  873.     EnforceMemory(theDocument, theHTE);
  874.     AdjustScrollbars(theDocument, false);
  875.     DrawPageExtras(theDocument);
  876.         
  877.     theDocument->dirty = true;
  878.  
  879.     return noErr;
  880. } /* DoPasteEdit */
  881.  
  882. /* -----------------------------------------------------------------------
  883.         Name:         DoDeleteEdit
  884.         Purpose:        Performs a delete text operation on the selection specified
  885.                         by the appleEvent direct object (if any)
  886.      -----------------------------------------------------------------------**/
  887.  
  888. pascal OSErr DoDeleteEdit(const AppleEvent *theAppleEvent, AppleEvent *reply, long refcon)
  889. {
  890. #if !defined(powerc) && !defined(__powerc)
  891. #pragma unused (reply,refcon)
  892. #endif
  893.  
  894.     OSErr     myErr;
  895.     TEHandle theHTE;
  896.     DPtr     theDocument;
  897.  
  898.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent, &theDocument, &theHTE))
  899.         return myErr;
  900.  
  901.     if (theDocument->kind == kDocumentWindow) {
  902.         DoTEDeleteSectionRecalc(theDocument);
  903.     } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  904.         if (AllSelected(theHTE)) {
  905.             if (theDocument->u.cons.fence < 32767)
  906.                 theDocument->u.cons.fence = 0;
  907.         } else {
  908.             SysBeep(1);
  909.                 
  910.             return errAEEventNotHandled;
  911.         }
  912.         theDocument->u.cons.fence = 0;
  913.     }
  914.     
  915.     TEDelete(theHTE);
  916.     AdjustScrollbars(theDocument, false);
  917.     DrawPageExtras(theDocument);
  918.     theDocument->dirty = true;
  919.  
  920.     return noErr;
  921. } /*DoDeleteEdit*/
  922.  
  923. void RecalcFontInfo(TEHandle te)
  924. {
  925.     TEPtr        t;
  926.     short        oldFont;
  927.     short        oldSize;
  928.     FontInfo    info;
  929.  
  930.     HLock((Handle) te);
  931.  
  932.     t             = *te;
  933.     oldFont    =    t->inPort->txFont;
  934.     oldSize    =    t->inPort->txSize;
  935.  
  936.     SetPort(t->inPort);
  937.     TextFont(t->txFont);
  938.     TextSize(t->txSize);
  939.     GetFontInfo(&info);
  940.     TextFont(oldFont);
  941.     TextSize(oldSize);
  942.  
  943.     t->lineHeight    =    info.ascent+info.descent+info.leading;
  944.     t->fontAscent    =    info.ascent;
  945.     InvalRect(&t->viewRect);
  946.     HUnlock((Handle) te);
  947.  
  948.     TECalText(te);
  949. }
  950.  
  951. /* -----------------------------------------------------------------------
  952.         Name:         SetWindowProperty
  953.         Purpose:        Sets the window property specified in theWindowPropToken to
  954.                         be that supplied in dataDesc.
  955.      -----------------------------------------------------------------------**/
  956.  
  957. pascal OSErr SetWindowProperty(const AEDesc *theWPTokenDesc, const AEDesc *dataDesc)
  958. {
  959.       Str255          name;
  960.     DPtr            theDocument;
  961.     short                 size;
  962.     short                 font;
  963.     OSErr           err;
  964.     OSErr           ignoreErr;
  965.     Rect            thePosnRect;
  966.     Boolean         theBoolean;
  967.     TEHandle        theHTE;
  968.     GrafPtr         oldPort;
  969.     Point           thePosn;
  970.     THPrint         theTHPrint;
  971.     windowPropToken theWindowPropToken;
  972.     AEDesc          newDesc;
  973.     AEDesc          tokenDesc;
  974.     Size            tokenSize;
  975.     TextToken       myTextToken;
  976.     short           hOffset;
  977.     short           vOffset;
  978.  
  979.     if (err = AECoerceDesc(theWPTokenDesc, typeMyWindowProp, &newDesc))
  980.         return err;
  981.  
  982.     GetRawDataFromDescriptor(
  983.         &newDesc,
  984.         (Ptr)&theWindowPropToken,
  985.         sizeof(theWindowPropToken),
  986.         &tokenSize);
  987.  
  988.     err = AEDisposeDesc(&newDesc);
  989.  
  990.     GetPort(&oldPort);
  991.     SetPort(theWindowPropToken.tokenWindowToken);
  992.  
  993.     theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  994.  
  995.     switch (theWindowPropToken.tokenProperty) {
  996.     case pName:
  997.         err = GetPStringFromDescriptor(dataDesc, (char *)name);
  998.         if (err==noErr)
  999.             if (theDocument->kind != kDocumentWindow)
  1000.                 return errAEEventNotHandled;
  1001.             else if (name[0] == 0)
  1002.                 err = errAEWrongDataType;
  1003.             else {
  1004.                 SetWTitle(theWindowPropToken.tokenWindowToken, name);
  1005.                 PLstrcpy(theDocument->theFileName, name); /* Should we do this??? */
  1006.                 theDocument->dirty = true;
  1007.             }
  1008.         break;
  1009.  
  1010.     case pText:
  1011.     case pContents:
  1012.         theHTE = theDocument->theText;
  1013.         TESetSelect(0, 32000, theHTE);
  1014.  
  1015.         if (theDocument->kind == kDocumentWindow) {
  1016.             DoTEDeleteSectionRecalc(theDocument);
  1017.         } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  1018.             SysBeep(1);
  1019.             
  1020.             return errAEEventNotHandled;
  1021.         }
  1022.         
  1023.         TEDelete(theHTE);
  1024.         GetTextFromDescIntoTEHandle(dataDesc, theHTE);
  1025.         EnforceMemory(theDocument, theHTE);
  1026.         
  1027.         theDocument->dirty = true;
  1028.         break;
  1029.  
  1030.     case pBounds:
  1031.         err = GetRectFromDescriptor(dataDesc, &thePosnRect);
  1032.         /* the rectangle is for the structure region, and is in global coordinates */
  1033.         /* MoveWindow and SizeWindow apply to the content region, so we have to massage a little */
  1034.  
  1035.         thePosnRect.top    += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.top -
  1036.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.top;
  1037.  
  1038.         thePosnRect.left   += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.left -
  1039.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.left;
  1040.  
  1041.         thePosnRect.bottom += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.bottom -
  1042.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.bottom;
  1043.  
  1044.         thePosnRect.right  += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.right -
  1045.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.right;
  1046.  
  1047.         if (EmptyRect(&thePosnRect))
  1048.             err = errAECorruptData;
  1049.         else {
  1050.             MoveWindow(
  1051.                 theWindowPropToken.tokenWindowToken,
  1052.                 thePosnRect.left,
  1053.                 thePosnRect.top,
  1054.                 false);
  1055.             SizeWindow(
  1056.                 theWindowPropToken.tokenWindowToken,
  1057.                 thePosnRect.right- thePosnRect.left,
  1058.                 thePosnRect.bottom-thePosnRect.top,
  1059.                 true);
  1060.             ResizeWindow(theDocument);
  1061.         }
  1062.         break;
  1063.  
  1064.     case pPosition:
  1065.         err = GetPointFromDescriptor(dataDesc, &thePosn);
  1066.         /* the point is for the structure region, and is in global coordinates */
  1067.         /* MoveWindow applies to the content region, so we have to massage a little */
  1068.  
  1069.         hOffset = (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.left -
  1070.                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.left;
  1071.  
  1072.         vOffset = (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.top -
  1073.                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.top;
  1074.  
  1075.         thePosn.v  += vOffset;
  1076.         thePosn.h  += hOffset;
  1077.  
  1078.         MoveWindow(
  1079.             theWindowPropToken.tokenWindowToken,
  1080.             thePosn.h,
  1081.             thePosn.v,
  1082.             false);
  1083.  
  1084.         ResizeWindow(theDocument);
  1085.         break;
  1086.  
  1087.     case pIsZoomed:
  1088.         err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  1089.         if (theBoolean)
  1090.             ZoomWindow(qd.thePort, inZoomOut, false);
  1091.         else
  1092.             ZoomWindow(qd.thePort, inZoomIn, false);
  1093.  
  1094.         ResizeWindow(theDocument);
  1095.         break;
  1096.  
  1097.     case pVisible:
  1098.         err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  1099.         if (theBoolean)
  1100.             DoShowWindow(theWindowPropToken.tokenWindowToken);
  1101.         else
  1102.             DoHideWindow(theWindowPropToken.tokenWindowToken);
  1103.         break;
  1104.  
  1105.     case pPageSetup:
  1106.         err = GetTHPrintFromDescriptor(dataDesc, &theTHPrint);
  1107.  
  1108.         if (theTHPrint) {
  1109.             if (theDocument->thePrintSetup)
  1110.                 DisposHandle((Handle)theDocument->thePrintSetup);
  1111.  
  1112.             theDocument->thePrintSetup = theTHPrint;
  1113.  
  1114.             ResizePageSetupForDocument(theDocument);
  1115.         }
  1116.         break;
  1117.  
  1118.     case pShowBorders:
  1119.         if (theDocument->kind != kDocumentWindow)
  1120.             return errAEEventNotHandled;
  1121.             
  1122.         err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  1123.         theDocument->u.reg.showBorders = theBoolean;
  1124.         if (theBoolean)
  1125.             DrawPageExtras(theDocument); /* Does the clipping as well as drawing borders/page breaks */
  1126.         else
  1127.             InvalidateDocument(theDocument);
  1128.         break;
  1129.  
  1130.     case pFont:
  1131.         err = GetPStringFromDescriptor(dataDesc, (char *)name);
  1132.         GetFNum(name, &font);
  1133.     
  1134.         (*theDocument->theText)->txFont = font;
  1135.         RecalcFontInfo(theDocument->theText);
  1136.         AdjustScrollbars(theDocument, false);
  1137.         DrawPageExtras(theDocument);
  1138.         
  1139.         if (theDocument->kind == kDocumentWindow)
  1140.             theDocument->dirty = true;
  1141.     
  1142.         if (theDocument->theWindow == FrontWindow() && !gInBackground)
  1143.             AdjustScript(theDocument);
  1144.  
  1145.         break;
  1146.  
  1147.     case pPointSize:
  1148.         err = GetIntegerFromDescriptor(dataDesc, &size);
  1149.  
  1150.         (*theDocument->theText)->txSize = size;
  1151.         RecalcFontInfo(theDocument->theText);
  1152.         AdjustScrollbars(theDocument, false);
  1153.         DrawPageExtras(theDocument);
  1154.         
  1155.         if (theDocument->kind == kDocumentWindow)
  1156.             theDocument->dirty = true;
  1157.  
  1158.         if (theDocument->theWindow == FrontWindow() && !gInBackground)
  1159.             AdjustScript(theDocument);
  1160.  
  1161.         break;
  1162.  
  1163.     case pSelection:
  1164.         err = AECoerceDesc(dataDesc, typeMyText, &tokenDesc);
  1165.  
  1166.         GetRawDataFromDescriptor(&tokenDesc,
  1167.                                                          (Ptr)&myTextToken,
  1168.                                                          sizeof(myTextToken),
  1169.                                                          &tokenSize);
  1170.  
  1171.         ignoreErr = AEDisposeDesc(&tokenDesc);
  1172.  
  1173.         if (err == noErr) {
  1174.             /* got a text token */
  1175.  
  1176.             theDocument = DPtrFromWindowPtr(myTextToken.tokenWindow);
  1177.             theHTE      = theDocument->theText;
  1178.  
  1179.             TESetSelect(
  1180.                 myTextToken.tokenOffset-1,
  1181.                 myTextToken.tokenOffset+myTextToken.tokenLength-1,
  1182.                 theHTE);
  1183.         }
  1184.         break;
  1185.  
  1186.     case pIndex:
  1187.     case pIsModal:
  1188.     case pIsResizable:
  1189.     case pHasTitleBar:
  1190.     case pHasCloseBox:
  1191.     case pIsFloating:
  1192.     case pIsZoomable:
  1193.     case pIsModified:
  1194.         err = errAEEventNotHandled; /* We don't allow these to be set */
  1195.         break;
  1196.     }
  1197.     
  1198.     SetPort(oldPort);
  1199.  
  1200.     return err;
  1201. } /* SetWindowProperty */
  1202.  
  1203. /* -----------------------------------------------------------------------
  1204.         Name:         SetTextProperty
  1205.         Purpose:        Sets the text property specfied by theTextPropToken to
  1206.                         that in dataDesc.
  1207.      -----------------------------------------------------------------------**/
  1208.  
  1209. pascal OSErr SetTextProperty(const AEDesc *tokenDesc, const AEDesc *dataDesc)
  1210. {
  1211.     TEHandle      theHTE;
  1212.     DPtr          theDoc;
  1213.     OSErr         myErr;
  1214.     textPropToken theTextPropToken;
  1215.     AEDesc        newDesc;
  1216.     Size          tokenSize;
  1217.  
  1218.     newDesc.dataHandle = nil;
  1219.  
  1220.     if (myErr = AECoerceDesc(tokenDesc, typeMyTextProp, &newDesc))
  1221.         return myErr;
  1222.  
  1223.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextPropToken, sizeof(theTextPropToken), &tokenSize);
  1224.     myErr             =    AEDisposeDesc(&newDesc);
  1225.     theDoc             =    DPtrFromWindowPtr(theTextPropToken.propertyTextToken.tokenWindow);
  1226.     
  1227.     if (theDoc->kind == kDocumentWindow)
  1228.         theDoc->dirty     =    true;
  1229.  
  1230.     switch (theTextPropToken.propertyProperty) {
  1231.     case pText:
  1232.     case pContents:
  1233.         theHTE = theDoc->theText;
  1234.         TESetSelect(
  1235.             theTextPropToken.propertyTextToken.tokenOffset-1,
  1236.             theTextPropToken.propertyTextToken.tokenOffset+theTextPropToken.propertyTextToken.tokenLength-1,
  1237.             theHTE);
  1238.         
  1239.         if (theDoc->kind == kDocumentWindow) {
  1240.             DoTEDeleteSectionRecalc(theDoc);
  1241.         } else if (!theDoc->u.cons.selected || (*theHTE)->selStart < theDoc->u.cons.fence) {
  1242.             SysBeep(1);
  1243.             
  1244.             return errAEEventNotHandled;
  1245.         }
  1246.         
  1247.         TEDelete(theHTE);
  1248.         myErr = GetTextFromDescIntoTEHandle(dataDesc, theHTE);
  1249.         EnforceMemory(theDoc, theHTE);
  1250.             
  1251.         theDoc->dirty = true;
  1252.         
  1253.         return myErr;
  1254.     }
  1255.  
  1256.     return errAEWrongDataType;
  1257. } /* SetTextProperty */
  1258.  
  1259. /* -----------------------------------------------------------------------
  1260.         Name:         HandleSetData
  1261.         Purpose:        Resolves the object into a token (could be one of many) and
  1262.                         the sets the data of that object to dataDesc.
  1263.      -----------------------------------------------------------------------**/
  1264.  
  1265. pascal OSErr HandleSetData(const AEDesc *theObj, const AEDesc *dataDesc)
  1266. {
  1267.     OSErr           myErr;
  1268.     AEDesc          newDesc;
  1269.     DPtr            theDocument;
  1270.     TEHandle        theHTE;
  1271.     TextToken       theTextToken;
  1272.     Size            tokenSize;
  1273.     AEDesc          objTokenDesc;
  1274.     OSErr           ignoreErr;
  1275.  
  1276.     objTokenDesc.dataHandle = nil;
  1277.     newDesc.dataHandle      = nil;
  1278.  
  1279.     /*
  1280.         Coerce theObj into a token which we can use -
  1281.              set the property or data for that token
  1282.     */
  1283.  
  1284.     myErr = AEResolve(theObj ,kAEIDoMinimum, &objTokenDesc);
  1285.  
  1286.     /* We don't actually allow ANY app property setting, but
  1287.         just incase we'll decode looking for an typeMyApplProp and flag an error -
  1288.          do same for menu related tokens
  1289.     */
  1290.  
  1291.     if (
  1292.         (objTokenDesc.descriptorType == typeMyApplProp) ||
  1293.         (objTokenDesc.descriptorType == typeMyMenu    ) ||
  1294.         (objTokenDesc.descriptorType == typeMyMenuProp) ||
  1295.         (objTokenDesc.descriptorType == typeMyMenuItem) ||
  1296.         (objTokenDesc.descriptorType == typeMyItemProp)
  1297.     )
  1298.         myErr = errAEWrongDataType;
  1299.     else if (objTokenDesc.descriptorType == typeMyWindowProp)
  1300.         myErr = SetWindowProperty(&objTokenDesc, dataDesc);
  1301.     else if (objTokenDesc.descriptorType == typeMyTextProp)
  1302.         myErr = SetTextProperty(&objTokenDesc, dataDesc);
  1303.     else if (objTokenDesc.descriptorType == typeMyText)
  1304.         if (!AECoerceDesc(&objTokenDesc, typeMyText, &newDesc)) {
  1305.             GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextToken, sizeof(theTextToken), &tokenSize);
  1306.  
  1307.             myErr         = AEDisposeDesc(&newDesc);
  1308.             theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  1309.             theHTE        = theDocument->theText;
  1310.  
  1311.             TESetSelect(
  1312.                 theTextToken.tokenOffset-1,
  1313.                 theTextToken.tokenOffset+theTextToken.tokenLength-1,
  1314.                 theHTE);
  1315.                 
  1316.             if (theDocument->kind == kDocumentWindow) {
  1317.                 DoTEDeleteSectionRecalc(theDocument);
  1318.             } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  1319.                 SysBeep(1);
  1320.                 
  1321.                 return errAEEventNotHandled;
  1322.             }
  1323.             
  1324.             TEDelete(theHTE);
  1325.             myErr = GetTextFromDescIntoTEHandle(dataDesc, theHTE);
  1326.             EnforceMemory(theDocument, theHTE);
  1327.                 
  1328.             theDocument->dirty = true;
  1329.         }
  1330.  
  1331.     ignoreErr = AEDisposeDesc(&objTokenDesc);
  1332.  
  1333.     return myErr;
  1334. }    /* HandleSetData */
  1335.  
  1336. /*
  1337.     A few convenient FORWARDS...
  1338. */
  1339.  
  1340. pascal OSErr MakeWindowObj(WindowPtr theWindow, AEDesc *dMyDoc);
  1341.  
  1342. /*
  1343.     Back to real code
  1344. */
  1345. pascal OSErr MakeSelTextObj(WindowPtr theWindow, TEHandle theTextEditHandle, AEDesc *selTextObj)
  1346. {
  1347.     OSErr    myErr;
  1348.     OSErr    ignoreErr;
  1349.     AEDesc   dNull;
  1350.     AEDesc   dMyDoc;
  1351.     AEDesc   startOfs;
  1352.     AEDesc   endOfs;
  1353.     AEDesc   startObj;
  1354.     AEDesc   endObj;
  1355.     AEDesc   rangeDesc;
  1356.     long     startChar;
  1357.     long     endChar;
  1358.     Boolean  spotFlag;
  1359.  
  1360.     myErr = noErr;
  1361.  
  1362.     if (theWindow==nil)
  1363.         return noErr;
  1364.  
  1365.     selTextObj->dataHandle = nil;
  1366.     dMyDoc.dataHandle      = nil;
  1367.     startObj.dataHandle    = nil;
  1368.     endObj.dataHandle      = nil;
  1369.  
  1370.     /*
  1371.         make the window object
  1372.     */
  1373.  
  1374.     if (myErr = MakeWindowObj(theWindow, &dMyDoc))
  1375.         return myErr;
  1376.  
  1377.     /* get the start and end of selection */
  1378.  
  1379.     startChar = (*theTextEditHandle)->selStart+1;    /* start counting obj's from 1, not 0 */
  1380.     endChar   = (*theTextEditHandle)->selEnd;
  1381.     spotFlag  = ((*theTextEditHandle)->selStart == (*theTextEditHandle)->selEnd);
  1382.  
  1383.     if (myErr = CreateOffsetDescriptor(startChar, &startOfs))
  1384.         return myErr;
  1385.  
  1386.     if (spotFlag)
  1387.         myErr = CreateObjSpecifier(cSpot, &dMyDoc, formAbsolutePosition, &startOfs, true, selTextObj);
  1388.     else {
  1389.         /* not a spot - must represent as range */
  1390.         /* make obj for start char */
  1391.  
  1392.         myErr = AECreateDesc(typeNull, nil , 0, &dNull);
  1393.  
  1394.         myErr = CreateObjSpecifier(cChar, &dMyDoc, formAbsolutePosition, &startOfs, false, &startObj);
  1395.  
  1396.         if (myErr==noErr)
  1397.             myErr = CreateOffsetDescriptor(endChar, &endOfs);
  1398.  
  1399.         if (myErr==noErr)
  1400.             myErr = CreateObjSpecifier(cChar, &dMyDoc, formAbsolutePosition, &endOfs, false, &endObj);
  1401.  
  1402.         if (myErr==noErr)
  1403.             myErr = CreateRangeDescriptor(&startObj, &endObj, false, &rangeDesc);
  1404.  
  1405.         if (myErr==noErr)
  1406.             myErr = CreateObjSpecifier(cText, &dMyDoc, formRange, &rangeDesc, true, selTextObj);
  1407.  
  1408.         if (startObj.dataHandle)
  1409.           ignoreErr = AEDisposeDesc(&startObj);
  1410.  
  1411.         if (startOfs.dataHandle)
  1412.           ignoreErr = AEDisposeDesc(&startOfs);
  1413.  
  1414.         if (endObj.dataHandle)
  1415.           ignoreErr = AEDisposeDesc(&endObj);
  1416.  
  1417.         if (endOfs.dataHandle)
  1418.           ignoreErr = AEDisposeDesc(&endOfs);
  1419.     }
  1420.  
  1421.     return myErr;
  1422. }    /* MakeSelTextObj */
  1423.  
  1424. /* -----------------------------------------------------------------------
  1425.         Name:             DoSetData
  1426.         Purpose:        Handles the SetData Apple Event, extracting the direct
  1427.                                 object (which says what to set) and the data (what to set
  1428.                                 it to).
  1429.      -----------------------------------------------------------------------**/
  1430.  
  1431. pascal OSErr DoSetData(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon)
  1432. {
  1433. #if !defined(powerc) && !defined(__powerc)
  1434. #pragma unused (reply, handlerRefCon)
  1435. #endif
  1436.  
  1437.     OSErr  myErr;
  1438.     OSErr  ignoreErr;
  1439.     AEDesc myDirObj;
  1440.     AEDesc myDataDesc;
  1441.  
  1442.     myDataDesc.dataHandle = nil;
  1443.     myDirObj.dataHandle   = nil;
  1444.  
  1445.     /* pick up the direct object, which is the object whose data is to be set */
  1446.  
  1447.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  1448.  
  1449.     /* now the data to set it to - typeWildCard means get as is*/
  1450.     if (myErr == noErr)
  1451.         myErr = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &myDataDesc);
  1452.  
  1453.     /* missing any parameters? */
  1454.     if (myErr == noErr)
  1455.         myErr = GotRequiredParams(theAppleEvent);
  1456.  
  1457.     /* set the data */
  1458.     if (myErr == noErr)
  1459.         myErr = HandleSetData(&myDirObj, &myDataDesc);
  1460.  
  1461.     if (myDataDesc.dataHandle)
  1462.         ignoreErr = AEDisposeDesc(&myDataDesc);
  1463.  
  1464.     if (myDirObj.dataHandle)
  1465.         ignoreErr = AEDisposeDesc(&myDirObj);
  1466.  
  1467.     return myErr;
  1468. }    /* DoSetData */
  1469.  
  1470. pascal OSErr BuildStyledTextDesc(TEHandle theHTE, short start, short howLong, AEDesc *resultDesc)
  1471. {
  1472.     AEDesc       listDesc;
  1473.     OSErr        myErr;
  1474.     OSErr        ignoreErr;
  1475.  
  1476.     listDesc.dataHandle = nil;
  1477.  
  1478.     TESetSelect(start-1, start+howLong-2, theHTE);
  1479.  
  1480.     myErr = AECreateList(nil, 0, true,  &listDesc);
  1481.  
  1482.     HLock((Handle)(**theHTE).hText);
  1483.  
  1484.     if (myErr==noErr)
  1485.         myErr = AEPutKeyPtr(&listDesc,
  1486.                                   keyAEText,
  1487.                                                 typeChar,
  1488.                                                 (Ptr)&(*(**theHTE).hText)[start-1],
  1489.                                                 howLong);
  1490.  
  1491.     HUnlock((Handle)(**theHTE).hText);
  1492.  
  1493.     myErr = AEPutKeyPtr(&listDesc, keyAEStyles, typeScrapStyles, (Ptr)nil, 0);
  1494.  
  1495.     if (myErr==noErr)
  1496.         myErr = AECoerceDesc(&listDesc, typeStyledText, resultDesc); // should be typeIntlText
  1497.  
  1498.     if (listDesc.dataHandle)
  1499.         ignoreErr = AEDisposeDesc(&listDesc);
  1500.  
  1501.     return myErr;
  1502. }
  1503.  
  1504. /* -----------------------------------------------------------------------
  1505.         Name:             GetTextProperty
  1506.         Purpose:        Fills dataDesc with the requested text property.
  1507.      -----------------------------------------------------------------------**/
  1508.  
  1509. pascal OSErr GetTextProperty(const AEDesc *theTokenDesc, AEDesc *dataDesc)
  1510. {
  1511.       DPtr          theDocument;
  1512.     TEHandle      theHTE;
  1513.     short         theSize;
  1514.     GrafPtr       oldPort;
  1515.     textPropToken theTextPropToken;
  1516.     OSErr         myErr;
  1517.     Size          tokenSize;
  1518.     AEDesc        newDesc;
  1519.  
  1520.       if (myErr = AECoerceDesc(theTokenDesc, typeMyTextProp, &newDesc))
  1521.         return myErr;
  1522.  
  1523.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextPropToken, sizeof(theTextPropToken), &tokenSize);
  1524.     myErr= AEDisposeDesc(&newDesc);
  1525.  
  1526.     /*
  1527.         For each property we build a descriptor to be returned as the reply.
  1528.     */
  1529.  
  1530.     theDocument = DPtrFromWindowPtr(theTextPropToken.propertyTextToken.tokenWindow);
  1531.     theHTE         = theDocument->theText;
  1532.  
  1533.     switch (theTextPropToken.propertyProperty) {
  1534.     case pText:
  1535.     case pContents:
  1536.         return BuildStyledTextDesc(
  1537.                         theHTE,
  1538.                         theTextPropToken.propertyTextToken.tokenOffset,
  1539.                         theTextPropToken.propertyTextToken.tokenLength,
  1540.                         dataDesc);
  1541.     case pStringWidth:
  1542.         GetPort(&oldPort);
  1543.         SetPort(theTextPropToken.propertyTextToken.tokenWindow);
  1544.  
  1545.         HLock((Handle)(*theHTE)->hText);
  1546.         theSize =
  1547.             TextWidth(
  1548.                 &(*theHTE)->hText,
  1549.                 theTextPropToken.propertyTextToken.tokenOffset-1,
  1550.                 theTextPropToken.propertyTextToken.tokenLength);
  1551.         HUnlock((Handle)(*theHTE)->hText);
  1552.  
  1553.         SetPort(oldPort);
  1554.         return CreateOffsetDescriptor(theSize, dataDesc);
  1555.     default:
  1556.         return errAEEventNotHandled;
  1557.     }
  1558. } /*GetTextProperty*/
  1559.  
  1560. /* -----------------------------------------------------------------------
  1561.         Name:         GetWindowProperty
  1562.         Purpose:        Fills dataDesc with the requested window property.
  1563.      -----------------------------------------------------------------------**/
  1564. typedef Rect **RectHandle;
  1565.  
  1566. pascal OSErr GetWindowProperty(const AEDesc *theWPTokenObj, AEDesc *dataDesc)
  1567. {
  1568.      OSErr           theErr;
  1569.     Str255          theName;
  1570.     Boolean         theBoolean;
  1571.     Rect            theRect;
  1572.     Point           thePoint;
  1573.     Rect            winRect;
  1574.     Rect            userRect;
  1575.     short           theIndex;
  1576.     DPtr            theDocument;
  1577.     TEHandle        theHTE;
  1578.     windowPropToken theWindowPropToken;
  1579.     AEDesc          newDesc;
  1580.     Size            tokenSize;
  1581.  
  1582.       if (theErr = AECoerceDesc(theWPTokenObj,typeMyWindowProp, &newDesc))
  1583.           return theErr;
  1584.  
  1585.     GetRawDataFromDescriptor(
  1586.         &newDesc,
  1587.         (Ptr)&theWindowPropToken,
  1588.         sizeof(theWindowPropToken),
  1589.         &tokenSize);
  1590.  
  1591.     theErr = AEDisposeDesc(&newDesc);
  1592.  
  1593.     theErr = kAEGenericErr;
  1594.  
  1595.     switch (theWindowPropToken.tokenProperty) {
  1596.     case pName:
  1597.         GetWTitle(theWindowPropToken.tokenWindowToken, theName);
  1598.  
  1599.         theErr = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1600.         break;
  1601.     case pText:
  1602.     case pContents:
  1603.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1604.         theHTE      = theDocument->theText;
  1605.         theErr         = BuildStyledTextDesc(theHTE, 1, (**theHTE).teLength, dataDesc);
  1606.         break;
  1607.     case pBounds:
  1608.         SetPort(theWindowPropToken.tokenWindowToken);
  1609.  
  1610.         theRect = (*((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn)->rgnBBox;
  1611.         theErr  = AECreateDesc(typeQDRectangle, (Ptr)&theRect, sizeof(theRect), dataDesc);
  1612.         break;
  1613.     case pPosition:
  1614.         thePoint.v     = (*((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn)->rgnBBox.top;
  1615.         thePoint.h     = (*((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn)->rgnBBox.left;
  1616.         theErr       = AECreateDesc(typeQDPoint, (Ptr)&thePoint, sizeof(thePoint), dataDesc);
  1617.         break;
  1618.     case pVisible:
  1619.         theBoolean     = ((WindowPeek)theWindowPropToken.tokenWindowToken)->visible;
  1620.         theErr          = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1621.         break;
  1622.     case pIsModal:
  1623.         theBoolean     = false;
  1624.         theErr          = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1625.         break;
  1626.     case pShowBorders:
  1627.         theDocument    = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1628.         theBoolean    = (theDocument->kind == kDocumentWindow) ? theDocument->u.reg.showBorders : false;
  1629.         theErr          = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1630.         break;
  1631.     case pIsZoomed:
  1632.         if (((WindowPeek)theWindowPropToken.tokenWindowToken)->spareFlag) {
  1633.             SetPort(theWindowPropToken.tokenWindowToken);
  1634.  
  1635.             userRect = **((RectHandle)((WindowPeek)qd.thePort)->dataHandle);
  1636.             winRect  = qd.thePort->portRect;
  1637.             LocalToGlobal((Point *)&winRect.top);
  1638.             LocalToGlobal((Point *)&winRect.bottom);
  1639.  
  1640.             theBoolean = !EqualRect(&userRect, &winRect);
  1641.         } else
  1642.             theBoolean = false;
  1643.  
  1644.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1645.         break;
  1646.     case pIsResizable:
  1647.     case pHasTitleBar:
  1648.     case pIsZoomable:
  1649.     case pHasCloseBox:
  1650.         theBoolean     = true;
  1651.         theErr          = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1652.         break;
  1653.     case pIsFloating:
  1654.         theBoolean     = false;
  1655.         theErr          = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1656.         break;
  1657.     case pIsModified:
  1658.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1659.         theBoolean  = (theDocument->kind == kDocumentWindow) ? theDocument->dirty : true;
  1660.         theErr          = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1661.     case pIndex:
  1662.         theIndex = 0;
  1663.         if (theWindowPropToken.tokenWindowToken)
  1664.             do
  1665.                 theIndex++;
  1666.             while (theWindowPropToken.tokenWindowToken != GetWindowPtrOfNthWindow(theIndex));
  1667.         theErr  = AECreateDesc(typeShortInteger, (Ptr)theIndex, sizeof(theIndex), dataDesc);
  1668.         break;
  1669.     case pPageSetup:
  1670.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1671.  
  1672.         HLock((Handle)theDocument->thePrintSetup);
  1673.         theErr  = AECreateDesc(typeTPrint, (Ptr)*(theDocument->thePrintSetup), sizeof(TPrint), dataDesc);
  1674.         HUnlock((Handle)theDocument->thePrintSetup);
  1675.         
  1676.         break;
  1677.     case pSelection:
  1678.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1679.         theErr          = MakeSelTextObj(theWindowPropToken.tokenWindowToken, theDocument->theText, dataDesc);
  1680.         break;
  1681.     case pFont:
  1682.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1683.         
  1684.         GetFontName((*theDocument->theText)->txFont, theName);
  1685.  
  1686.         theErr = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1687.         break; 
  1688.     case pPointSize:
  1689.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1690.         theErr         = CreateOffsetDescriptor((*theDocument->theText)->txSize, dataDesc);
  1691.         break;
  1692.     case pScriptTag:
  1693.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1694.         theErr         = CreateOffsetDescriptor(FontToScript((*theDocument->theText)->txFont), dataDesc);
  1695.         break;
  1696.     }
  1697.  
  1698.     return theErr;
  1699. } /* GetWindowProperty */
  1700.  
  1701. /** -----------------------------------------------------------------------
  1702.         Name:             GetApplicationProperty
  1703.         Purpose:        Fills dataDesc with the requested application property.
  1704.      -----------------------------------------------------------------------**/
  1705.  
  1706. pascal OSErr GetApplicationProperty(const AEDesc *theObjToken, AEDesc *dataDesc)
  1707. {
  1708.       OSErr             theErr;
  1709.     Str255            theName;
  1710.     Boolean           isFront;
  1711.     applPropToken     theApplPropToken;
  1712.     AEDesc            newDesc;
  1713.     Size              tokenSize;
  1714.     AEStream            aes;
  1715.     Handle            scrap;
  1716.  
  1717.     if (theErr = AECoerceDesc(theObjToken, typeMyApplProp, &newDesc))
  1718.         return theErr;
  1719.  
  1720.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theApplPropToken, sizeof(theApplPropToken), &tokenSize);
  1721.  
  1722.     theErr = AEDisposeDesc(&newDesc);
  1723.     theErr = kAEGenericErr;
  1724.  
  1725.     switch (theApplPropToken.tokenApplProperty) {
  1726.     case pName:
  1727.         PLstrcpy((StringPtr)theName, (StringPtr) "\pMacPerl");
  1728.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1729.         break;
  1730.     case pVersion:
  1731.         PLstrcpy((StringPtr)theName, (StringPtr) "\p4.1.0");
  1732.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1733.         break;
  1734.     case pIsFrontProcess:
  1735.         isFront = !gInBackground;
  1736.         theErr  = AECreateDesc(typeBoolean, (Ptr)&isFront, sizeof(isFront), dataDesc);
  1737.         break;
  1738.     case pClipboard:
  1739.         if (theErr = AEStream_Open(&aes))
  1740.             break;
  1741.         if (theErr = AEStream_OpenList(&aes))
  1742.             goto abortClipboard;
  1743.         TEFromScrap();
  1744.         scrap = TEScrapHandle();
  1745.         HLock(scrap);
  1746.         theErr = AEStream_WriteDesc(&aes, typeChar, *scrap, GetHandleSize(scrap));
  1747.         HLock(scrap);
  1748.         if (theErr || (theErr = AEStream_CloseList(&aes)))
  1749.             goto abortClipboard;
  1750.         theErr = AEStream_Close(&aes, dataDesc);
  1751.         break;
  1752. abortClipboard:
  1753.         AEStream_Close(&aes, nil);
  1754.         break;
  1755.     }
  1756.     
  1757.     return theErr;
  1758. } /* GetApplicationProperty */
  1759.  
  1760. /** -----------------------------------------------------------------------
  1761.         Name:             GetMenuProperty
  1762.         Purpose:        Fills dataDesc with the requested menu property.
  1763.      -----------------------------------------------------------------------**/
  1764.  
  1765. pascal OSErr GetMenuProperty(const AEDesc *theObjToken, AEDesc *dataDesc)
  1766. {
  1767.       OSErr         theErr;
  1768.     Str255        theName;
  1769.     MenuPropToken theMenuPropToken;
  1770.     AEDesc        newDesc;
  1771.     Size          tokenSize;
  1772.  
  1773.     if (theErr = AECoerceDesc(theObjToken, typeMyMenuProp, &newDesc))
  1774.         return theErr;
  1775.  
  1776.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theMenuPropToken, sizeof(theMenuPropToken), &tokenSize);
  1777.  
  1778.     theErr = AEDisposeDesc(&newDesc);
  1779.     theErr = kAEGenericErr;
  1780.  
  1781.     if (theMenuPropToken.theMenuProp == pName)  {
  1782.           PLstrcpy(theName, (**theMenuPropToken.theMenuToken.theTokenMenu).menuData);
  1783.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1784.     }
  1785.  
  1786.     if (theMenuPropToken.theMenuProp == pMenuID) {
  1787.         theErr  =
  1788.             AECreateDesc(
  1789.                 typeShortInteger,
  1790.                 (Ptr)&theMenuPropToken.theMenuToken.theTokenID,
  1791.                 sizeof(theMenuPropToken.theMenuToken.theTokenID),
  1792.                 dataDesc);
  1793.     }
  1794.  
  1795.     return theErr;
  1796. } /* GetMenuProperty */
  1797.  
  1798. /** -----------------------------------------------------------------------
  1799.         Name:         GetMenuItemProperty
  1800.         Purpose:        Fills dataDesc with the requested menu property.
  1801.      -----------------------------------------------------------------------**/
  1802.  
  1803. pascal OSErr GetMenuItemProperty(const AEDesc *theObjToken, AEDesc *dataDesc)
  1804. {
  1805.       OSErr             theErr;
  1806.     Str255            theName;
  1807.     MenuItemPropToken theMenuItemPropToken;
  1808.     AEDesc            newDesc;
  1809.     Size              tokenSize;
  1810.  
  1811.     if (theErr = AECoerceDesc(theObjToken, typeMyItemProp, &newDesc))
  1812.         return theErr;
  1813.  
  1814.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theMenuItemPropToken, sizeof(theMenuItemPropToken), &tokenSize);
  1815.  
  1816.     theErr = AEDisposeDesc(&newDesc);
  1817.     theErr = kAEGenericErr;
  1818.  
  1819.     if (theMenuItemPropToken.theItemProp == pName) {
  1820.           GetItem(
  1821.             theMenuItemPropToken.theItemToken.theMenuToken.theTokenMenu,
  1822.             theMenuItemPropToken.theItemToken.theTokenItem,
  1823.             theName);
  1824.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1825.     }
  1826.  
  1827.     if (theMenuItemPropToken.theItemProp == pItemNumber) {
  1828.         theErr  =
  1829.             AECreateDesc(
  1830.                 typeShortInteger,
  1831.                 (Ptr)&theMenuItemPropToken.theItemToken.theTokenItem,
  1832.                 sizeof(theMenuItemPropToken.theItemToken.theTokenItem),
  1833.                 dataDesc);
  1834.     }
  1835.  
  1836.     return theErr;
  1837. } /* GetMenuItemProperty */
  1838.  
  1839. /** -----------------------------------------------------------------------
  1840.         Name:         HandleGetData
  1841.         Purpose:        Coerces theObj into a token which we understand and
  1842.                         extracts the data requested in the token and puts it
  1843.                         into dataDesc.
  1844.      -----------------------------------------------------------------------**/
  1845.  
  1846. typedef char chars[32001];
  1847. typedef chars **charsHandle;
  1848.  
  1849. pascal OSErr HandleGetData(AEDesc *theObj, DescType whatType, AEDesc *dataDesc)
  1850. {
  1851. #if !defined(powerc) && !defined(__powerc)
  1852. #pragma unused (whatType)
  1853. #endif
  1854.  
  1855.       OSErr           myErr;
  1856.     AEDesc          newDesc;
  1857.     TextToken       theTextToken;
  1858.     Size            tokenSize;
  1859.     DPtr            theDoc;
  1860.     AEDesc          objTokenDesc;
  1861.  
  1862.     myErr = errAEWrongDataType;
  1863.  
  1864.     /*
  1865.         Coerce theObj into a token which we can use -
  1866.              set the property for that token
  1867.     */
  1868.  
  1869.  
  1870.     if (myErr = AEResolve(theObj, kAEIDoMinimum, &objTokenDesc))
  1871.         return myErr;
  1872.  
  1873.     switch (objTokenDesc.descriptorType) {
  1874.     case typeMyApplProp:
  1875.         myErr = GetApplicationProperty(&objTokenDesc, dataDesc);
  1876.         break;
  1877.     case typeMyMenuProp:
  1878.         myErr = GetMenuProperty(&objTokenDesc, dataDesc);
  1879.         break;
  1880.     case typeMyItemProp:
  1881.         myErr = GetMenuItemProperty(&objTokenDesc, dataDesc);
  1882.         break;
  1883.     case typeMyTextProp:
  1884.         myErr = GetTextProperty(&objTokenDesc, dataDesc);
  1885.         break;
  1886.     case typeMyWindowProp:
  1887.         myErr = GetWindowProperty(&objTokenDesc, dataDesc);
  1888.         break;
  1889.     case typeMyText:
  1890.         if (!AECoerceDesc(&objTokenDesc, typeMyText, &newDesc)) {
  1891.             GetRawDataFromDescriptor(
  1892.                 &newDesc,
  1893.                 (Ptr)&theTextToken,
  1894.                 sizeof(theTextToken),
  1895.                 &tokenSize);
  1896.  
  1897.             myErr     = AEDisposeDesc(&newDesc);
  1898.  
  1899.             theDoc    = DPtrFromWindowPtr(theTextToken.tokenWindow);
  1900.  
  1901.             myErr     =
  1902.                 BuildStyledTextDesc(
  1903.                     theDoc->theText,
  1904.                     theTextToken.tokenOffset,
  1905.                     theTextToken.tokenLength,
  1906.                     dataDesc);
  1907.         break;
  1908.         }
  1909.     }
  1910.  
  1911.     return myErr;
  1912. }    /* HandleGetData */
  1913.  
  1914. /** -----------------------------------------------------------------------
  1915.         Name:         DoGetData
  1916.         Purpose:        Handles the GetData AppleEvent.
  1917.      -----------------------------------------------------------------------**/
  1918.  
  1919. pascal OSErr DoGetData(
  1920.     const AppleEvent *theAppleEvent,
  1921.     AppleEvent *reply,
  1922.     long handlerRefCon)
  1923. {
  1924. #if !defined(powerc) && !defined(__powerc)
  1925. #pragma unused (handlerRefCon)
  1926. #endif
  1927.  
  1928.     OSErr    myErr;
  1929.     OSErr    tempErr;
  1930.     AEDesc   myDirObj;
  1931.     AEDesc   myDataDesc;
  1932.     Size     actualSize;
  1933.     DescType returnedType;
  1934.     DescType reqType;
  1935.  
  1936.     myDataDesc.dataHandle = nil;
  1937.     myDirObj.dataHandle   = nil;
  1938.  
  1939.     /*
  1940.         extract the direct object, which is the object whose data is to be returned
  1941.     */
  1942.  
  1943.     myErr  = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  1944.  
  1945.     /*
  1946.         now the get the type of data wanted - optional
  1947.     */
  1948.  
  1949.     tempErr =
  1950.         AEGetParamPtr(
  1951.             theAppleEvent,
  1952.             keyAERequestedType,
  1953.             typeType,
  1954.             &returnedType,
  1955.             (Ptr)&reqType,
  1956.             sizeof(reqType),
  1957.             &actualSize);
  1958.  
  1959.     if (tempErr!=noErr)
  1960.         reqType = typeChar;
  1961.  
  1962.     if (myErr == noErr)
  1963.         myErr = GotRequiredParams(theAppleEvent);
  1964.  
  1965.     /* get the data */
  1966.     if (myErr == noErr)
  1967.         myErr = HandleGetData(&myDirObj, reqType, &myDataDesc);
  1968.  
  1969.     /* if they wanted a reply, attach it now */
  1970.     if (myErr==noErr)
  1971.         if (reply->descriptorType != typeNull)
  1972.             myErr = AEPutParamDesc(reply, keyDirectObject, &myDataDesc);
  1973.  
  1974.      if (myDataDesc.dataHandle)
  1975.           tempErr = AEDisposeDesc(&myDataDesc);
  1976.  
  1977.      if (myDirObj.dataHandle)
  1978.           tempErr = AEDisposeDesc(&myDirObj);
  1979.  
  1980.     return myErr;
  1981. }    /* DoGetData */
  1982.  
  1983.  
  1984. /** -----------------------------------------------------------------------
  1985.         Name:         DoGetDataSize
  1986.         Purpose:        Handles the GetDataSize AppleEvent.
  1987.      -----------------------------------------------------------------------**/
  1988.  
  1989. pascal OSErr DoGetDataSize(
  1990.     const AppleEvent *theAppleEvent,
  1991.     AppleEvent *reply,
  1992.     long       handlerRefCon)
  1993. {
  1994. #if !defined(powerc) && !defined(__powerc)
  1995. #pragma unused (handlerRefCon)
  1996. #endif
  1997.  
  1998.     OSErr     myErr;
  1999.     OSErr     tempErr;
  2000.     AEDesc    myDirObj;
  2001.     AEDesc    myDataDesc;
  2002.     Size      actualSize;
  2003.     DescType  returnedType;
  2004.     DescType  reqType;
  2005.     long      dataSize;
  2006.  
  2007.     myDataDesc.dataHandle = nil;
  2008.     myDirObj.dataHandle = nil;
  2009.  
  2010.     /* pick up the direct object, which is the object whose data is to be sized */
  2011.  
  2012.     myErr  = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2013.  
  2014.     /* now the get the type wanted - optional*/
  2015.  
  2016.     tempErr =
  2017.         AEGetParamPtr(
  2018.             theAppleEvent,
  2019.             keyAERequestedType,
  2020.             typeType,
  2021.             &returnedType,
  2022.             (Ptr)&reqType,
  2023.             sizeof(reqType),
  2024.             &actualSize);
  2025.  
  2026.     if (tempErr!=noErr)
  2027.         reqType = typeChar;
  2028.  
  2029.     if (myErr == noErr)
  2030.         myErr = GotRequiredParams(theAppleEvent);
  2031.  
  2032.     /* get the data */
  2033.     if (myErr == noErr)
  2034.         myErr = HandleGetData(&myDirObj, reqType, &myDataDesc);
  2035.  
  2036.     /* evaluate size of data and discard, create desc for size */
  2037.     if (myErr == noErr)
  2038.         if (myDataDesc.dataHandle) {
  2039.             dataSize = GetHandleSize((Handle)myDataDesc.dataHandle);
  2040.             DisposHandle((Handle)myDataDesc.dataHandle);
  2041.             myErr  = AECreateDesc(typeLongInteger, (Ptr)&dataSize, sizeof(dataSize), &myDataDesc);
  2042.         }
  2043.  
  2044.  
  2045.     /* if they wanted a reply, attach it now */
  2046.  
  2047.     if (myErr==noErr)
  2048.         if (reply->descriptorType != typeNull)
  2049.             myErr = AEPutParamDesc(reply, keyDirectObject, &myDataDesc);
  2050.  
  2051.     /* discard our copy */
  2052.  
  2053.     if (myDataDesc.dataHandle)
  2054.         tempErr = AEDisposeDesc(&myDataDesc);
  2055.  
  2056.     if (myDirObj.dataHandle)
  2057.         tempErr = AEDisposeDesc(&myDirObj);
  2058.  
  2059.     return myErr;
  2060. }    /* DoGetDataSize */
  2061.  
  2062. /** -----------------------------------------------------------------------
  2063.         Name:         DoNewElement
  2064.         Purpose:        Handles the NewElement AppleEvent. Only Creates windows for
  2065.                     now.
  2066.      -----------------------------------------------------------------------**/
  2067.  
  2068. pascal OSErr DoNewElement(
  2069.     const AppleEvent *theAppleEvent,
  2070.     AppleEvent *reply,
  2071.     long       handlerRefCon)
  2072. {
  2073. #if !defined(powerc) && !defined(__powerc)
  2074. #pragma unused (handlerRefCon)
  2075. #endif
  2076.  
  2077.     OSErr       myErr;
  2078.     OSErr       ignoreErr;
  2079.     DescType      returnedType;
  2080.     DescType      newElemClass;
  2081.     Size        actSize;
  2082.     AEDesc        wndwObjSpec;
  2083.     DPtr        theDoc;
  2084.  
  2085.     wndwObjSpec.dataHandle = nil;
  2086.  
  2087.     myErr =
  2088.         AEGetParamPtr(
  2089.             theAppleEvent,
  2090.             keyAEObjectClass,
  2091.             typeType,
  2092.             &returnedType,
  2093.             (Ptr)&newElemClass,
  2094.             sizeof(newElemClass),
  2095.             &actSize);
  2096.  
  2097.   /* check for missing required parameters */
  2098.  
  2099.   if (myErr == noErr)
  2100.         myErr = GotRequiredParams(theAppleEvent);
  2101.  
  2102.   /* got all required params */
  2103.  
  2104.   /* let's make sure container is the null desc */
  2105.   /* and they want a window */
  2106.  
  2107.   if (newElemClass != cWindow && newElemClass != cDocument)
  2108.     myErr = errAEWrongDataType;
  2109.  
  2110.   /* let's create a new window */
  2111.  
  2112.     if (myErr == noErr)
  2113.         theDoc = NewDocument(false, kDocumentWindow);
  2114.  
  2115.     if (myErr==noErr)
  2116.         if (theDoc == nil)
  2117.             myErr = -1700;
  2118.         else {
  2119.             DoShowWindow(theDoc->theWindow);
  2120.             theDoc->dirty = false;
  2121.             myErr = AEBuild(
  2122.                         &wndwObjSpec, 
  2123. /*                        "obj{want: type(@), form: 'indx', seld: 1, from: ()}", */
  2124.                         "obj{want:type(@),form:'indx',seld:1,from:()}",
  2125.                         sizeof(newElemClass), &newElemClass);
  2126.         }
  2127.  
  2128.     if (myErr == noErr)
  2129.         if (reply->descriptorType != typeNull)
  2130.              myErr = AEPutParamDesc(reply, keyDirectObject, &wndwObjSpec);
  2131.  
  2132.     if (wndwObjSpec.dataHandle)
  2133.         ignoreErr = AEDisposeDesc(&wndwObjSpec);
  2134.  
  2135.       return myErr;
  2136. }    /* DoNewElement */
  2137.  
  2138. /** -----------------------------------------------------------------------
  2139.         Name:         DoIsThereA
  2140.         Purpose:        Handles the IsThereA AppleEvent.
  2141.      -----------------------------------------------------------------------**/
  2142.  
  2143. pascal OSErr DoIsThereA(
  2144.     const AppleEvent *theAppleEvent,
  2145.     AppleEvent       *reply,
  2146.     long             handlerRefCon)
  2147. /*
  2148.     Support check of Windows at first
  2149.  
  2150.     What we do :
  2151.         Get Direct Object
  2152.         Check have all required params
  2153.         Coerce into things we support
  2154.         if we get something back
  2155.             check to see it exists and set reply
  2156.         clean up
  2157.         return
  2158. */
  2159. {
  2160. #if !defined(powerc) && !defined(__powerc)
  2161. #pragma unused (handlerRefCon)
  2162. #endif
  2163.  
  2164.     OSErr         myErr;
  2165.     OSErr         ignoreErr;
  2166.     AEDesc        myDirObject;
  2167.     AEDesc        windDesc;
  2168.     AEDesc        dataDesc;
  2169.     WindowToken   theWindowToken;
  2170.     Size          tokenSize;
  2171.     Boolean       exists;
  2172.  
  2173.     myDirObject.dataHandle = nil;
  2174.     windDesc.dataHandle    = nil;
  2175.     dataDesc.dataHandle    = nil;
  2176.  
  2177.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObject);
  2178.  
  2179.     /* check for missing required parameters */
  2180.  
  2181.     if (myErr == noErr)
  2182.         myErr = GotRequiredParams(theAppleEvent);
  2183.  
  2184.     /* got all required params */
  2185.  
  2186.     /* let's make sure they want to check for a window */
  2187.  
  2188.     exists = false;
  2189.  
  2190.     if (myErr == noErr)
  2191.         if (AECoerceDesc(&myDirObject, typeMyWndw, &windDesc)==noErr)
  2192.             if (windDesc.descriptorType!=typeNull) {
  2193.                 GetRawDataFromDescriptor(
  2194.                     &windDesc,
  2195.                     (Ptr)&theWindowToken,
  2196.                     sizeof(theWindowToken),
  2197.                     &tokenSize);
  2198.  
  2199.                 exists = (theWindowToken != nil);
  2200.             }
  2201.  
  2202.     if (myErr == noErr)
  2203.         myErr = AECreateDesc(typeBoolean, (Ptr)&exists, sizeof(exists), &dataDesc);
  2204.  
  2205.     /*
  2206.         if they wanted a reply, which they surely must,
  2207.         attach the result to it…
  2208.     */
  2209.  
  2210.     if (myErr == noErr)
  2211.         if (reply->descriptorType != typeNull)
  2212.              myErr = AEPutParamDesc(reply, keyDirectObject, &dataDesc);
  2213.  
  2214.     if (dataDesc.dataHandle)
  2215.         ignoreErr = AEDisposeDesc(&dataDesc);
  2216.  
  2217.     if (myDirObject.dataHandle)
  2218.         ignoreErr = AEDisposeDesc(&myDirObject);
  2219.  
  2220.     if (windDesc.dataHandle)
  2221.         ignoreErr = AEDisposeDesc(&windDesc);
  2222.  
  2223.     return myErr;
  2224. }    /* DoIsThereA */
  2225.  
  2226. /** -----------------------------------------------------------------------
  2227.         Name:         DoCloseWindow
  2228.         Purpose:        Handles the Close AppleEvent.
  2229.      -----------------------------------------------------------------------**/
  2230.  
  2231. pascal OSErr DoCloseWindow(
  2232.     const AppleEvent *theAppleEvent,
  2233.     AppleEvent       *reply,
  2234.     long             handlerRefCon)
  2235. {
  2236. #if !defined(powerc) && !defined(__powerc)
  2237. #pragma unused (reply, handlerRefCon)
  2238. #endif
  2239.  
  2240.     OSErr         myErr;
  2241.     OSErr         tempErr;
  2242.     AEDesc        myDirObj;
  2243.     AEDesc        newDesc;
  2244.     WindowToken   theWindowToken;
  2245.     Size          tokenSize;
  2246.     DescType      saveOpt;
  2247.     Size          actSize;
  2248.     DescType      returnedType;
  2249.     DPtr          myDPtr;
  2250.  
  2251.     myDirObj.dataHandle = nil;
  2252.  
  2253.     /* pick up the direct object, which is the object (window) to close */
  2254.  
  2255.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2256.  
  2257.     /* pick up optional save param, if any */
  2258.  
  2259.     saveOpt = kAEAsk; /* the default */
  2260.  
  2261.     tempErr =
  2262.         AEGetParamPtr(
  2263.             theAppleEvent,
  2264.             keyAESaveOptions,
  2265.             typeEnumerated,
  2266.             &returnedType,
  2267.             (Ptr)&saveOpt,
  2268.             sizeof(saveOpt),
  2269.             &actSize);
  2270.  
  2271.     if (myErr == noErr)
  2272.         myErr = GotRequiredParams(theAppleEvent);
  2273.  
  2274.     /* get the window to close as a window ptr */
  2275.     if (myErr == noErr)
  2276.         if (!AECoerceDesc(&myDirObj, typeMyWndw, &newDesc))
  2277.             if (newDesc.descriptorType!=typeNull)  {
  2278.                 GetRawDataFromDescriptor(
  2279.                     &newDesc,
  2280.                     (Ptr)&theWindowToken,
  2281.                     sizeof(theWindowToken),
  2282.                     &tokenSize);
  2283.  
  2284.                 myErr = AEDisposeDesc(&newDesc);
  2285.  
  2286.                 if (theWindowToken) {
  2287.                     myErr=AESetInteractionAllowed(kAEInteractWithAll); /* Should do this in prefs */
  2288.  
  2289.                     /*
  2290.                         We do some of the close checks here to avoid
  2291.                         calling AEInteractWithUser
  2292.                     */
  2293.                     if (!(myDPtr = DPtrFromWindowPtr(theWindowToken)))
  2294.                         myErr =  errAEIllegalIndex;
  2295.                     else if (myDPtr->kind == kDocumentWindow && (myDPtr->dirty || !myDPtr->u.reg.everSaved))
  2296.                         if (saveOpt != kAENo) /* Don't flip layers if force no ask */
  2297.                             myErr = AEInteractWithUser(kAEDefaultTimeout, nil, nil);
  2298.  
  2299.                     if (myErr==noErr)
  2300.                         myErr = DoClose(theWindowToken, true, saveOpt);
  2301.                 } else
  2302.                     myErr =  errAEIllegalIndex;
  2303.             }
  2304.  
  2305.     if (myDirObj.dataHandle)
  2306.         tempErr = AEDisposeDesc(&myDirObj);
  2307.  
  2308.     return myErr;
  2309. }    /* DoCloseWindow */
  2310.  
  2311. /** -----------------------------------------------------------------------
  2312.         Name:             DoSaveWindow
  2313.         Purpose:        Handles the Save AppleEvent.
  2314.      -----------------------------------------------------------------------**/
  2315.  
  2316. pascal OSErr DoSaveWindow(
  2317.     const AppleEvent *theAppleEvent,
  2318.     AppleEvent       *reply,
  2319.     long             handlerRefCon)
  2320. {
  2321. #if !defined(powerc) && !defined(__powerc)
  2322. #pragma unused (reply, handlerRefCon)
  2323. #endif
  2324.  
  2325.     OSErr             myErr;
  2326.     OSErr             tempErr;
  2327.     AEDesc            myDirObj;
  2328.     AEDesc            newDesc;
  2329.     WindowToken       theWindowToken;
  2330.     Size              tokenSize;
  2331.     Size              actSize;
  2332.     DescType          returnedType;
  2333.     DPtr              theDoc;
  2334.     OSType            type;
  2335.     FSSpec            destFSSpec;
  2336.  
  2337.     myDirObj.dataHandle = nil;
  2338.  
  2339.     /* pick up the direct object, which is the window to save */
  2340.  
  2341.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard,  &myDirObj);
  2342.  
  2343.     /* pick up optional destination param, if any */
  2344.  
  2345.     tempErr =
  2346.         AEGetParamPtr(
  2347.             theAppleEvent,
  2348.             keyAEDestination,
  2349.               typeFSS,
  2350.             &returnedType,
  2351.             (Ptr)&destFSSpec,
  2352.             sizeof(destFSSpec),
  2353.             &actSize);
  2354.  
  2355.     if (AEGetParamPtr(
  2356.             theAppleEvent,
  2357.             keyAEFileType,
  2358.               typeEnumerated,
  2359.             &returnedType,
  2360.             (Ptr)&type,
  2361.             sizeof(type),
  2362.             &actSize)
  2363.         || !CanSaveAs(type)
  2364.     )
  2365.         type = 0;
  2366.     
  2367.     if (myErr == noErr)
  2368.         myErr = GotRequiredParams(theAppleEvent);
  2369.  
  2370.     /* get the data */
  2371.  
  2372.     if (myErr = AECoerceDesc(&myDirObj, typeMyWndw, &newDesc))    {
  2373.         /* No window, maybe a file? */
  2374.         if (AECoerceDesc(&myDirObj, typeFSS, &newDesc)) {
  2375.             /* Apparently not, maybe just some text ? */
  2376.             if (!AECoerceDesc(&myDirObj, typeChar, &newDesc))
  2377.                 myErr = Handle2File(newDesc.dataHandle, destFSSpec, type ? type : 'TEXT');
  2378.         } else {
  2379.             FSSpec    fromFile;
  2380.             DocType    oldType;
  2381.             
  2382.             GetRawDataFromDescriptor(
  2383.                 &newDesc,
  2384.                 (Ptr)&fromFile,
  2385.                 sizeof(fromFile),
  2386.                 &tokenSize);
  2387.                 
  2388.             oldType = GetDocType(&fromFile);
  2389.             
  2390.             if (oldType == kUnknownDoc)
  2391.                 myErr = errAEWrongDataType;
  2392.             else
  2393.                 myErr = File2File(fromFile, oldType, destFSSpec, type ? type : oldType);
  2394.         }
  2395.     } else if (newDesc.descriptorType!=typeNull) {
  2396.         GetRawDataFromDescriptor(
  2397.             &newDesc,
  2398.             (Ptr)&theWindowToken,
  2399.             sizeof(theWindowToken),
  2400.             &tokenSize);
  2401.  
  2402.         myErr = AEDisposeDesc(&newDesc);
  2403.  
  2404.         if (theWindowToken) {
  2405.             theDoc = DPtrFromWindowPtr(theWindowToken);
  2406.  
  2407.             if (theDoc->kind != kDocumentWindow || theDoc->u.reg.everSaved == false)
  2408.                 if (tempErr != noErr)
  2409.                      /* We had no supplied destination and no default either */
  2410.                     myErr = kAEGenericErr;
  2411.  
  2412.             if (type)
  2413.                 theDoc->type = type;
  2414.                 
  2415.             if (myErr==noErr)
  2416.                 if (tempErr==noErr) { /* we were told where */
  2417.                     myErr = SaveWithoutTemp(theDoc, destFSSpec);
  2418.  
  2419.                     if (myErr==noErr)
  2420.                         AssocAllSections(theDoc);
  2421.                 } else
  2422.                     myErr = SaveUsingTemp(theDoc);
  2423.         } else
  2424.             myErr =  errAEIllegalIndex;
  2425.     }
  2426.  
  2427.     if (myDirObj.dataHandle)
  2428.         tempErr = AEDisposeDesc(&myDirObj);
  2429.  
  2430.     return myErr;
  2431. }    /* DoSaveWindow */
  2432.  
  2433. /** -----------------------------------------------------------------------
  2434.         Name:         DoRevertWindow
  2435.         Purpose:        Handles the Revert AppleEvent.
  2436.      -----------------------------------------------------------------------**/
  2437.  
  2438. pascal OSErr DoRevertWindow(
  2439.     const AppleEvent *theAppleEvent,
  2440.     AppleEvent       *reply,
  2441.     long             handlerRefCon)
  2442. {
  2443. #if !defined(powerc) && !defined(__powerc)
  2444. #pragma unused (reply, handlerRefCon)
  2445. #endif
  2446.  
  2447.     OSErr          myErr;
  2448.     OSErr          ignoreErr;
  2449.     AEDesc         myDirObj;
  2450.     AEDesc         newDesc;
  2451.     WindowToken    theWindowToken;
  2452.     Size           tokenSize;
  2453.     DPtr           theDoc;
  2454.  
  2455.     myDirObj.dataHandle = nil;
  2456.  
  2457.   /* pick up the direct object, which is the window to revert */
  2458.  
  2459.       if (myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj))
  2460.           return myErr;
  2461.  
  2462.       GotRequiredParams(theAppleEvent);
  2463.  
  2464.   /* get the window to revert from the direct object */
  2465.  
  2466.     myErr = AECoerceDesc(&myDirObj, typeMyWndw, &newDesc);
  2467.  
  2468.       if (myErr == noErr)
  2469.         if (newDesc.descriptorType!=typeNull) {
  2470.             GetRawDataFromDescriptor(
  2471.                 &newDesc,
  2472.                 (Ptr)&theWindowToken,
  2473.                 sizeof(theWindowToken),
  2474.                 &tokenSize);
  2475.  
  2476.             myErr = AEDisposeDesc(&newDesc);
  2477.  
  2478.             if (theWindowToken) {
  2479.                 theDoc = DPtrFromWindowPtr(theWindowToken);
  2480.  
  2481.                 if (theDoc->kind != kDocumentWindow)
  2482.                     myErr = errAEEventNotHandled;
  2483.                 else {
  2484.                     HidePen();
  2485.                     TESetSelect(0, (*(theDoc->theText))->teLength, theDoc->theText);
  2486.                     ShowPen();
  2487.                     TEDelete(theDoc->theText);
  2488.     
  2489.                     if (theDoc->u.reg.everSaved) {
  2490.                         myErr = GetFileContents(theDoc->theFSSpec, theDoc);
  2491.                         if (myErr == noErr) {
  2492.                             ResizeWindow(theDoc);
  2493.                             theDoc->dirty = false;
  2494.                         }
  2495.                     }
  2496.     
  2497.                     DoShowWindow(theDoc->theWindow); /* <<< Visible already??? */
  2498.                     DoUpdate(theDoc, theDoc->theWindow);
  2499.                 }
  2500.             } else
  2501.                 myErr =  errAEIllegalIndex;
  2502.         }
  2503.  
  2504.     if (myDirObj.dataHandle)
  2505.         ignoreErr = AEDisposeDesc(&myDirObj);
  2506.  
  2507.   return myErr;
  2508. }    /* DoRevertWindow */
  2509.  
  2510. /**-----------------------------------------------------------------------
  2511.         Name:         DoPrintDocuments
  2512.         Purpose:        Print a list of documents (or windows).
  2513. -----------------------------------------------------------------------**/
  2514. pascal OSErr DoPrintDocuments(
  2515.     const AppleEvent *message,
  2516.    AppleEvent       *reply,
  2517.     long refcon)
  2518. {
  2519. #if !defined(powerc) && !defined(__powerc)
  2520. #pragma unused (reply, refcon)
  2521. #endif
  2522.     long          index;
  2523.     long          itemsInList;
  2524.     AEKeyword     keywd;
  2525.     OSErr         err;
  2526.     AEDescList    docList;
  2527.     Size          actSize;
  2528.     DescType      typeCode;
  2529.     FSSpec        theFSSpec;
  2530.     WindowToken   theWindowToken;
  2531.     OSErr         forgetErr;
  2532.     Boolean       talkToUser;
  2533.  
  2534.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  2535.     err = AECountItems(&docList, &itemsInList);
  2536.  
  2537.     for (index = 1; index<=itemsInList; index++)
  2538.         if (err == noErr) {
  2539.             forgetErr =
  2540.                 AEGetNthPtr(
  2541.                     &docList,
  2542.                     index,
  2543.                     typeFSS,
  2544.                     &keywd,
  2545.                     &typeCode,
  2546.                     (Ptr)&theFSSpec,
  2547.                     sizeof(theFSSpec),
  2548.                     &actSize);
  2549.  
  2550.             if (forgetErr == noErr) {
  2551.                 if (err == noErr)
  2552.                     err = IssueAEOpenDoc(theFSSpec);
  2553.  
  2554.                 if (err == noErr)
  2555.                     IssuePrintWindow(FrontWindow());
  2556.  
  2557.                 if (err == noErr)
  2558.                     IssueCloseCommand(FrontWindow());
  2559.             } else { /* wasn't a file - was it a window ? */
  2560.                 err =
  2561.                     AEGetNthPtr(
  2562.                         &docList,
  2563.                         index,
  2564.                         typeMyWndw,
  2565.                         &keywd,
  2566.                         &typeCode,
  2567.                         (Ptr)&theWindowToken,
  2568.                         sizeof(WindowToken),
  2569.                         &actSize);
  2570.  
  2571.                 talkToUser = (AEInteractWithUser(kAEDefaultTimeout, nil, nil) == noErr);
  2572.  
  2573.                 if (err == noErr)
  2574.                     PrintWindow(DPtrFromWindowPtr(theWindowToken), talkToUser);
  2575.             }
  2576.         }
  2577.  
  2578.     if (docList.dataHandle)
  2579.         forgetErr = AEDisposeDesc(&docList);
  2580.  
  2581.     return err;
  2582. } /* DoPrintDocuments */
  2583.  
  2584. /**-----------------------------------------------------------------------
  2585.         Name:         HandleCreatePub
  2586.         Purpose:        Create a publisher.
  2587. -----------------------------------------------------------------------**/
  2588. pascal OSErr HandleCreatePub(
  2589.     const AppleEvent *theAppleEvent,
  2590.    AppleEvent       *reply,
  2591.     long refcon)
  2592. {
  2593. #if !defined(powerc) && !defined(__powerc)
  2594. #pragma unused (reply, refcon)
  2595. #endif
  2596.  
  2597.     OSErr       myErr;
  2598.     FSSpec      theFSSpec;
  2599.     OSErr       forgetErr;
  2600.     OSErr       forget2Err;
  2601.     AEDesc      myDirObj;
  2602.     AEDesc      myFileLoc;
  2603.     TextToken   theTextToken;
  2604.     DPtr        theDoc;
  2605.     AEDesc      newDesc;
  2606.     long        tokenSize;
  2607.     Boolean     haveFSSpec;
  2608.  
  2609.     myErr = noErr;
  2610.  
  2611.     forgetErr  = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2612.     forget2Err = AEGetParamDesc(theAppleEvent, keyAEEditionFileLoc, typeWildCard, &myFileLoc);
  2613.  
  2614.     if (myErr==noErr)
  2615.         myErr = GotRequiredParams(theAppleEvent);
  2616.  
  2617.     if (forgetErr==noErr) { /* Set the selection to the supplied object - if any */
  2618.         forgetErr = AECoerceDesc(&myDirObj, typeMyText, &newDesc);
  2619.         if (newDesc.descriptorType!=typeNull) {
  2620.             GetRawDataFromDescriptor(&newDesc,
  2621.                                                              (Ptr)&theTextToken,
  2622.                                                              sizeof(theTextToken),
  2623.                                                              &tokenSize);
  2624.  
  2625.             theDoc = DPtrFromWindowPtr(theTextToken.tokenWindow);
  2626.  
  2627.             TESetSelect(theTextToken.tokenOffset-1,
  2628.                                     theTextToken.tokenOffset+
  2629.                                                         theTextToken.tokenLength-1,
  2630.                                     theDoc->theText);
  2631.  
  2632.             forgetErr = AEDisposeDesc(&newDesc);
  2633.         }
  2634.     } else
  2635.         theDoc = DPtrFromWindowPtr(FrontWindow());
  2636.  
  2637.     if (theDoc==nil) {
  2638.         /* Should clean up and exit with error */
  2639.     }
  2640.  
  2641.     haveFSSpec = false;
  2642.  
  2643.     if (forget2Err==noErr) { /* Get the Edition Container File */
  2644.         forget2Err = AECoerceDesc(&myDirObj,typeFSS,&newDesc);
  2645.         if (newDesc.descriptorType!=typeNull) {
  2646.             GetRawDataFromDescriptor(&newDesc, (Ptr)&theFSSpec, sizeof(theFSSpec), &tokenSize);
  2647.             forget2Err = AEDisposeDesc(&newDesc);
  2648.             haveFSSpec = true;
  2649.         }
  2650.     }
  2651.  
  2652.     if (haveFSSpec==false)
  2653.         myErr = GetEditionContainer(theDoc, &theFSSpec);
  2654.  
  2655.     if (myErr == noErr)
  2656.         myErr = PublishText(theDoc, &theFSSpec);
  2657.  
  2658.     if (myDirObj.dataHandle)
  2659.         forgetErr = AEDisposeDesc(&myDirObj);
  2660.  
  2661.     if (myFileLoc.dataHandle)
  2662.         forgetErr = AEDisposeDesc(&myFileLoc);
  2663.  
  2664.     return myErr;
  2665. } /* HandleCreatePub */
  2666.  
  2667.  
  2668. pascal OSErr MyCountProc(
  2669.     DescType desiredType,
  2670.     DescType containerClass,
  2671.     const AEDesc *container,
  2672.     long *result);
  2673.  
  2674. /** -----------------------------------------------------------------------
  2675.         Name:       HandleNumberOfElements
  2676.         Purpose:        Handles the Number Of Elements AppleEvent.
  2677.      -----------------------------------------------------------------------**/
  2678.  
  2679. pascal OSErr HandleNumberOfElements(
  2680.     const AppleEvent *theAppleEvent,
  2681.     AppleEvent *reply,
  2682.     long       handlerRefCon)
  2683. {
  2684. #if !defined(powerc) && !defined(__powerc)
  2685. #pragma unused (handlerRefCon)
  2686. #endif
  2687.  
  2688.       OSErr    myErr;
  2689.       OSErr    forgetErr;
  2690.     AEDesc   myDirObj;
  2691.     DescType myClass;
  2692.     long     myCount;
  2693.     DescType returnedType;
  2694.     Size     actSize;
  2695.  
  2696.     myErr                        = errAEEventNotHandled;
  2697.     myDirObj.dataHandle     = nil;
  2698.  
  2699.     /* pick up direct object, which is the container in which things are to be counted */
  2700.  
  2701.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2702.  
  2703.     /* now the class of objects to be counted */
  2704.  
  2705.     myErr =
  2706.         AEGetParamPtr(
  2707.             theAppleEvent,
  2708.             keyAEObjectClass,
  2709.             typeType,
  2710.             &returnedType,
  2711.             (Ptr)&myClass,
  2712.             sizeof(myClass),
  2713.             &actSize);
  2714.  
  2715.     /* missing any parameters? */
  2716.  
  2717.     myErr = GotRequiredParams(theAppleEvent);
  2718.  
  2719.     /* now count */
  2720.  
  2721.     if (myErr == noErr)
  2722.         myErr = MyCountProc(myClass,myDirObj.descriptorType, &myDirObj,&myCount);
  2723.  
  2724.     /* add result to reply */
  2725.  
  2726.     if (myErr == noErr)
  2727.         if (reply->descriptorType != typeNull)
  2728.              myErr  =
  2729.                  AEPutParamPtr(
  2730.                     reply,
  2731.                     keyDirectObject,
  2732.                     typeLongInteger,
  2733.                     (Ptr)&myCount,
  2734.                     sizeof(myCount));
  2735.     if (myErr == noErr)
  2736.         forgetErr  = AEDisposeDesc(&myDirObj);
  2737.  
  2738.     return myErr;
  2739. }    /* HandleNumberOfElements */
  2740.  
  2741. /** -----------------------------------------------------------------------
  2742.         Name:             HandleShowSelection
  2743.         Purpose:        Handles the Make Selection Visible AppleEvent.
  2744.      -----------------------------------------------------------------------**/
  2745.  
  2746. pascal OSErr HandleShowSelection(
  2747.     const AppleEvent *theAppleEvent,
  2748.     AppleEvent       *reply,
  2749.     long             handlerRefCon)
  2750. {
  2751. #if !defined(powerc) && !defined(__powerc)
  2752. #pragma unused (reply,handlerRefCon)
  2753. #endif
  2754.  
  2755.     OSErr       myErr;
  2756.     OSErr       ignoreErr;
  2757.     AEDesc      myDirObj;
  2758.     AEDesc      newDesc;
  2759.     AEDesc      tokenDesc;
  2760.     Size        actSize;
  2761.     WindowToken theWindowToken;
  2762.     DPtr        theDocument;
  2763.     TEHandle    theHTE;
  2764.  
  2765.     myErr      = errAEEventNotHandled;
  2766.     myDirObj.dataHandle  = nil;
  2767.     tokenDesc.dataHandle = nil;
  2768.  
  2769.     /*
  2770.         pick up direct object, i.e. the window in which to show the selection
  2771.     */
  2772.  
  2773.     myErr  =
  2774.         AEGetParamDesc(
  2775.             theAppleEvent,
  2776.             keyDirectObject,
  2777.             typeWildCard,
  2778.             &myDirObj);
  2779.  
  2780.     /*
  2781.         missing any parameters?
  2782.     */
  2783.  
  2784.     myErr = GotRequiredParams(theAppleEvent);
  2785.  
  2786.     /*
  2787.         convert object to WindowToken which we understand
  2788.     */
  2789.     myErr = AEResolve(&myDirObj, kAEIDoMinimum, &tokenDesc);
  2790.  
  2791.     if (myErr == noErr)
  2792.         if (tokenDesc.descriptorType==typeMyWndw) {
  2793.             if (AECoerceDesc(&myDirObj, typeMyWndw, &newDesc) == noErr) {
  2794.                 GetRawDataFromDescriptor(
  2795.                     &newDesc,
  2796.                     (Ptr)&theWindowToken,
  2797.                     sizeof(theWindowToken),
  2798.                     &actSize);
  2799.  
  2800.                 ignoreErr = AEDisposeDesc(&newDesc);
  2801.  
  2802.                 if (myErr==noErr)
  2803.                     if (theWindowToken)
  2804.                         ShowSelect(DPtrFromWindowPtr(theWindowToken));
  2805.                     else
  2806.                         myErr = errAEIllegalIndex;
  2807.             }
  2808.         } else if (tokenDesc.descriptorType==typeMyText) {
  2809.             myErr =
  2810.                 SetSelectionOfAppleEventObject(
  2811.                     keyDirectObject,
  2812.                     theAppleEvent,
  2813.                     &theDocument,
  2814.                     &theHTE);
  2815.  
  2816.             if (theDocument)
  2817.               ShowSelect(theDocument);
  2818.             else
  2819.                 myErr = errAEIllegalIndex;
  2820.         } else
  2821.             myErr = errAEEventNotHandled;
  2822.  
  2823.     if (myDirObj.dataHandle)
  2824.         ignoreErr = AEDisposeDesc(&myDirObj);
  2825.  
  2826.     if (tokenDesc.dataHandle)
  2827.         ignoreErr = AEDisposeDesc(&tokenDesc);
  2828.  
  2829.     return myErr;
  2830. }    /* HandleShowSelection */
  2831.  
  2832. /** -----------------------------------------------------------------------
  2833.         Name:         HandleSelect
  2834.         Purpose:        Handles the Select AppleEvent.
  2835.      -----------------------------------------------------------------------**/
  2836.  
  2837. pascal OSErr HandleSelect(
  2838.     const AppleEvent *theAppleEvent,
  2839.     AppleEvent       *reply,
  2840.     long             handlerRefCon)
  2841. {
  2842. #if !defined(powerc) && !defined(__powerc)
  2843. #pragma unused (reply,handlerRefCon)
  2844. #endif
  2845.  
  2846.     OSErr       myErr;
  2847.     OSErr       ignoreErr;
  2848.     AEDesc      myDirObj;
  2849.     AEDesc      tokenDesc;
  2850.     DPtr        theDocument;
  2851.     Size        actSize;
  2852.     TEHandle    theHTE;
  2853.     WindowToken theWindowToken;
  2854.  
  2855.     myErr      = errAEEventNotHandled;
  2856.     myDirObj.dataHandle  = nil;
  2857.     tokenDesc.dataHandle = nil;
  2858.  
  2859.     /*
  2860.         pick up direct object, i.e. the window in which to show the selection
  2861.     */
  2862.  
  2863.     myErr  =
  2864.         AEGetParamDesc(
  2865.             theAppleEvent,
  2866.             keyDirectObject,
  2867.             typeWildCard,
  2868.             &myDirObj);
  2869.  
  2870.     /*
  2871.         missing any parameters?
  2872.     */
  2873.  
  2874.     myErr = GotRequiredParams(theAppleEvent);
  2875.  
  2876.     /*
  2877.         convert object to WindowToken which we understand
  2878.     */
  2879.     myErr = AEResolve(&myDirObj, kAEIDoMinimum, &tokenDesc);
  2880.  
  2881.     if (!myErr)
  2882.         switch (tokenDesc.descriptorType) {
  2883.         case typeMyWndw:
  2884.             GetRawDataFromDescriptor(
  2885.                 &tokenDesc,
  2886.                 (Ptr)&theWindowToken,
  2887.                 sizeof(theWindowToken),
  2888.                 &actSize);
  2889.  
  2890.             if (theWindowToken)
  2891.                 SelectWindow(theWindowToken);
  2892.             else
  2893.                 myErr = errAEIllegalIndex;
  2894.             
  2895.             break;
  2896.         case typeMyText:
  2897.             myErr =
  2898.                 SetSelectionOfAppleEventObject(
  2899.                     keyDirectObject,
  2900.                     theAppleEvent,
  2901.                     &theDocument,
  2902.                     &theHTE);
  2903.             break;
  2904.         default:
  2905.             myErr = errAEEventNotHandled;
  2906.             break;
  2907.         }
  2908.  
  2909.     if (myDirObj.dataHandle)
  2910.         ignoreErr = AEDisposeDesc(&myDirObj);
  2911.  
  2912.     if (tokenDesc.dataHandle)
  2913.         ignoreErr = AEDisposeDesc(&tokenDesc);
  2914.  
  2915.     return myErr;
  2916. }    /* HandleSelect */
  2917.  
  2918. pascal OSErr HandleStartRecording(
  2919.     const AppleEvent *theAppleEvent,
  2920.     AppleEvent *reply,
  2921.     long       handlerRefCon)
  2922. {
  2923. #if !defined(powerc) && !defined(__powerc)
  2924. #pragma unused (reply,handlerRefCon)
  2925. #endif
  2926.  
  2927.     OSErr myErr;
  2928.  
  2929.     gBigBrother++;
  2930.  
  2931.     myErr = GotRequiredParams(theAppleEvent);
  2932.  
  2933.     return myErr;
  2934.  
  2935. }    /* HandleStartRecording */
  2936.  
  2937. pascal OSErr HandleStopRecording(
  2938.     const AppleEvent *theAppleEvent,
  2939.     AppleEvent *reply,
  2940.     long handlerRefCon)
  2941. {
  2942. #if !defined(powerc) && !defined(__powerc)
  2943. #pragma unused (theAppleEvent,reply,handlerRefCon)
  2944. #endif
  2945.  
  2946.     gBigBrother--;
  2947.     return noErr;
  2948. }    /* HandleStopRecording */
  2949.  
  2950.  
  2951. #if !defined(powerc) && !defined(__powerc)
  2952. #pragma segment AECommandIssuers
  2953. #endif
  2954.  
  2955. /*******************************************************************************/
  2956. /*
  2957.         Start of section involved in building and sending AppleEvent Objects as/with
  2958.         commands
  2959.  */
  2960.  
  2961. /*
  2962.     Make an AEDesc that describes the selection in the window and text edit
  2963.     record supplied
  2964. */
  2965.  
  2966. pascal OSErr MakeWindowObj(
  2967.     WindowPtr theWindow,
  2968.     AEDesc    *dMyDoc)
  2969. {
  2970.       WindowPtr searchWindow;
  2971.     short         index;
  2972.     
  2973.     searchWindow = (WindowPtr)LMGetWindowList();
  2974.  
  2975.     /* iterate through windows */
  2976.  
  2977.     for (index = 1; searchWindow; ++index)
  2978.         if (searchWindow == theWindow)
  2979.             break;
  2980.         else
  2981.             searchWindow = (WindowPtr)((WindowPeek)searchWindow)->nextWindow;
  2982.  
  2983.     if (searchWindow == theWindow) 
  2984.         return AEBuild(
  2985.                     dMyDoc, 
  2986.                     "obj{want: type('docu'), form: 'indx', seld: long(@), from: ()}",
  2987. /*                    "obj{want:type('docu'),form:'indx',seld:long(@),from:()}", */ 
  2988.                     (long) index);
  2989.     else {
  2990.         char   windowName[256];
  2991.         
  2992.         getwtitle(theWindow, windowName);
  2993.         
  2994.         return AEBuild(
  2995.                     dMyDoc, 
  2996. /*                    "obj{want: type('docu'), form: 'name', seld: TEXT(@), from: ()}", */
  2997.                     "obj{want:type('docu'),form:'name',seld:TEXT(@),from:()}",
  2998.                     windowName);
  2999.     }
  3000. } /*MakeWindowObj*/
  3001.  
  3002. pascal OSErr MakeTextObj(
  3003.     WindowPtr theWindow,
  3004.     short     selStart,
  3005.     short     selEnd,
  3006.     AEDesc    *selTextObj)
  3007. {
  3008.     OSErr    myErr;
  3009.     OSErr    ignoreErr;
  3010.     AEDesc   dMyDoc;
  3011.     AEDesc   startOfs;
  3012.     AEDesc   endOfs;
  3013.     AEDesc   startObj;
  3014.     AEDesc   endObj;
  3015.     AEDesc   rangeDesc;
  3016.     long     startChar;
  3017.     long     endChar;
  3018.     Boolean  spotFlag;
  3019.  
  3020.     myErr = noErr;
  3021.  
  3022.     if (theWindow==nil)
  3023.         return noErr;
  3024.  
  3025.     selTextObj->dataHandle = nil;
  3026.     dMyDoc.dataHandle      = nil;
  3027.     startObj.dataHandle    = nil;
  3028.     endObj.dataHandle      = nil;
  3029.  
  3030.     /*
  3031.         make the window object
  3032.     */
  3033.  
  3034.     if (myErr = MakeWindowObj(theWindow, &dMyDoc))
  3035.         return myErr;
  3036.  
  3037.     /* get the start and end of selection */
  3038.  
  3039.     startChar = selStart+1;    /* start counting obj's from 1, not 0 */
  3040.     endChar   = selEnd;
  3041.     spotFlag  = (selStart == selEnd);
  3042.  
  3043.     if (myErr = CreateOffsetDescriptor(startChar, &startOfs))
  3044.         return noErr;
  3045.  
  3046.     if (spotFlag)
  3047.         myErr =
  3048.             CreateObjSpecifier(
  3049.                 cSpot,
  3050.                 &dMyDoc,
  3051.                 formAbsolutePosition,
  3052.                 &startOfs,
  3053.                 true,
  3054.                 selTextObj);
  3055.     else {
  3056.         /* not a spot - must represent as range */
  3057.         /* make obj for start char */
  3058.  
  3059.         myErr =
  3060.             CreateObjSpecifier(
  3061.                 cChar,
  3062.                 &dMyDoc,
  3063.                 formAbsolutePosition,
  3064.                 &startOfs,
  3065.                 false,
  3066.                 &startObj);
  3067.  
  3068.         if (myErr==noErr)
  3069.             myErr = CreateOffsetDescriptor(endChar, &endOfs);
  3070.  
  3071.         if (myErr==noErr)
  3072.             myErr =
  3073.                 CreateObjSpecifier(
  3074.                     cChar,
  3075.                     &dMyDoc,
  3076.                     formAbsolutePosition,
  3077.                     &endOfs,
  3078.                     false,
  3079.                     &endObj);
  3080.  
  3081.         if (myErr==noErr)
  3082.             myErr = CreateRangeDescriptor(&startObj, &endObj, false, &rangeDesc);
  3083.  
  3084.         if (myErr==noErr)
  3085.             myErr = CreateObjSpecifier(cChar, &dMyDoc, formRange, &rangeDesc, true, selTextObj);
  3086.  
  3087.         if (startObj.dataHandle)
  3088.           ignoreErr = AEDisposeDesc(&startObj);
  3089.  
  3090.         if (startOfs.dataHandle)
  3091.           ignoreErr = AEDisposeDesc(&startOfs);
  3092.  
  3093.         if (endObj.dataHandle)
  3094.           ignoreErr = AEDisposeDesc(&endObj);
  3095.  
  3096.         if (endOfs.dataHandle)
  3097.           ignoreErr = AEDisposeDesc(&endOfs);
  3098.     }
  3099.  
  3100.     return myErr;
  3101. }
  3102.  
  3103. pascal OSErr MakeSelectedTextObj(
  3104.     WindowPtr theWindow,
  3105.     TEHandle  theTextEditHandle,
  3106.     AEDesc    *selTextObj)
  3107. {
  3108.     return
  3109.         MakeTextObj(
  3110.             theWindow,
  3111.             (**theTextEditHandle).selStart,
  3112.             (**theTextEditHandle).selEnd,
  3113.             selTextObj);
  3114.  
  3115. }    /* MakeSelectedTextObj */
  3116.  
  3117. enum editCommandType {
  3118. editCutCommand   = 1,
  3119. editCopyCommand  = 2,
  3120. editPasteCommand = 3,
  3121. editClearCommand = 4
  3122. };
  3123.  
  3124. typedef enum editCommandType editCommandType;
  3125.  
  3126. pascal void DoEditCommand(DPtr theDocument,editCommandType whatCommand)
  3127. {
  3128.       OSErr         err;
  3129.       OSErr         forgetErr;
  3130.     AEAddressDesc ourAddress;
  3131.     AppleEvent    editCommandEvent;
  3132.     AppleEvent    ignoreReply;
  3133.     AEDesc        ourTextSelObj;
  3134.     AEEventID     theEventID;
  3135.     AEEventClass  theEventClass;
  3136.  
  3137.     /*
  3138.             Initialise
  3139.     */
  3140.  
  3141.     ourAddress.dataHandle             = nil;
  3142.     ourTextSelObj.dataHandle         = nil;
  3143.     editCommandEvent.dataHandle     = nil;
  3144.     ignoreReply.dataHandle             = nil;
  3145.  
  3146.     err = MakeSelfAddress(&ourAddress);
  3147.  
  3148.     /*
  3149.         Build an object to represent the current document's selection
  3150.     */
  3151.     err = MakeSelectedTextObj(theDocument->theWindow, theDocument->theText, &ourTextSelObj);
  3152.  
  3153.     if (err==noErr) {
  3154.         switch (whatCommand) {
  3155.         case  editCutCommand:
  3156.             theEventID    = kAECut;
  3157.             theEventClass = kAEMiscStandards;
  3158.             break;
  3159.         case  editCopyCommand:
  3160.             theEventID    = kAECopy;
  3161.             theEventClass = kAEMiscStandards;
  3162.             break;
  3163.         case  editPasteCommand:
  3164.             theEventID    = kAEPaste;
  3165.             theEventClass = kAEMiscStandards;
  3166.             break;
  3167.         case  editClearCommand:
  3168.             theEventID    = kAEDelete;
  3169.             theEventClass = kAECoreSuite;
  3170.             break;
  3171.         }
  3172.  
  3173.         err = AECreateAppleEvent( theEventClass, theEventID, &ourAddress, 0, 0, &editCommandEvent);
  3174.  
  3175.         /* add parameter */
  3176.         if (err==noErr)
  3177.             err = AEPutParamDesc(&editCommandEvent, keyDirectObject, &ourTextSelObj);
  3178.  
  3179.         /*and now Send the message*/
  3180.         if (err==noErr)
  3181.             err = AESend(&editCommandEvent,&ignoreReply,kAENoReply,kAEHighPriority,10000,nil, nil);
  3182.     }
  3183.  
  3184.     /*
  3185.         Clean up
  3186.     */
  3187.     if (ourAddress.dataHandle)
  3188.         forgetErr = AEDisposeDesc(&ourAddress);
  3189.  
  3190.     if (editCommandEvent.dataHandle)
  3191.         forgetErr = AEDisposeDesc(&editCommandEvent);
  3192.  
  3193.     if (ignoreReply.dataHandle)
  3194.         forgetErr = AEDisposeDesc(&ignoreReply);
  3195.  
  3196.     if (ourTextSelObj.dataHandle)
  3197.         forgetErr = AEDisposeDesc(&ourTextSelObj);
  3198.  
  3199. } /*DoEditCommand*/
  3200.  
  3201. pascal void IssueCutCommand(DPtr theDocument)
  3202. {
  3203.     DoEditCommand(theDocument, editCutCommand);
  3204. }
  3205.  
  3206. pascal void IssueCopyCommand(DPtr theDocument)
  3207. {
  3208.     DoEditCommand(theDocument, editCopyCommand);
  3209. }
  3210.  
  3211. pascal void IssuePasteCommand(DPtr theDocument)
  3212. {
  3213.     DoEditCommand(theDocument, editPasteCommand);
  3214. }
  3215.  
  3216. pascal void IssueClearCommand(DPtr theDocument)
  3217. {
  3218.     DoEditCommand(theDocument, editClearCommand);
  3219. }
  3220.  
  3221. pascal OSErr IssueJumpCommand(FSSpec * file, WindowPtr win, short line)
  3222. {
  3223.     OSErr                        err;
  3224.     AEDesc                    window;
  3225.     AEDesc                    target;
  3226.     AppleEvent                ignoreReply;
  3227.     ProcessSerialNumber     psn;
  3228.     DescType                    type;
  3229.     Size                        size;
  3230.     
  3231.     MakeSelfPSN(&psn);
  3232.  
  3233.     if (win) {
  3234.         if (err = MakeWindowObj(win, &window))
  3235.             return err;
  3236.             
  3237.         err = AEBuildAppleEvent(kAEMiscStandards, kAESelect,
  3238.                     typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber),
  3239.                     0, 0, &target,
  3240.                     "'----':@",
  3241.                     &window);
  3242.         
  3243.         AEDisposeDesc(&window);
  3244.         
  3245.         if (err)
  3246.             return err;
  3247.             
  3248.         err = AESend(&target,&ignoreReply,kAENoReply,kAEHighPriority,10000,nil,nil);
  3249.     
  3250.         AEDisposeDesc(&target);
  3251.  
  3252.         if (ignoreReply.dataHandle)
  3253.             AEDisposeDesc(&ignoreReply);    
  3254.  
  3255.         if (err)
  3256.             return err;
  3257.     } else if (file) {
  3258.         if (err = IssueAEOpenDoc(*file))
  3259.             return err;
  3260.     }
  3261.  
  3262.     if (!line)
  3263.         return noErr;
  3264.         
  3265.     if (err = AEBuildAppleEvent(kAEMiscStandards, kAEMakeObjectsVisible,
  3266.         typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber),
  3267.         0, 0, &target,
  3268.         "'----':obj{ "
  3269.                      "want:type(clin),"
  3270.                      "form:indx,"
  3271.                      "seld:long(@),"
  3272.                      "from:obj{"
  3273.                                   "want:type(cwin),"
  3274.                                   "form:indx,"
  3275.                                   "seld:long(1),"
  3276.                                   "from:()"
  3277.                                  "}"
  3278.                     "}",
  3279.         line
  3280.         )
  3281.     )
  3282.         return err;
  3283.  
  3284.     err = AESend(&target,&ignoreReply,kAENoReply,kAEHighPriority,10000,nil,nil);
  3285.     
  3286.     AEDisposeDesc(&target);
  3287.  
  3288.     if (ignoreReply.dataHandle)
  3289.         AEDisposeDesc(&ignoreReply);    
  3290.  
  3291.     return err;
  3292. }
  3293.  
  3294. /*
  3295.     Window property routines
  3296. */
  3297.  
  3298. pascal void IssueZoomCommand(WindowPtr whichWindow, short whichPart)
  3299. {
  3300.       Boolean       zoomBool;
  3301.     AEDesc        zoomDesc;
  3302.     AEAddressDesc selfAddr;
  3303.     AEDesc        frontWinObj;
  3304.     OSErr         err;
  3305.  
  3306.     err = MakeSelfAddress(&selfAddr);
  3307.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3308.  
  3309.     zoomBool = (whichPart==inZoomOut);
  3310.  
  3311.     err = AECreateDesc(typeBoolean, (Ptr)&zoomBool, sizeof(zoomBool), &zoomDesc);
  3312.     err = SendAESetObjProp(&frontWinObj, pIsZoomed, &zoomDesc, &selfAddr);
  3313. } /* IssueZoomCommand */
  3314.  
  3315. pascal void IssueCloseCommand(WindowPtr whichWindow)
  3316. {
  3317.     AEAddressDesc  selfAddr;
  3318.     AEDesc         frontWinObj;
  3319.     OSErr          err;
  3320.     OSErr          ignoreErr;
  3321.     AppleEvent     closeCommandEvent;
  3322.     AppleEvent     ignoreReply;
  3323.  
  3324.     frontWinObj.dataHandle = nil;
  3325.  
  3326.     err = MakeSelfAddress(&selfAddr);
  3327.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3328.     err = AECreateAppleEvent( kAECoreSuite, kAEClose, &selfAddr, 0, 0, &closeCommandEvent) ;
  3329.  
  3330.     /* add parameter - the window to close */
  3331.     if (err==noErr)
  3332.         err = AEPutParamDesc(&closeCommandEvent, keyDirectObject, &frontWinObj);
  3333.  
  3334.     if (err==noErr)
  3335.         err = AESend(&closeCommandEvent,&ignoreReply,kAENoReply+kAEAlwaysInteract,kAEHighPriority,10000,nil, nil);
  3336.  
  3337.     if (closeCommandEvent.dataHandle)
  3338.         ignoreErr = AEDisposeDesc(&closeCommandEvent);
  3339.  
  3340.     if (selfAddr.dataHandle)
  3341.         ignoreErr = AEDisposeDesc(&selfAddr);
  3342.  
  3343.     if (frontWinObj.dataHandle)
  3344.         ignoreErr = AEDisposeDesc(&frontWinObj);
  3345. } /* IssueCloseCommand */
  3346.  
  3347. pascal void IssueSizeWindow(WindowPtr whichWindow, short newHSize, short newVSize)
  3348. {
  3349.       Rect          sizeRect;
  3350.     Rect          contentRect;
  3351.     short         edgeSize;
  3352.     AEDesc        sizeDesc;
  3353.     AEAddressDesc selfAddr;
  3354.     AEDesc        frontWinObj;
  3355.     OSErr         err;
  3356.  
  3357.     sizeRect    = (**(((WindowPeek)whichWindow)->strucRgn)).rgnBBox;
  3358.     contentRect = (**(((WindowPeek)whichWindow)->contRgn)).rgnBBox;
  3359.  
  3360.     edgeSize = sizeRect.right-sizeRect.left-(contentRect.right-contentRect.left);
  3361.     sizeRect.right = sizeRect.left+newHSize+edgeSize;
  3362.  
  3363.     edgeSize = sizeRect.bottom-sizeRect.top-(contentRect.bottom-contentRect.top);
  3364.     sizeRect.bottom = sizeRect.top+newVSize+edgeSize;
  3365.  
  3366.     err = MakeSelfAddress(&selfAddr);
  3367.  
  3368.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3369.  
  3370.     if (err==noErr)
  3371.         err =
  3372.             AECreateDesc(
  3373.                 typeQDRectangle,
  3374.                 (Ptr)&sizeRect,
  3375.                 sizeof(sizeRect),
  3376.                 &sizeDesc);
  3377.  
  3378.     if (err==noErr)
  3379.         err =
  3380.             SendAESetObjProp(
  3381.                 &frontWinObj,
  3382.                 pBounds,
  3383.                 &sizeDesc,
  3384.                 &selfAddr);
  3385. } /*IssueSizeWindow*/
  3386.  
  3387. pascal void IssueMoveWindow(WindowPtr whichWindow, Rect sizeRect)
  3388. {
  3389.     AEDesc        sizeDesc;
  3390.     AEAddressDesc selfAddr;
  3391.     AEDesc        frontWinObj;
  3392.     OSErr         err;
  3393.  
  3394.     err = MakeSelfAddress(&selfAddr);
  3395.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3396.  
  3397.     if (err==noErr)
  3398.         err = AECreateDesc(typeQDRectangle, (Ptr)&sizeRect, sizeof(sizeRect), &sizeDesc);
  3399.  
  3400.     if (err==noErr)
  3401.         err = SendAESetObjProp(&frontWinObj, pBounds, &sizeDesc, &selfAddr);
  3402. } /*IssueMoveWindow*/
  3403.  
  3404. pascal void IssuePageSetupWindow(WindowPtr whichWindow, TPrint thePageSetup)
  3405. {
  3406.     AEDesc        sizeDesc;
  3407.     AEAddressDesc selfAddr;
  3408.     AEDesc        frontWinObj;
  3409.     OSErr         err;
  3410.  
  3411.     err = MakeSelfAddress(&selfAddr);
  3412.  
  3413.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3414.  
  3415.     if (err==noErr)
  3416.         err = AECreateDesc(typeTPrint, (Ptr)&thePageSetup, sizeof(thePageSetup), &sizeDesc);
  3417.  
  3418.     if (err==noErr)
  3419.         err = SendAESetObjProp(&frontWinObj, pPageSetup, &sizeDesc, &selfAddr);
  3420. } /*IssuePageSetupWindow*/
  3421.  
  3422. pascal void IssueShowBorders(WindowPtr whichWindow, Boolean showBorders)
  3423. {
  3424.     AEDesc        sizeDesc;
  3425.     AEAddressDesc selfAddr;
  3426.     AEDesc        frontWinObj;
  3427.     OSErr         err;
  3428.  
  3429.     err = MakeSelfAddress(&selfAddr);
  3430.  
  3431.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3432.  
  3433.     if (err==noErr)
  3434.         err = AECreateDesc(typeBoolean, (Ptr)&showBorders, sizeof(showBorders), &sizeDesc);
  3435.  
  3436.     if (err==noErr)
  3437.         err = SendAESetObjProp(&frontWinObj, pShowBorders, &sizeDesc, &selfAddr);
  3438. } /*IssueShowBorders*/
  3439.  
  3440. pascal void IssuePrintWindow(WindowPtr whichWindow)
  3441. {
  3442.     AEAddressDesc selfAddr;
  3443.     AEDesc        frontWinObj;
  3444.     OSErr         err;
  3445.     OSErr         ignoreErr;
  3446.     AppleEvent    printCommandEvent;
  3447.     AppleEvent    ignoreReply;
  3448.  
  3449.     err = MakeSelfAddress(&selfAddr);
  3450.  
  3451.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3452.  
  3453.     err = AECreateAppleEvent(kCoreEventClass, kAEPrintDocuments, &selfAddr, 0, 0, &printCommandEvent) ;
  3454.  
  3455.     /*
  3456.         add parameter - the window to print
  3457.     */
  3458.  
  3459.     if (err==noErr)
  3460.         err = AEPutParamDesc(&printCommandEvent, keyDirectObject, &frontWinObj);
  3461.  
  3462.     if (err==noErr)
  3463.         err = AESend(&printCommandEvent,&ignoreReply,kAENoReply+kAEAlwaysInteract,kAEHighPriority,10000,nil, nil);
  3464.  
  3465.       if (printCommandEvent.dataHandle)
  3466.         ignoreErr = AEDisposeDesc(&printCommandEvent);
  3467.  
  3468.     if (frontWinObj.dataHandle)
  3469.         err = AEDisposeDesc(&frontWinObj);
  3470.  
  3471.     if (selfAddr.dataHandle)
  3472.         err = AEDisposeDesc(&selfAddr);
  3473. } /*IssuePrintWindow*/
  3474.  
  3475. pascal OSErr IssueAEOpenDoc(FSSpec myFSSpec)
  3476. /* send OpenDocs AppleEvent to myself, with a one-element list
  3477.   containing the given file spec
  3478.  
  3479.   NOTES : the core AEOpenDocs event is defined as taking a list of
  3480.           aliases (not file specs) as its direct parameter.  However,
  3481.             we can send the file spec instead and depend on AppleEvents'
  3482.             automatic coercion.  In fact, we don't really even have to put
  3483.             in a list; AppleEvents will coerce a descriptor into a 1-element
  3484.             list if called for.  In this routine, though, we'll make the
  3485.             list for demonstration purposes.
  3486. */
  3487.  
  3488. {
  3489.     AppleEvent    myAppleEvent;
  3490.     AppleEvent    defReply;
  3491.     AEDescList    docList;
  3492.     AEAddressDesc selfAddr;
  3493.     OSErr         myErr;
  3494.     OSErr         ignoreErr;
  3495.  
  3496.     myAppleEvent.dataHandle = nil;
  3497.     docList.dataHandle  = nil;
  3498.     selfAddr.dataHandle = nil;
  3499.     defReply.dataHandle = nil;
  3500.  
  3501.     /*
  3502.         Create empty list and add one file spec
  3503.     */
  3504.     myErr = AECreateList(nil,0,false, &docList);
  3505.  
  3506.     if (myErr==noErr)
  3507.         myErr = AEPutPtr(&docList,1,typeFSS,(Ptr)&myFSSpec,sizeof(myFSSpec));
  3508.  
  3509.     /*
  3510.         Create a self address to send it to
  3511.     */
  3512.     if (myErr==noErr)
  3513.         myErr = MakeSelfAddress(&selfAddr);
  3514.  
  3515.     if (myErr==noErr)
  3516.         myErr =
  3517.             AECreateAppleEvent(
  3518.                 MPAppSig,
  3519.                 kAEOpenDocuments,
  3520.                 &selfAddr,
  3521.                 kAutoGenerateReturnID,
  3522.                 kAnyTransactionID,
  3523.                 &myAppleEvent);
  3524.  
  3525.     /*
  3526.         Put Params into our event and send it
  3527.     */
  3528.     if (myErr == noErr)
  3529.         myErr =
  3530.             AEPutParamDesc(
  3531.                 &myAppleEvent,
  3532.                 keyDirectObject,
  3533.                 &docList);
  3534.  
  3535.     myErr =
  3536.         AESend(
  3537.             &myAppleEvent,
  3538.             &defReply,
  3539.             kAENoReply+kAEAlwaysInteract,
  3540.             kAENormalPriority,
  3541.             kAEDefaultTimeout,
  3542.             nil,
  3543.             nil);
  3544.  
  3545.     if (selfAddr.dataHandle)
  3546.         ignoreErr = AEDisposeDesc(&selfAddr);
  3547.  
  3548.     if (myAppleEvent.dataHandle)
  3549.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3550.  
  3551.     if (docList.dataHandle)
  3552.         ignoreErr = AEDisposeDesc(&docList);
  3553.  
  3554.     return myErr;
  3555. }    /* IssueAEOpenDoc */
  3556.  
  3557. pascal void IssueAENewWindow(void)
  3558. /*
  3559.     send the New Element event to myself with a null container
  3560. */
  3561. {
  3562.     AppleEvent    myAppleEvent;
  3563.     AppleEvent    defReply;
  3564.     AEAddressDesc selfAddr;
  3565.     OSErr         myErr;
  3566.     OSErr         ignoreErr;
  3567.     DescType      elemClass;
  3568.  
  3569.     myAppleEvent.dataHandle = nil;
  3570.  
  3571.     /*
  3572.         Create the address of us
  3573.     */
  3574.  
  3575.     myErr = MakeSelfAddress(&selfAddr);
  3576.  
  3577.     /*
  3578.         create event
  3579.     */
  3580.  
  3581.     myErr =
  3582.         AECreateAppleEvent(
  3583.             kAECoreSuite,
  3584.             kAECreateElement,
  3585.             &selfAddr,
  3586.             kAutoGenerateReturnID,
  3587.             kAnyTransactionID,
  3588.             &myAppleEvent);
  3589.  
  3590.     /*
  3591.         attach desired class of new element
  3592.     */
  3593.  
  3594.     elemClass = cDocument;
  3595.  
  3596.     if (myErr == noErr)
  3597.         myErr =
  3598.             AEPutParamPtr(
  3599.                 &myAppleEvent,
  3600.                 keyAEObjectClass,
  3601.                 typeType,
  3602.                 (Ptr)&elemClass,
  3603.                 sizeof(elemClass));
  3604.  
  3605.     /*
  3606.         send the event
  3607.     */
  3608.  
  3609.     if (myErr == noErr)
  3610.         myErr =
  3611.             AESend(
  3612.                 &myAppleEvent,
  3613.                 &defReply,
  3614.                 kAENoReply+kAENeverInteract,
  3615.                 kAENormalPriority,
  3616.                 kAEDefaultTimeout,
  3617.                 nil,
  3618.                 nil);
  3619.     /*
  3620.         Clean up - reply never created so don't throw away
  3621.     */
  3622.     if (selfAddr.dataHandle)
  3623.         ignoreErr = AEDisposeDesc(&selfAddr);
  3624.  
  3625.     if (myAppleEvent.dataHandle)
  3626.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3627. }    /* IssueAENewWindow */
  3628.  
  3629. pascal OSErr IssueSaveCommand(
  3630.     DPtr             theDocument,
  3631.     FSSpecPtr     where)
  3632. /*
  3633.     send an AppleEvent Save Event to myself
  3634. */
  3635. {
  3636.     AEDesc        windowObj;
  3637.     AppleEvent    myAppleEvent;
  3638.     AppleEvent    defReply;
  3639.     OSErr         myErr;
  3640.     OSErr         ignoreErr;
  3641.     AEAddressDesc selfAddr;
  3642.  
  3643.     windowObj.dataHandle = nil;
  3644.     myAppleEvent.dataHandle = nil;
  3645.  
  3646.     myErr = MakeWindowObj(theDocument->theWindow, &windowObj);
  3647.  
  3648.     if (myErr==noErr)
  3649.         myErr = MakeSelfAddress(&selfAddr);
  3650.  
  3651.   /*
  3652.         Build event
  3653.     */
  3654.   if (myErr == noErr)
  3655.         myErr =
  3656.             AECreateAppleEvent(
  3657.                 kAECoreSuite,
  3658.                 kAESave,
  3659.                 &selfAddr,
  3660.                 kAutoGenerateReturnID,
  3661.                 kAnyTransactionID,
  3662.                 &myAppleEvent);
  3663.  
  3664.   /*
  3665.         say which window
  3666.     */
  3667.   if (myErr==noErr)
  3668.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObj);
  3669.  
  3670.   /*
  3671.         add optional file param if we need to
  3672.     */
  3673.   if (where)
  3674.         if (myErr==noErr)
  3675.             myErr =
  3676.                 AEPutParamPtr(
  3677.                     &myAppleEvent,
  3678.                     keyAEDestination,
  3679.                     typeFSS,
  3680.                     (Ptr)where,
  3681.                     sizeof(FSSpec));
  3682.  
  3683.     if (!myErr)
  3684.         myErr =
  3685.             AEPutParamPtr(
  3686.                 &myAppleEvent,
  3687.                 keyAEFileType,
  3688.                 typeEnumerated,
  3689.                 (Ptr)&theDocument->type,
  3690.                 sizeof(OSType));
  3691.         
  3692.   /*
  3693.         send the event
  3694.     */
  3695.   if (myErr==noErr)
  3696.         myErr  =
  3697.             AESend(
  3698.                 &myAppleEvent,
  3699.                 &defReply,
  3700.                 kAENoReply+kAENeverInteract,
  3701.                 kAENormalPriority,
  3702.                 kAEDefaultTimeout,
  3703.                 nil,
  3704.                 nil);
  3705.  
  3706.     if (selfAddr.dataHandle)
  3707.         ignoreErr = AEDisposeDesc(&selfAddr);
  3708.  
  3709.     if (windowObj.dataHandle)
  3710.         ignoreErr = AEDisposeDesc(&windowObj);
  3711.  
  3712.     if (myAppleEvent.dataHandle)
  3713.         myErr = AEDisposeDesc(&myAppleEvent);
  3714.  
  3715.     return myErr;
  3716. }    /* IssueSaveCommand */
  3717.  
  3718. pascal OSErr IssueRevertCommand(WindowPtr theWindow)
  3719. /*
  3720.     send an AppleEvent Revert Event to myself
  3721. */
  3722. {
  3723.     AEDesc        windowObj;
  3724.     AppleEvent    myAppleEvent;
  3725.     AppleEvent    defReply;
  3726.     OSErr         myErr;
  3727.     OSErr         ignoreErr;
  3728.     AEAddressDesc selfAddr;
  3729.  
  3730.     windowObj.dataHandle = nil;
  3731.     myAppleEvent.dataHandle = nil;
  3732.  
  3733.     myErr = MakeWindowObj(theWindow, &windowObj);
  3734.  
  3735.     if (myErr==noErr)
  3736.         myErr = MakeSelfAddress(&selfAddr);
  3737.  
  3738.     /*
  3739.         Build event
  3740.     */
  3741.  
  3742.     if (myErr == noErr)
  3743.         myErr  =
  3744.             AECreateAppleEvent(
  3745.                 kAEMiscStandards,
  3746.                 kAERevert,
  3747.                 &selfAddr,
  3748.                 kAutoGenerateReturnID,
  3749.                 kAnyTransactionID,
  3750.                 &myAppleEvent);
  3751.     /*
  3752.         say which window
  3753.     */
  3754.  
  3755.     if (myErr == noErr)
  3756.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObj);
  3757.     /*
  3758.         send the event
  3759.     */
  3760.     if (myErr==noErr)
  3761.         myErr =
  3762.             AESend(
  3763.                 &myAppleEvent,
  3764.                 &defReply,
  3765.                 kAENoReply+kAENeverInteract,
  3766.                 kAENormalPriority,
  3767.                 kAEDefaultTimeout,
  3768.                 nil,
  3769.                 nil);
  3770.  
  3771.     if (windowObj.dataHandle)
  3772.         ignoreErr = AEDisposeDesc(&windowObj);
  3773.  
  3774.     if (myAppleEvent.dataHandle)
  3775.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3776.  
  3777.     if (selfAddr.dataHandle)
  3778.         ignoreErr = AEDisposeDesc(&selfAddr);
  3779.  
  3780.     return myErr;
  3781. }    /* IssueRevertCommand */
  3782.  
  3783. /*
  3784.     Name : IssueQuitCommand
  3785.     Purpose : Sends self a Quit AppleEvent
  3786. */
  3787. pascal OSErr IssueQuitCommand(void)
  3788. {
  3789.     AppleEvent    myAppleEvent;
  3790.     AppleEvent    defReply;
  3791.     OSErr         myErr;
  3792.     OSErr         ignoreErr;
  3793.     AEAddressDesc selfAddr;
  3794.     DescType      mySaveOpt;
  3795.  
  3796.     myAppleEvent.dataHandle = nil;
  3797.     selfAddr.dataHandle     = nil;
  3798.  
  3799.     myErr = MakeSelfAddress(&selfAddr);
  3800.  
  3801.     /*
  3802.         Build event
  3803.     */
  3804.     if (myErr == noErr)
  3805.         myErr  =
  3806.             AECreateAppleEvent(
  3807.                 kCoreEventClass,
  3808.                 kAEQuitApplication,
  3809.                 &selfAddr,
  3810.                 kAutoGenerateReturnID,
  3811.                 kAnyTransactionID,
  3812.                 &myAppleEvent);
  3813.     /*
  3814.         say which save option
  3815.     */
  3816.     mySaveOpt = kAEAsk;
  3817.  
  3818.     if (myErr == noErr)
  3819.         myErr =
  3820.             AEPutParamPtr(
  3821.                 &myAppleEvent,
  3822.                 keyAESaveOptions,
  3823.                 typeEnumerated,
  3824.                 (Ptr)&mySaveOpt,
  3825.                 sizeof(mySaveOpt));
  3826.     /*
  3827.         send the event
  3828.     */
  3829.     if (myErr==noErr)
  3830.         myErr =
  3831.             AESend(
  3832.                 &myAppleEvent,
  3833.                 &defReply,
  3834.                 kAENoReply+kAEAlwaysInteract,
  3835.                 kAENormalPriority,
  3836.                 kAEDefaultTimeout,
  3837.                 nil,
  3838.                 nil);
  3839.  
  3840.     if (myAppleEvent.dataHandle)
  3841.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3842.  
  3843.     if (selfAddr.dataHandle)
  3844.         ignoreErr = AEDisposeDesc(&selfAddr);
  3845.  
  3846.     return myErr;
  3847. }    /* IssueQuitCommand */
  3848.  
  3849. /*
  3850.      Name :IssueCreatePublisher
  3851.      Purpose :Interact with user to get Publisher info
  3852.                         and the IssueAECommand to Publish currect selection
  3853. */
  3854. pascal void IssueCreatePublisher(DPtr whichDoc)
  3855. {
  3856.     AEAddressDesc selfAddr;
  3857.     AEDesc        selTextObj;
  3858.     OSErr         err;
  3859.     OSErr         ignoreErr;
  3860.     AppleEvent    publishCommandEvent;
  3861.     AppleEvent    ignoreReply;
  3862.  
  3863.       publishCommandEvent.dataHandle = nil;
  3864.     selfAddr.dataHandle = nil;
  3865.     selTextObj.dataHandle = nil;
  3866.  
  3867.     err = MakeSelfAddress(&selfAddr);
  3868.  
  3869.     if (err==noErr)
  3870.         err = MakeSelectedTextObj(whichDoc->theWindow, whichDoc->theText, &selTextObj);
  3871.  
  3872.     err =
  3873.         AECreateAppleEvent(
  3874.             kAEMiscStandards,
  3875.             kAECreatePublisher,
  3876.             &selfAddr,
  3877.             0,
  3878.             0,
  3879.             &publishCommandEvent) ;
  3880.  
  3881.     /*
  3882.         add parameter - the text to publish
  3883.     */
  3884.     if (err==noErr)
  3885.         err = AEPutParamDesc(&publishCommandEvent, keyDirectObject, &selTextObj);
  3886.  
  3887.     if (err==noErr)
  3888.         err =
  3889.             AESend(
  3890.                 &publishCommandEvent,
  3891.                 &ignoreReply,
  3892.                 kAENoReply+kAEAlwaysInteract,
  3893.                 kAEHighPriority,
  3894.                 10000,
  3895.                 nil,
  3896.                 nil);
  3897.  
  3898.       if (publishCommandEvent.dataHandle)
  3899.         ignoreErr = AEDisposeDesc(&publishCommandEvent);
  3900.  
  3901.     if (selTextObj.dataHandle)
  3902.         ignoreErr = AEDisposeDesc(&selTextObj);
  3903.  
  3904.     if (selfAddr.dataHandle)
  3905.         ignoreErr = AEDisposeDesc(&selfAddr);
  3906. } /*IssueCreatePublisher*/
  3907.  
  3908. #define kOK 1
  3909. #define kCancel 2
  3910. #define kOtherSize 4
  3911. #define kOutlineItem 5
  3912.  
  3913. pascal Boolean PoseSizeDialog(long *whatSize)
  3914. {
  3915.     GrafPtr   savedPort;
  3916.     DialogPtr aDialog;
  3917.     Str255    aString;
  3918.     short     itemHit;
  3919.  
  3920.     GetPort(&savedPort);
  3921.     aDialog = GetNewDialog(1004, nil, (WindowPtr)-1);
  3922.     DoShowWindow(aDialog);
  3923.     SetPort(aDialog);
  3924.  
  3925.     AdornDefaultButton(aDialog, kOutlineItem);
  3926.  
  3927.     /*set the edittext button to contain the right size*/
  3928.     NumToString(*whatSize, aString);
  3929.     SetText(aDialog, kOtherSize, aString);
  3930.  
  3931.     do {
  3932.         ModalDialog(nil, &itemHit);
  3933.     } while ((itemHit!=kOK) && (itemHit!=kCancel));
  3934.  
  3935.     if (itemHit == kOK)
  3936.         RetrieveText(aDialog, kOtherSize, aString);
  3937.  
  3938.     DisposDialog(aDialog);
  3939.     SetPort(savedPort);
  3940.  
  3941.     if (itemHit == kOK) {
  3942.         /*set the new size of the text*/
  3943.         StringToNum(aString, whatSize);
  3944.         if ((*whatSize<1) || (*whatSize>2000))
  3945.              *whatSize = 12;
  3946.     }
  3947.     return itemHit == kOK;
  3948. }
  3949.  
  3950. pascal void IssueFormatCommand(DPtr theDocument)
  3951. {
  3952.     Str255            name;
  3953.     AEDesc            desc;
  3954.     AEAddressDesc     theAddress;
  3955.     AEDesc            windowObj;
  3956.     OSErr             err;
  3957.     DocFormat        fmt;
  3958.     Boolean            defaultFormat;
  3959.     
  3960.     if (theDocument) {
  3961.         fmt.font         =     (*theDocument->theText)->txFont;
  3962.         fmt.size         =     (*theDocument->theText)->txSize;
  3963.         defaultFormat    =    false;
  3964.     } else {
  3965.         fmt                 =     gFormat;
  3966.         defaultFormat    =    true;
  3967.     }
  3968.     
  3969.     if (DoFormatDialog(&fmt, &defaultFormat)) {
  3970.         if (theDocument) {
  3971.             err = MakeSelfAddress(&theAddress);
  3972.             err = MakeWindowObj(theDocument->theWindow, &windowObj);
  3973.  
  3974.             if (err==noErr)
  3975.                   err = CreateOffsetDescriptor(fmt.size, &desc);
  3976.  
  3977.             if (err==noErr)
  3978.                 err = SendAESetObjProp(&windowObj, pPointSize, &desc, &theAddress);
  3979.                 
  3980.             err = MakeSelfAddress(&theAddress);
  3981.             err = MakeWindowObj(theDocument->theWindow, &windowObj);
  3982.         
  3983.             GetFontName(fmt.font, name);
  3984.         
  3985.             if (err==noErr)
  3986.                 err  = AECreateDesc(typeChar, (Ptr)&name[1], name[0], &desc);
  3987.         
  3988.             if (err==noErr)
  3989.                 err  = SendAESetObjProp(&windowObj, pFont, &desc, &theAddress);
  3990.         }
  3991.         
  3992.         if (defaultFormat) {
  3993.             gFormat = fmt;
  3994.  
  3995.             if (gPrefsFile) {
  3996.                 short        resFile;
  3997.                 short    **    defaultFont;
  3998.             
  3999.                 resFile = CurResFile();
  4000.                 UseResFile(gPrefsFile);
  4001.                 
  4002.                 defaultFont = (short **) Get1Resource('PFNT', 128);
  4003.                 **defaultFont = gFormat.size;
  4004.                 GetFontName(gFormat.font, name);
  4005.                 SetResInfo((Handle) defaultFont, 128, name);
  4006.                 ChangedResource((Handle) defaultFont);
  4007.                 WriteResource((Handle) defaultFont);
  4008.                 UpdateResFile(gPrefsFile);
  4009.             
  4010.                 UseResFile(resFile);
  4011.             }
  4012.         }
  4013.     }
  4014. } /*IssueFormatCommand*/
  4015.  
  4016. pascal OSErr IssueSetDataObjToBufferContents(const AEDesc * theObj)
  4017. {
  4018.       OSErr             myErr;
  4019.     OSErr                ignoreErr;
  4020.     AEAddressDesc     theAddress;
  4021.     AppleEvent        myAppleEvent;
  4022.     AppleEvent        defReply;
  4023.  
  4024.     myErr = MakeSelfAddress(&theAddress);
  4025.  
  4026.     /* create event */
  4027.  
  4028.     if (myErr==noErr)
  4029.         myErr = AECreateAppleEvent(kAECoreSuite, kAESetData, &theAddress, 0, 0, &myAppleEvent);
  4030.  
  4031.     /* add prop obj spec to the event */
  4032.  
  4033.     if (myErr==noErr)
  4034.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, theObj);
  4035.  
  4036.     /* add prop data to the event */
  4037.  
  4038.     if (myErr==noErr)
  4039.         myErr =
  4040.             AEPutParamPtr(
  4041.                 &myAppleEvent,
  4042.                 keyAEData,
  4043.                 typeChar,
  4044.                 (Ptr)gTypingBuffer,
  4045.                 gCharsInBuffer);
  4046.  
  4047.     /* send event */
  4048.  
  4049.     if (myErr==noErr)
  4050.      if (gRecordingImplemented)
  4051.          myErr =
  4052.              AESend(
  4053.                 &myAppleEvent,
  4054.                 &defReply,
  4055.                 kAENoReply+kAEDontExecute,
  4056.                 kAENormalPriority,
  4057.                 kAEDefaultTimeout,
  4058.                 nil,
  4059.                 nil);
  4060.  
  4061.     if (theAddress.dataHandle)
  4062.         ignoreErr = AEDisposeDesc(&theAddress);
  4063.  
  4064.     if (myAppleEvent.dataHandle)
  4065.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  4066.  
  4067.     return myErr;
  4068. }
  4069.  
  4070. pascal void AddKeyToTypingBuffer(DPtr theDocument, char theKey)
  4071. {
  4072.     OSErr myErr;
  4073.     OSErr ignoreErr;
  4074.  
  4075.     if (theKey==BS || theKey==FS || theKey==GS || theKey==RS || theKey==US) {
  4076.         FlushAndRecordTypingBuffer();
  4077.         if (theKey==BS) {
  4078.             if ((**theDocument->theText).selStart!=(**theDocument->theText).selEnd) {
  4079.                 myErr =
  4080.                     MakeTextObj(
  4081.                         theDocument->theWindow,
  4082.                         (**theDocument->theText).selStart,
  4083.                         (**theDocument->theText).selEnd,
  4084.                         &gTypingTargetObject);
  4085.             } else {
  4086.                 myErr =
  4087.                     MakeTextObj(
  4088.                         theDocument->theWindow,
  4089.                         (**theDocument->theText).selStart-1,
  4090.                         (**theDocument->theText).selStart,
  4091.                         &gTypingTargetObject);
  4092.             }
  4093.  
  4094.              myErr = IssueSetDataObjToBufferContents(&gTypingTargetObject);
  4095.  
  4096.             ignoreErr = AEDisposeDesc(&gTypingTargetObject);
  4097.  
  4098.             gTypingTargetObject.dataHandle = nil;
  4099.         }
  4100.     } else {
  4101.         if (gCharsInBuffer==0)
  4102.             myErr =
  4103.                 MakeSelectedTextObj(
  4104.                     theDocument->theWindow,
  4105.                     theDocument->theText,
  4106.                     &gTypingTargetObject);
  4107.  
  4108.         gTypingBuffer[gCharsInBuffer++] = theKey;
  4109.     }
  4110. }
  4111.  
  4112. pascal void FlushAndRecordTypingBuffer(void)
  4113. {
  4114.       OSErr  myErr;
  4115.     OSErr  ignoreErr;
  4116.  
  4117.     if (gCharsInBuffer != 0) {
  4118.         myErr = IssueSetDataObjToBufferContents(&gTypingTargetObject);
  4119.  
  4120.         if (gTypingTargetObject.dataHandle)
  4121.             ignoreErr = AEDisposeDesc(&gTypingTargetObject);
  4122.     }
  4123.  
  4124.     gCharsInBuffer = 0;
  4125.     gTypingTargetObject.dataHandle = 0;
  4126. }
  4127.  
  4128. /*****************************************************************************/
  4129. /*
  4130.     Object Accessors
  4131. */
  4132.  
  4133. pascal OSErr WindowFromNullAccessor(
  4134.     DescType      wantClass,
  4135.     const AEDesc  *container,
  4136.     DescType      containerClass,
  4137.     DescType      form,
  4138.     const AEDesc  *selectionData,
  4139.     AEDesc        *value,
  4140.     long          theRefCon)
  4141. {
  4142. #if !defined(powerc) && !defined(__powerc)
  4143. #pragma unused (container,theRefCon)
  4144. #endif
  4145.  
  4146.     OSErr       myErr;
  4147.     Str255      nameStr;
  4148.     WindowToken theWindow;
  4149.     short       index;
  4150.     AEDesc      resultDesc;
  4151.  
  4152.     myErr = errAEBadKeyForm;    /* or whatever */
  4153.  
  4154.     value->dataHandle     = nil;
  4155.     resultDesc.dataHandle = nil;
  4156.  
  4157.     /*
  4158.         should only be called with wantClass = cWindow and
  4159.         with containerClass = typeNull or typeMyAppl.
  4160.         Currently accept as either formName or formAbsolutePosition
  4161.     */
  4162.  
  4163.     if (
  4164.         ((wantClass != cWindow) && (wantClass != cDocument)) ||
  4165.         ((containerClass != typeNull) && (containerClass != typeMyAppl)) ||
  4166.         !((form == formName) || (form == formAbsolutePosition))
  4167.     )
  4168.         return errAEWrongDataType;
  4169.  
  4170.     if (form == formName) {
  4171.         myErr     = GetPStringFromDescriptor(selectionData, (char *)nameStr);
  4172.         theWindow = WindowNameToWindowPtr(nameStr);
  4173.     }
  4174.  
  4175.     if (form == formAbsolutePosition) {
  4176.         myErr         = GetIntegerFromDescriptor(selectionData, &index);
  4177.  
  4178.         if (index<0)
  4179.             index = CountWindows()+index+1;
  4180.  
  4181.         theWindow = GetWindowPtrOfNthWindow(index);
  4182.     }
  4183.  
  4184.     if (myErr == noErr)
  4185.         myErr = AECreateDesc(typeMyWndw, (Ptr)&theWindow, sizeof(theWindow), value);
  4186.  
  4187.     return myErr;
  4188. }    /* WindowFromNullAccessor */
  4189.  
  4190. pascal OSErr ApplicationFromNullAccessor(
  4191.     DescType      wantClass,
  4192.     const AEDesc  *container,
  4193.     DescType      containerClass,
  4194.     DescType      form,
  4195.     const AEDesc  *selectionData,
  4196.     AEDesc        *value,
  4197.     long          theRefCon)
  4198. {
  4199. #if !defined(powerc) && !defined(__powerc)
  4200. #pragma unused (container,selectionData,theRefCon)
  4201. #endif
  4202.  
  4203.     OSErr    myErr;
  4204.     appToken theApp;
  4205.     AEDesc   resultDesc;
  4206.  
  4207.     value->dataHandle     = nil;
  4208.     resultDesc.dataHandle = nil;
  4209.  
  4210.     /*
  4211.         should only be called with wantClass = cApplication and
  4212.         with containerClass = typeNull.
  4213.         Currently accept as either formName or formAbsolutePosition
  4214.     */
  4215.  
  4216.     if (
  4217.         (wantClass != cApplication) ||
  4218.         (containerClass != typeNull) ||
  4219.         !((form == formName) || (form == formAbsolutePosition))
  4220.     )
  4221.         return errAEWrongDataType;
  4222.  
  4223.     if ((form == formName) || (form == formAbsolutePosition)) {
  4224.         theApp.highLongOfPSN = 0;
  4225.         theApp.lowLongOfPSN  = kCurrentProcess;
  4226.     }
  4227.  
  4228.     myErr = AECreateDesc(typeMyAppl, (Ptr)&theApp, sizeof(theApp), value);
  4229.  
  4230.     return myErr;
  4231. }    /* ApplicationFromNullAccessor */
  4232.  
  4233. pascal void MoveToNonSpace(short *start, short limit, charsHandle myChars)
  4234. /*
  4235.     Treats space,comma, full stop, ; and : as space chars
  4236. */
  4237. {
  4238.     while (*start<=limit)
  4239.           switch ((**myChars)[*start]) {
  4240.           case ' ':
  4241.         case ',':
  4242.         case '.':
  4243.         case ':':
  4244.         case 10:
  4245.         case 13:
  4246.             (*start) +=1;
  4247.             break;
  4248.         default:
  4249.             return;
  4250.         }
  4251. }
  4252.  
  4253. pascal void MoveToSpace(short *start, short limit, charsHandle myChars)
  4254.     /*
  4255.         Treats space,comma, full stop, ; and : as space chars
  4256.     */
  4257. {
  4258.     while (*start<=limit)
  4259.           switch ((**myChars)[*start]) {
  4260.           case ' ':
  4261.         case ',':
  4262.         case '.':
  4263.         case ':':
  4264.         case 10:
  4265.         case 13:
  4266.             return;
  4267.         default:
  4268.             (*start) +=1;
  4269.             break;
  4270.         }
  4271. }
  4272.  
  4273. pascal short CountWords(TEHandle inTextHandle, short startAt, short forHowManyChars)
  4274. {
  4275.     charsHandle myChars;
  4276.     short       start;
  4277.     short       limit;
  4278.     short       myWords;
  4279.  
  4280.     myChars  = (charsHandle)(**inTextHandle).hText;
  4281.     limit    = startAt+forHowManyChars-1;
  4282.     start    = startAt;
  4283.     myWords  = 0;
  4284.     MoveToNonSpace(&start, limit, myChars);
  4285.     while (start<=limit) {
  4286.         myWords++;
  4287.         MoveToSpace(&start, limit, myChars);
  4288.         MoveToNonSpace(&start, limit, myChars);
  4289.     }
  4290.     return myWords;
  4291. } /* CountWords */
  4292.  
  4293. pascal void GetNthWordInfo(
  4294.     short    whichWord,
  4295.     TEHandle inTextHandle,
  4296.     short    *wordStartChar,
  4297.     short    *wordLength)
  4298.     /*
  4299.         On entry:    wordStartChar is start of char range to count in
  4300.                             wordLength is number of chars to consider
  4301.  
  4302.         On Exit : wordStartChar is start of requested word
  4303.                             wordLength is number of chars in word
  4304.     */
  4305. {
  4306.     charsHandle myChars;
  4307.     short       start;
  4308.     short       limit;
  4309.  
  4310.     myChars  = (charsHandle)(**inTextHandle).hText;
  4311.     limit    = *wordStartChar + *wordLength-1;
  4312.     start    = *wordStartChar;
  4313.     MoveToNonSpace(&start, limit, myChars);
  4314.     while ((start<=limit) && (whichWord>0)) {
  4315.  
  4316.         whichWord       = whichWord-1;
  4317.         *wordStartChar  = start;
  4318.         MoveToSpace(&start, limit, myChars);
  4319.         *wordLength     = start- *wordStartChar;
  4320.  
  4321.         MoveToNonSpace(&start, limit, myChars);
  4322.     }
  4323. } /* GetNthWordInfo */
  4324.  
  4325. pascal void GetWordInfo(
  4326.     short    whichWord,
  4327.     TEHandle inTextHandle,
  4328.     short    *wordStartChar,
  4329.     short    *wordLength)
  4330.     /*
  4331.         On wordStartChar entry is start of char range to count in
  4332.                             wordLength is number of chars to consider
  4333.  
  4334.         On Exit : wordStartChar is start of requested word
  4335.                             wordLength is number of chars in word
  4336.     */
  4337. {
  4338.     short noOfWords;
  4339.  
  4340.     noOfWords = CountWords(inTextHandle, *wordStartChar, *wordLength);
  4341.  
  4342.     if (whichWord<0)
  4343.         whichWord = noOfWords + whichWord + 1;
  4344.  
  4345.     if (whichWord>noOfWords) {
  4346.         *wordStartChar = *wordStartChar+*wordLength;
  4347.         *wordLength    = 0;
  4348.     } else
  4349.         GetNthWordInfo(whichWord, inTextHandle, wordStartChar, wordLength);
  4350. }
  4351.  
  4352. pascal short CountLines(TEHandle inTextHandle)
  4353. {
  4354.     /*
  4355.         CountLines makes use of info in TERec
  4356.     */
  4357.     return (**inTextHandle).nLines;
  4358. }
  4359.  
  4360. pascal short LineOfOffset(TEHandle theHTE, short charOffset)
  4361. {
  4362.     short n;
  4363.  
  4364.     n = (**theHTE).nLines;
  4365.  
  4366.     while (((**theHTE).lineStarts[n-1]>charOffset) &&
  4367.                  (n>0))
  4368.          n--;
  4369.  
  4370.     return n;
  4371. } /* LineOfOffset */
  4372.  
  4373. pascal void GetLineInfo(
  4374.     short    whichLine,
  4375.     TEHandle inTextHandle,
  4376.     short    *lineStartChar,
  4377.     short    *lineLength)
  4378. {
  4379.     short       noOfLines;
  4380.     charsHandle myChars;
  4381.  
  4382.     /* Addition of lines within text object */
  4383.     short       lineOfStart;
  4384.     short       lineOfEnd;
  4385.  
  4386.     lineOfStart = LineOfOffset(inTextHandle, *lineStartChar);
  4387.     lineOfEnd   = LineOfOffset(inTextHandle, *lineStartChar+*lineLength-1);
  4388.  
  4389.     myChars   = (charsHandle)(**inTextHandle).hText;
  4390.     noOfLines = lineOfEnd - lineOfStart + 1;
  4391.  
  4392.     if (whichLine<0)
  4393.         whichLine = noOfLines + whichLine + 1;
  4394.  
  4395.     noOfLines = CountLines(inTextHandle);
  4396.     whichLine = whichLine + lineOfStart - 1; /* convert offset relative to offset absolute */
  4397.  
  4398.     /* End of addition */
  4399.  
  4400.     if (whichLine<=lineOfEnd) {
  4401.         *lineStartChar = (**inTextHandle).lineStarts[whichLine-1];
  4402.         if (whichLine==noOfLines)
  4403.             *lineLength  = (**inTextHandle).teLength;
  4404.         else
  4405.             *lineLength  = (**inTextHandle).lineStarts[whichLine];
  4406.         *lineLength    = *lineLength-*lineStartChar;
  4407.         /*
  4408.             Don't return CR
  4409.         */
  4410.         if ((**myChars)[ *lineStartChar+*lineLength-1] == 13)
  4411.             *lineLength = *lineLength-1;
  4412.     } else {
  4413.         if (whichLine<noOfLines)
  4414.           *lineStartChar = (**inTextHandle).lineStarts[whichLine]; /* start of whichLine++ */
  4415.         else
  4416.             *lineStartChar = (**inTextHandle).teLength;
  4417.         *lineLength    = 0;
  4418.     }
  4419. } /* GetLineInfo */
  4420.  
  4421. pascal OSErr TextElemFromWndwAccessor(
  4422.     DescType     wantClass,
  4423.     const AEDesc *container,
  4424.     DescType     containerClass,
  4425.     DescType     form,
  4426.     const AEDesc *selectionData,
  4427.     AEDesc       *value,
  4428.     long         theRefCon)
  4429. {
  4430. #if !defined(powerc) && !defined(__powerc)
  4431. #pragma unused (theRefCon)
  4432. #endif
  4433.  
  4434.     OSErr       myErr;
  4435.     OSErr       ignoreErr;
  4436.     WindowToken theWindow;
  4437.     Size        actSize;
  4438.     long        index;
  4439.     TextToken   theTextToken;
  4440.     AERecord    selectionRecord;
  4441.     TextToken   startText;
  4442.     TextToken   stopText;
  4443.     DescType    returnedType;
  4444.     AEDesc      windDesc;
  4445.     TEHandle    theHTE;
  4446.     DPtr        theDocument;
  4447.     short       wordStartChar;
  4448.     short       wordLength;
  4449.  
  4450.     myErr = -1700;    /* or whatever */
  4451.  
  4452.     selectionRecord.dataHandle = nil;
  4453.  
  4454.     /* do some checking for robustness' sake */
  4455.  
  4456.     if (
  4457.         ((containerClass != cWindow) && (containerClass != cDocument)) ||
  4458.         ((wantClass != cText) && (wantClass != cChar) && (wantClass != cSpot) && (wantClass != cWord) && (wantClass != cLine)    ) ||
  4459.         ((form!=formRange) && (form!=formAbsolutePosition))
  4460.     )
  4461.         return errAEWrongDataType;
  4462.  
  4463.     /* let's get the window which contains the text element */
  4464.  
  4465.     myErr = AECoerceDesc(container, typeMyWndw, &windDesc);
  4466.     GetRawDataFromDescriptor(&windDesc, (Ptr)&theWindow, sizeof(theWindow), &actSize);
  4467.     myErr = AEDisposeDesc(&windDesc);
  4468.  
  4469.     if (theWindow==nil)
  4470.         myErr = errAEIllegalIndex;
  4471.     else {
  4472.         theTextToken.tokenWindow = theWindow;
  4473.  
  4474.         theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  4475.         theHTE      = theDocument->theText;
  4476.  
  4477.         switch (form) {
  4478.         case formAbsolutePosition:
  4479.             myErr = GetLongIntFromDescriptor(selectionData, &index);
  4480.  
  4481.             switch (wantClass) {
  4482.             case cSpot:
  4483.                 if (index<0)
  4484.                     theTextToken.tokenOffset = (**theHTE).teLength+index+2; /* Past last char */
  4485.                 else
  4486.                     theTextToken.tokenOffset = index;
  4487.  
  4488.                 theTextToken.tokenLength = 0;
  4489.                 break;
  4490.  
  4491.             case cChar:
  4492.                 if (index<0)
  4493.                     theTextToken.tokenOffset = (**theHTE).teLength+index+1;
  4494.                 else
  4495.                   theTextToken.tokenOffset = index;
  4496.  
  4497.                 theTextToken.tokenLength = 1;
  4498.                 break;
  4499.  
  4500.             case cWord:
  4501.                 wordStartChar = 0;
  4502.                 wordLength    = (**theHTE).teLength;
  4503.                 GetWordInfo(index, theHTE, &wordStartChar, &wordLength); /* zero based */
  4504.                 theTextToken.tokenOffset = wordStartChar+1;
  4505.                 theTextToken.tokenLength = wordLength;
  4506.                 break;
  4507.  
  4508.             case cLine:
  4509.                 wordStartChar = 0;
  4510.                 wordLength    = (**theHTE).teLength;
  4511.                 GetLineInfo(index, theHTE, &wordStartChar, &wordLength); /* zero based */
  4512.                 theTextToken.tokenOffset = wordStartChar+1;
  4513.                 theTextToken.tokenLength = wordLength;
  4514.                 break;
  4515.             
  4516.             case cText:
  4517.                 theTextToken.tokenOffset = 1;
  4518.                 theTextToken.tokenLength = (**theHTE).teLength;
  4519.                 myErr                             = noErr;
  4520.                 break;
  4521.             }
  4522.             break;
  4523.  
  4524.         case formRange:
  4525.             /* coerce the selection data into an AERecord */
  4526.  
  4527.              myErr = AECoerceDesc(selectionData, typeAERecord, &selectionRecord);
  4528.  
  4529.             /* get the start object as a text token -
  4530.                     this will reenter this proc but as formAbsolutePosition via the coercion handler*/
  4531.  
  4532.             myErr =
  4533.                 AEGetKeyPtr(
  4534.                     &selectionRecord,
  4535.                     keyAERangeStart,
  4536.                     typeMyText,
  4537.                     &returnedType,
  4538.                     (Ptr)&startText,
  4539.                     sizeof(startText),
  4540.                     &actSize);
  4541.  
  4542.             /* now do the same for the stop object */
  4543.             if (myErr==noErr)
  4544.                 myErr =
  4545.                     AEGetKeyPtr(
  4546.                         &selectionRecord,
  4547.                         keyAERangeStop,
  4548.                         typeMyText,
  4549.                         &returnedType,
  4550.                         (Ptr)&stopText,
  4551.                         sizeof(stopText),
  4552.                         &actSize);
  4553.  
  4554.             if (myErr==noErr)
  4555.                 if (
  4556.                     (theTextToken.tokenWindow != stopText.tokenWindow) ||
  4557.                     (theTextToken.tokenWindow != startText.tokenWindow)
  4558.                 )
  4559.                     myErr = errAECorruptData;    /* or whatever ????*/
  4560.  
  4561.             theTextToken.tokenOffset  = startText.tokenOffset;
  4562.             theTextToken.tokenLength  = stopText.tokenOffset + stopText.tokenLength - startText.tokenOffset;
  4563.  
  4564.             if (theTextToken.tokenLength<0)
  4565.                 myErr = errAECorruptData;    /* or whatever */
  4566.  
  4567.             ignoreErr = AEDisposeDesc(&selectionRecord);
  4568.  
  4569.             break;
  4570.         }
  4571.     }
  4572.  
  4573.     /* return theTextToken in a descriptor */
  4574.  
  4575.     if (myErr==noErr)
  4576.         myErr = AECreateDesc(typeMyText, (Ptr)&theTextToken, sizeof(theTextToken), value);
  4577.  
  4578.     return myErr;
  4579. }    /* TextElemFromWndwAccessor */
  4580.  
  4581. pascal OSErr TextElemFromWndwPropAccessor(
  4582.     DescType     wantClass,
  4583.     const AEDesc *container,
  4584.     DescType     containerClass,
  4585.     DescType     form,
  4586.     const AEDesc *selectionData,
  4587.     AEDesc       *value,
  4588.     long         theRefCon)
  4589. {
  4590. #if !defined(powerc) && !defined(__powerc)
  4591. #pragma unused (theRefCon, containerClass)
  4592. #endif
  4593.  
  4594.     OSErr               myErr;
  4595.     Size                actSize;
  4596.     long                index;
  4597.     AEDesc                windowPropDesc;
  4598.     windowPropToken     theWindowPropToken;
  4599.     TextToken           theTextToken;
  4600.     AERecord            selectionRecord;
  4601.     TextToken           startText;
  4602.     TextToken           stopText;
  4603.     DescType            returnedType;
  4604.     TEHandle            theHTE;
  4605.     short               wordStartChar;
  4606.     short               wordLength;
  4607.     DPtr                theDocument;
  4608.  
  4609.     myErr = -1700;    /* or whatever */
  4610.     windowPropDesc.dataHandle = nil;
  4611.     
  4612.     /* do some checking for robustness' sake */
  4613.  
  4614.     if (
  4615.         ((wantClass != cText) && (wantClass != cChar) && (wantClass != cSpot) && (wantClass != cLine) && (wantClass != cWord)) ||
  4616.         ((form != formAbsolutePosition) && (form != formRange))
  4617.     )
  4618.         return errAEWrongDataType;
  4619.  
  4620.     /* get the window property token*/
  4621.     myErr = AECoerceDesc(container, typeMyWindowProp, &windowPropDesc);
  4622.     GetRawDataFromDescriptor(&windowPropDesc, (Ptr)&theWindowPropToken, sizeof(theWindowPropToken), &actSize);
  4623.     if (windowPropDesc.dataHandle)
  4624.         AEDisposeDesc(&windowPropDesc);
  4625.  
  4626.     if (theWindowPropToken.tokenProperty != pSelection)
  4627.         return errAEEventNotHandled;
  4628.         
  4629.     /* let's get the src text */
  4630.     theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  4631.     theHTE      = theDocument->theText;
  4632.  
  4633.     theTextToken.tokenWindow     = theWindowPropToken.tokenWindowToken;
  4634.     theTextToken.tokenOffset    = (*theHTE)->selStart + 1;
  4635.     theTextToken.tokenLength    = (*theHTE)->selEnd - (*theHTE)->selStart;
  4636.  
  4637.     switch (form) {
  4638.     case formAbsolutePosition:
  4639.         myErr = GetLongIntFromDescriptor(selectionData, &index);
  4640.  
  4641.         switch (wantClass) {
  4642.         case cSpot:
  4643.             if (index<0)
  4644.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index+1+theTextToken.tokenLength;
  4645.             else
  4646.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index-1;
  4647.             theTextToken.tokenLength = 0;
  4648.             break;
  4649.  
  4650.         case cChar:
  4651.             if (index<0)
  4652.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index+1+theTextToken.tokenLength;
  4653.             else
  4654.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index-1;
  4655.             theTextToken.tokenLength = 1;
  4656.             break;
  4657.  
  4658.         case cWord:
  4659.             wordStartChar = theTextToken.tokenOffset-1;
  4660.             wordLength    = theTextToken.tokenLength;
  4661.  
  4662.             GetWordInfo(index, theHTE, &wordStartChar, &wordLength);/*zero based*/
  4663.  
  4664.             theTextToken.tokenOffset = wordStartChar+1;
  4665.             theTextToken.tokenLength = wordLength;
  4666.             break;
  4667.  
  4668.         case cLine:
  4669.             wordStartChar = theTextToken.tokenOffset-1;
  4670.             wordLength    = theTextToken.tokenLength;
  4671.  
  4672.             GetLineInfo(index, theHTE, &wordStartChar, &wordLength);
  4673.  
  4674.             theTextToken.tokenOffset = wordStartChar+1;
  4675.             theTextToken.tokenLength = wordLength;
  4676.             break;
  4677.         default: /* case cText */
  4678.             break;
  4679.         }
  4680.         break;
  4681.  
  4682.     case formRange:
  4683.         /* coerce the selection data into an AERecord */
  4684.  
  4685.          myErr = AECoerceDesc(selectionData, typeAERecord, &selectionRecord);
  4686.  
  4687.         /* get the start object as a text token -
  4688.                 this will reenter this proc but as formAbsolutePosition via the coercion handler*/
  4689.  
  4690.         myErr =
  4691.             AEGetKeyPtr(
  4692.                 &selectionRecord,
  4693.                 keyAERangeStart,
  4694.                 typeMyText,
  4695.                 &returnedType,
  4696.                 (Ptr)&startText,
  4697.                 sizeof(startText),
  4698.                 &actSize);
  4699.  
  4700.         /* now do the same for the stop object */
  4701.  
  4702.         if (myErr==noErr)
  4703.             myErr =
  4704.                 AEGetKeyPtr(
  4705.                     &selectionRecord,
  4706.                     keyAERangeStop,
  4707.                     typeMyText,
  4708.                     &returnedType,
  4709.                     (Ptr)&stopText,
  4710.                     sizeof(stopText),
  4711.                     &actSize);
  4712.  
  4713.         if (myErr==noErr)
  4714.             if ((theTextToken.tokenWindow != stopText.tokenWindow) ||
  4715.                   (theTextToken.tokenWindow != startText.tokenWindow))
  4716.                 myErr = errAECorruptData;    /* or whatever */
  4717.  
  4718.         theTextToken.tokenOffset  = startText.tokenOffset;
  4719.         theTextToken.tokenLength  = stopText.tokenOffset + stopText.tokenLength - startText.tokenOffset;
  4720.  
  4721.         myErr = AEDisposeDesc(&selectionRecord);
  4722.         break;
  4723.     }
  4724.  
  4725.     /* return theTextToken in a descriptor */
  4726.  
  4727.     myErr =
  4728.         AECreateDesc(
  4729.             typeMyText,
  4730.             (Ptr)&theTextToken,
  4731.             sizeof(theTextToken),
  4732.             value);
  4733.  
  4734.     return myErr;
  4735. }    /* TextElemFromWndwPropAccessor */
  4736.  
  4737. pascal OSErr TextElemFromTextAccessor(
  4738.     DescType     wantClass,
  4739.     const AEDesc *container,
  4740.     DescType     containerClass,
  4741.     DescType     form,
  4742.     const AEDesc *selectionData,
  4743.     AEDesc       *value,
  4744.     long         theRefCon)
  4745. {
  4746. #if !defined(powerc) && !defined(__powerc)
  4747. #pragma unused (theRefCon, containerClass)
  4748. #endif
  4749.  
  4750.     OSErr       myErr;
  4751.     Size        actSize;
  4752.     long        index;
  4753.     TextToken   theTextToken;
  4754.     AERecord    selectionRecord;
  4755.     TextToken   startText;
  4756.     TextToken   stopText;
  4757.     DescType    returnedType;
  4758.     AEDesc      textDesc;
  4759.     TEHandle    theHTE;
  4760.     short       wordStartChar;
  4761.     short       wordLength;
  4762.     DPtr        theDocument;
  4763.  
  4764.     myErr = -1700;    /* or whatever */
  4765.  
  4766.     /* do some checking for robustness' sake */
  4767.  
  4768.     if (
  4769.         ((wantClass != cText) && (wantClass != cChar) && (wantClass != cSpot) && (wantClass != cLine) && (wantClass != cWord)) ||
  4770.         ((form != formAbsolutePosition) && (form != formRange))
  4771.     )
  4772.         return errAEWrongDataType;
  4773.  
  4774.     /* let's get the src text */
  4775.  
  4776.     myErr = AECoerceDesc(container, typeMyText, &textDesc);
  4777.     GetRawDataFromDescriptor(&textDesc, (Ptr)&theTextToken, sizeof(theTextToken), &actSize);
  4778.  
  4779.     myErr = AEDisposeDesc(&textDesc);
  4780.  
  4781.     theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  4782.     theHTE      = theDocument->theText;
  4783.  
  4784.     switch (form) {
  4785.     case formAbsolutePosition:
  4786.         myErr = GetLongIntFromDescriptor(selectionData, &index);
  4787.  
  4788.         switch (wantClass) {
  4789.         case cSpot:
  4790.             if (index<0)
  4791.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index+1+theTextToken.tokenLength;
  4792.             else
  4793.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index-1;
  4794.             theTextToken.tokenLength = 0;
  4795.             break;
  4796.  
  4797.         case cChar:
  4798.             if (index<0)
  4799.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index+1+theTextToken.tokenLength;
  4800.             else
  4801.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index-1;
  4802.             theTextToken.tokenLength = 1;
  4803.             break;
  4804.  
  4805.         case cWord:
  4806.             wordStartChar = theTextToken.tokenOffset-1;
  4807.             wordLength    = theTextToken.tokenLength;
  4808.  
  4809.             GetWordInfo(index, theHTE, &wordStartChar, &wordLength);/*zero based*/
  4810.  
  4811.             theTextToken.tokenOffset = wordStartChar+1;
  4812.             theTextToken.tokenLength = wordLength;
  4813.             break;
  4814.  
  4815.         case cLine:
  4816.             wordStartChar = theTextToken.tokenOffset-1;
  4817.             wordLength    = theTextToken.tokenLength;
  4818.  
  4819.             GetLineInfo(index, theHTE, &wordStartChar, &wordLength);
  4820.  
  4821.             theTextToken.tokenOffset = wordStartChar+1;
  4822.             theTextToken.tokenLength = wordLength;
  4823.             break;
  4824.         }
  4825.         break;
  4826.  
  4827.     case formRange:
  4828.         /* coerce the selection data into an AERecord */
  4829.  
  4830.          myErr = AECoerceDesc(selectionData, typeAERecord, &selectionRecord);
  4831.  
  4832.         /* get the start object as a text token -
  4833.                 this will reenter this proc but as formAbsolutePosition via the coercion handler*/
  4834.  
  4835.         myErr =
  4836.             AEGetKeyPtr(
  4837.                 &selectionRecord,
  4838.                 keyAERangeStart,
  4839.                 typeMyText,
  4840.                 &returnedType,
  4841.                 (Ptr)&startText,
  4842.                 sizeof(startText),
  4843.                 &actSize);
  4844.  
  4845.         /* now do the same for the stop object */
  4846.  
  4847.         if (myErr==noErr)
  4848.             myErr =
  4849.                 AEGetKeyPtr(
  4850.                     &selectionRecord,
  4851.                     keyAERangeStop,
  4852.                     typeMyText,
  4853.                     &returnedType,
  4854.                     (Ptr)&stopText,
  4855.                     sizeof(stopText),
  4856.                     &actSize);
  4857.  
  4858.         if (myErr==noErr)
  4859.             if ((theTextToken.tokenWindow != stopText.tokenWindow) ||
  4860.                   (theTextToken.tokenWindow != startText.tokenWindow))
  4861.                 myErr = errAECorruptData;    /* or whatever */
  4862.  
  4863.         theTextToken.tokenOffset  = startText.tokenOffset;
  4864.         theTextToken.tokenLength  = stopText.tokenOffset + stopText.tokenLength - startText.tokenOffset;
  4865.  
  4866.         myErr = AEDisposeDesc(&selectionRecord);
  4867.         break;
  4868.     }
  4869.  
  4870.     /* return theTextToken in a descriptor */
  4871.  
  4872.     myErr =
  4873.         AECreateDesc(
  4874.             typeMyText,
  4875.             (Ptr)&theTextToken,
  4876.             sizeof(theTextToken),
  4877.             value);
  4878.  
  4879.     return myErr;
  4880. }    /* TextElemFromTextAccessor */
  4881.  
  4882. pascal OSErr PropertyFromTextAccessor(
  4883.     DescType     wantClass,
  4884.     const AEDesc *container,
  4885.     DescType     containerClass,
  4886.     DescType     form,
  4887.     const AEDesc *selectionData,
  4888.     AEDesc       *value,
  4889.     long         theRefCon)
  4890. {
  4891. #if !defined(powerc) && !defined(__powerc)
  4892. #pragma unused (theRefCon, containerClass)
  4893. #endif
  4894.  
  4895.     OSErr         myErr;
  4896.     OSErr         ignoreErr;
  4897.     TextToken     theTextToken;
  4898.     DescType      theProperty;
  4899.     AEDesc        textDesc;
  4900.     AEDesc        propDesc;
  4901.     Size          actualSize;
  4902.     textPropToken myTextProp;
  4903.  
  4904.     value->dataHandle   = nil;
  4905.     textDesc.dataHandle = nil;
  4906.     propDesc.dataHandle = nil;
  4907.  
  4908.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4909.         return errAEWrongDataType;
  4910.     }
  4911.  
  4912.     /* get the text token */
  4913.     myErr = AECoerceDesc(container, typeMyText, &textDesc);
  4914.     GetRawDataFromDescriptor(&textDesc, (Ptr)&theTextToken, sizeof(theTextToken), &actualSize);
  4915.  
  4916.     /* get the property */
  4917.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4918.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4919.  
  4920.     /*
  4921.         Combine the two into single token
  4922.     */
  4923.     myTextProp.propertyTextToken = theTextToken;
  4924.     myTextProp.propertyProperty  = theProperty;
  4925.  
  4926.     myErr = AECreateDesc(typeMyTextProp, (Ptr)&myTextProp, sizeof(myTextProp), value);
  4927.  
  4928.     if (textDesc.dataHandle)
  4929.         ignoreErr = AEDisposeDesc(&textDesc);
  4930.  
  4931.     if (propDesc.dataHandle)
  4932.         ignoreErr = AEDisposeDesc(&propDesc);
  4933.  
  4934.     return myErr;
  4935. }    /* PropertyFromTextAccessor */
  4936.  
  4937. pascal OSErr PropertyFromWndwAccessor(
  4938.     DescType     wantClass,
  4939.     const AEDesc *container,
  4940.     DescType     containerClass,
  4941.     DescType     form,
  4942.     const AEDesc *selectionData,
  4943.     AEDesc       *value,
  4944.     long         theRefCon)
  4945. {
  4946. #if !defined(powerc) && !defined(__powerc)
  4947. #pragma unused (theRefCon, containerClass)
  4948. #endif
  4949.  
  4950.     OSErr           myErr;
  4951.     OSErr           ignoreErr;
  4952.     WindowToken     theWindowToken;
  4953.     DescType        theProperty;
  4954.     AEDesc          windowDesc;
  4955.     AEDesc          propDesc;
  4956.     Size            actualSize;
  4957.     windowPropToken myWindowProp;
  4958.  
  4959.     value->dataHandle     = nil;
  4960.     windowDesc.dataHandle = nil;
  4961.     propDesc.dataHandle   = nil;
  4962.  
  4963.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4964.         return errAEWrongDataType;
  4965.     }
  4966.  
  4967.     /* get the window token - it's the container */
  4968.     myErr = AECoerceDesc(container, typeMyWndw, &windowDesc);
  4969.     GetRawDataFromDescriptor(&windowDesc, (Ptr)&theWindowToken, sizeof(theWindowToken), &actualSize);
  4970.  
  4971.     /* Check the window exists */
  4972.     if (theWindowToken==nil)
  4973.         myErr = errAEIllegalIndex;
  4974.     else {
  4975.  
  4976.         /* get the property - it's in the selection data */
  4977.  
  4978.         myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4979.         GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4980.  
  4981.         myWindowProp.tokenWindowToken = theWindowToken;
  4982.         myWindowProp.tokenProperty    = theProperty;
  4983.  
  4984.         myErr = AECreateDesc(typeMyWindowProp, (Ptr)&myWindowProp, sizeof(myWindowProp), value);
  4985.     }
  4986.  
  4987.     if (windowDesc.dataHandle)
  4988.         ignoreErr = AEDisposeDesc(&windowDesc);
  4989.  
  4990.     if (propDesc.dataHandle)
  4991.         ignoreErr = AEDisposeDesc(&propDesc);
  4992.  
  4993.     return myErr;
  4994. }    /* PropertyFromWndwAccessor */
  4995.  
  4996. pascal OSErr PropertyFromWndwPropAccessor(
  4997.     DescType     wantClass,
  4998.     const AEDesc *container,
  4999.     DescType     containerClass,
  5000.     DescType     form,
  5001.     const AEDesc *selectionData,
  5002.     AEDesc       *value,
  5003.     long         theRefCon)
  5004. {
  5005. #if !defined(powerc) && !defined(__powerc)
  5006. #pragma unused (theRefCon, containerClass)
  5007. #endif
  5008.  
  5009.     OSErr               myErr;
  5010.     OSErr               ignoreErr;
  5011.     windowPropToken     theWindowPropToken;
  5012.     textPropToken         myTextProp;
  5013.     DescType            theProperty;
  5014.     AEDesc              windowPropDesc;
  5015.     AEDesc              propDesc;
  5016.     Size                actualSize;
  5017.     TEHandle            theHTE;
  5018.     DPtr                theDocument;
  5019.  
  5020.     value->dataHandle             = nil;
  5021.     windowPropDesc.dataHandle     = nil;
  5022.     propDesc.dataHandle           = nil;
  5023.  
  5024.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  5025.         return errAEWrongDataType;
  5026.     }
  5027.  
  5028.     /* get the window property token*/
  5029.     myErr = AECoerceDesc(container, typeMyWindowProp, &windowPropDesc);
  5030.     GetRawDataFromDescriptor(&windowPropDesc, (Ptr)&theWindowPropToken, sizeof(theWindowPropToken), &actualSize);
  5031.  
  5032.     /* get the property */
  5033.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  5034.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  5035.  
  5036.     if (theWindowPropToken.tokenProperty != pSelection)
  5037.         myErr = errAEEventNotHandled;
  5038.     else {
  5039.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  5040.         theHTE      = theDocument->theText;
  5041.         
  5042.         myTextProp.propertyTextToken.tokenWindow     = theWindowPropToken.tokenWindowToken;
  5043.         myTextProp.propertyTextToken.tokenOffset    = (*theHTE)->selStart + 1;
  5044.         myTextProp.propertyTextToken.tokenLength    = (*theHTE)->selEnd - (*theHTE)->selStart;
  5045.         myTextProp.propertyProperty                    = theProperty;
  5046.  
  5047.         myErr = AECreateDesc(typeMyTextProp, (Ptr)&myTextProp, sizeof(myTextProp), value);
  5048.     }
  5049.  
  5050.     if (windowPropDesc.dataHandle)
  5051.         ignoreErr = AEDisposeDesc(&windowPropDesc);
  5052.  
  5053.     if (propDesc.dataHandle)
  5054.         ignoreErr = AEDisposeDesc(&propDesc);
  5055.  
  5056.     return myErr;
  5057. }    /* PropertyFromWndwPropAccessor */
  5058.  
  5059. pascal OSErr PropertyFromNullAccessor(
  5060.     DescType     wantClass,
  5061.     const AEDesc *container,
  5062.     DescType     containerClass,
  5063.     DescType     form,
  5064.     const AEDesc *selectionData,
  5065.     AEDesc       *value,
  5066.     long         theRefCon)
  5067. {
  5068. #if !defined(powerc) && !defined(__powerc)
  5069. #pragma unused (theRefCon)
  5070. #endif
  5071.  
  5072.     OSErr                    myErr;
  5073.     OSErr                    ignoreErr;
  5074.     appToken                theApplToken;
  5075.     DescType                theProperty;
  5076.     AEDesc                applDesc;
  5077.     AEDesc                propDesc;
  5078.     Size                    actualSize;
  5079.     applPropToken        myApplProp;
  5080.     windowPropToken    myWindowProp;
  5081.     TEHandle                theHTE;
  5082.     DPtr                    theDocument;
  5083.  
  5084.     value->dataHandle     = nil;
  5085.     applDesc.dataHandle   = nil;
  5086.     propDesc.dataHandle   = nil;
  5087.  
  5088.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  5089.         return errAEWrongDataType;
  5090.     }
  5091.  
  5092.     /* get the application token - it's the container */
  5093.     
  5094.     if (containerClass != typeNull) {
  5095.         myErr = AECoerceDesc(container, typeMyAppl, &applDesc);
  5096.         GetRawDataFromDescriptor(&applDesc, (Ptr)&theApplToken, sizeof(theApplToken), &actualSize);
  5097.     } else {
  5098.         theApplToken.highLongOfPSN = 0;
  5099.         theApplToken.lowLongOfPSN  = kCurrentProcess;
  5100.     }
  5101.     
  5102.     /* get the property - it's in the selection data */
  5103.  
  5104.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  5105.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  5106.  
  5107.     switch (theProperty) {
  5108.     case pUserSelection:
  5109.         theProperty = pSelection;
  5110.         /* Fall through */
  5111.     case pSelection:
  5112.         if (myWindowProp.tokenWindowToken = FrontWindow()) {
  5113.             myWindowProp.tokenProperty    = theProperty;
  5114.  
  5115.             myErr = AECreateDesc(typeMyWindowProp, (Ptr)&myWindowProp, sizeof(myWindowProp), value);
  5116.         } else
  5117.             myErr = errAEIllegalIndex;
  5118.             
  5119.         break;
  5120.     default:
  5121.         /*
  5122.             Combine the two into single token
  5123.         */
  5124.         myApplProp.tokenApplToken    = theApplToken;
  5125.         myApplProp.tokenApplProperty = theProperty;
  5126.     
  5127.         myErr = AECreateDesc(typeMyApplProp, (Ptr)&myApplProp, sizeof(myApplProp), value);
  5128.         break;
  5129.     }
  5130.     
  5131.     if (applDesc.dataHandle)
  5132.         ignoreErr = AEDisposeDesc(&applDesc);
  5133.  
  5134.     if (propDesc.dataHandle)
  5135.         ignoreErr = AEDisposeDesc(&propDesc);
  5136.  
  5137.     return myErr;
  5138. }    /* PropertyFromApplAccessor */
  5139.  
  5140. pascal OSErr MenuNameToMenuToken(const Str255 theName, MenuToken *theToken)
  5141. {
  5142.     short   index;
  5143.  
  5144.     for (index=appleM; index<kLastMenu; index++) {
  5145.         if (IUEqualString(theName, (**(myMenus[index])).menuData)==0) {
  5146.             theToken->theTokenMenu = myMenus[index];
  5147.             theToken->theTokenID   = index+appleID;
  5148.             return noErr;
  5149.         }
  5150.     }
  5151.     return errAEIllegalIndex;
  5152. }
  5153.  
  5154. pascal OSErr MenuFromNullAccessor(
  5155.     DescType      wantClass,
  5156.     const AEDesc  *container,
  5157.     DescType      containerClass,
  5158.     DescType      form,
  5159.     const AEDesc  *selectionData,
  5160.     AEDesc        *value,
  5161.     long          theRefCon)
  5162. {
  5163. #if !defined(powerc) && !defined(__powerc)
  5164. #pragma unused (container,theRefCon)
  5165. #endif
  5166.  
  5167.     OSErr       myErr;
  5168.     Str255      nameStr;
  5169.     MenuToken   theMenu;
  5170.     short       index;
  5171.     AEDesc      resultDesc;
  5172.  
  5173.     myErr = errAEBadKeyForm;    /* or whatever */
  5174.  
  5175.     value->dataHandle     = nil;
  5176.     resultDesc.dataHandle = nil;
  5177.  
  5178.     /*
  5179.         should only be called with wantClass = cMenu and
  5180.         with containerClass = typeNull or typeMyAppl.
  5181.         Currently accept as either formName or formAbsolutePosition
  5182.     */
  5183.  
  5184.     if (
  5185.         (wantClass != cMenu) ||
  5186.         ((containerClass != typeNull) && (containerClass != typeMyAppl)) ||
  5187.         !((form == formName) || (form == formAbsolutePosition))
  5188.     )
  5189.         return errAEWrongDataType;
  5190.  
  5191.     if (form == formName) {
  5192.         myErr = GetPStringFromDescriptor(selectionData, (char *)nameStr);
  5193.         myErr = MenuNameToMenuToken(nameStr, &theMenu);
  5194.     }
  5195.  
  5196.     if (form == formAbsolutePosition) {
  5197.         myErr     = GetIntegerFromDescriptor(selectionData, &index);
  5198.         if (index<0)
  5199.             index = kLastMenu + index + 1;
  5200.  
  5201.         if (index>0 && index<kLastMenu+1) {
  5202.             theMenu.theTokenMenu = myMenus[index-1];
  5203.             theMenu.theTokenID   = index-1+appleID;
  5204.         } else
  5205.             myErr = errAEIllegalIndex;    /* or whatever */
  5206.     }
  5207.  
  5208.     if (myErr == noErr)
  5209.         myErr = AECreateDesc(typeMyMenu, (Ptr)&theMenu, sizeof(theMenu), value);
  5210.  
  5211.     return myErr;
  5212. }    /* MenuFromNullAccessor */
  5213.  
  5214. pascal OSErr PropertyFromMenuAccessor(
  5215.     DescType     wantClass,
  5216.     const AEDesc *container,
  5217.     DescType     containerClass,
  5218.     DescType     form,
  5219.     const AEDesc *selectionData,
  5220.     AEDesc       *value,
  5221.     long         theRefCon)
  5222. {
  5223. #if !defined(powerc) && !defined(__powerc)
  5224. #pragma unused (theRefCon, containerClass)
  5225. #endif
  5226.  
  5227.     OSErr         myErr;
  5228.     OSErr         ignoreErr;
  5229.     MenuToken     theMenuToken;
  5230.     DescType      theProperty;
  5231.     AEDesc        menuDesc;
  5232.     AEDesc        propDesc;
  5233.     Size          actualSize;
  5234.     MenuPropToken myMenuProp;
  5235.  
  5236.     value->dataHandle     = nil;
  5237.     menuDesc.dataHandle   = nil;
  5238.     propDesc.dataHandle   = nil;
  5239.  
  5240.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  5241.         return errAEWrongDataType;
  5242.     }
  5243.  
  5244.     /* get the menu token - it's the container */
  5245.  
  5246.     myErr = AECoerceDesc(container, typeMyMenu, &menuDesc);
  5247.     GetRawDataFromDescriptor(&menuDesc, (Ptr)&theMenuToken, sizeof(theMenuToken), &actualSize);
  5248.  
  5249.     /* get the property - it's in the selection data */
  5250.  
  5251.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  5252.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  5253.  
  5254.     /*
  5255.         Combine the two into single token
  5256.     */
  5257.     myMenuProp.theMenuToken = theMenuToken;
  5258.     myMenuProp.theMenuProp  = theProperty;
  5259.  
  5260.     myErr = AECreateDesc(typeMyMenuProp, (Ptr)&myMenuProp, sizeof(myMenuProp), value);
  5261.  
  5262.     if (menuDesc.dataHandle)
  5263.         ignoreErr = AEDisposeDesc(&menuDesc);
  5264.  
  5265.     if (propDesc.dataHandle)
  5266.         ignoreErr = AEDisposeDesc(&propDesc);
  5267.  
  5268.     return myErr;
  5269. }    /* PropertyFromMenuAccessor */
  5270.  
  5271. pascal OSErr PropertyFromMenuItemAccessor(
  5272.     DescType     wantClass,
  5273.     const AEDesc *container,
  5274.     DescType     containerClass,
  5275.     DescType     form,
  5276.     const AEDesc *selectionData,
  5277.     AEDesc       *value,
  5278.     long         theRefCon)
  5279. {
  5280. #if !defined(powerc) && !defined(__powerc)
  5281. #pragma unused (theRefCon, containerClass)
  5282. #endif
  5283.  
  5284.     OSErr         myErr;
  5285.     OSErr         ignoreErr;
  5286.     MenuItemToken theMenuItemToken;
  5287.     DescType      theProperty;
  5288.     AEDesc        itemDesc;
  5289.     AEDesc        propDesc;
  5290.     Size          actualSize;
  5291.     MenuItemPropToken myItemProp;
  5292.  
  5293.     value->dataHandle     = nil;
  5294.     itemDesc.dataHandle   = nil;
  5295.     propDesc.dataHandle   = nil;
  5296.  
  5297.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  5298.         return errAEWrongDataType;
  5299.     }
  5300.  
  5301.     /* get the menu token - it's the container */
  5302.  
  5303.     myErr = AECoerceDesc(container, typeMyMenuItem, &itemDesc);
  5304.     GetRawDataFromDescriptor(&itemDesc, (Ptr)&theMenuItemToken, sizeof(theMenuItemToken), &actualSize);
  5305.  
  5306.     /* get the property - it's in the selection data */
  5307.  
  5308.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  5309.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  5310.     /*
  5311.         Combine the two into single token
  5312.     */
  5313.     myItemProp.theItemToken  = theMenuItemToken;
  5314.     myItemProp.theItemProp   = theProperty;
  5315.  
  5316.     myErr = AECreateDesc(typeMyItemProp, (Ptr)&myItemProp, sizeof(myItemProp), value);
  5317.  
  5318.     if (itemDesc.dataHandle)
  5319.         ignoreErr = AEDisposeDesc(&itemDesc);
  5320.  
  5321.     if (propDesc.dataHandle)
  5322.         ignoreErr = AEDisposeDesc(&propDesc);
  5323.  
  5324.     return myErr;
  5325. }    /* PropertyFromMenuItemAccessor */
  5326.  
  5327. pascal OSErr ItemNameToItemIndex(const Str255 theName, MenuHandle theMenu, short *theIndex)
  5328. {
  5329.     short   index;
  5330.     short   maxItems;
  5331.     Str255  menuName;
  5332.  
  5333.     maxItems = CountMItems(theMenu);
  5334.  
  5335.     for (index=1; index<=maxItems; index++) {
  5336.         GetItem(theMenu, index, menuName);
  5337.         if (IUEqualString(theName, menuName)==0) {
  5338.             *theIndex = index;
  5339.             return noErr;
  5340.         }
  5341.     }
  5342.     return errAEIllegalIndex;
  5343. }
  5344.  
  5345. pascal OSErr MenuItemFromMenuAccessor(
  5346.     DescType     wantClass,
  5347.     const AEDesc *container,
  5348.     DescType     containerClass,
  5349.     DescType     form,
  5350.     const AEDesc *selectionData,
  5351.     AEDesc       *value,
  5352.     long         theRefCon)
  5353. {
  5354. #if !defined(powerc) && !defined(__powerc)
  5355. #pragma unused (theRefCon)
  5356. #endif
  5357.  
  5358.     OSErr         myErr;
  5359.     OSErr         ignoreErr;
  5360.     MenuItemToken theMenuItemToken;
  5361.     MenuToken     theMenuToken;
  5362.     AEDesc        menuDesc;
  5363.     Size          actualSize;
  5364.     Str255        nameStr;
  5365.     short         maxItems;
  5366.     short         index;
  5367.  
  5368.     value->dataHandle     = nil;
  5369.     menuDesc.dataHandle   = nil;
  5370.  
  5371.     if (
  5372.         (wantClass != cMenuItem) || (containerClass != cMenu) ||
  5373.         ((form != formAbsolutePosition) && (form != formName))
  5374.     ) {
  5375.         return errAEWrongDataType;
  5376.     }
  5377.  
  5378.     /* get the menu token - it's the container */
  5379.  
  5380.     myErr = AECoerceDesc(container, typeMyMenu, &menuDesc);
  5381.     GetRawDataFromDescriptor(&menuDesc, (Ptr)&theMenuToken, sizeof(theMenuToken), &actualSize);
  5382.  
  5383.     if (form==formAbsolutePosition) {
  5384.         myErr = GetIntegerFromDescriptor(selectionData, &index);
  5385.         maxItems = CountMItems(theMenuToken.theTokenMenu);
  5386.  
  5387.         if (index<0)
  5388.             index = maxItems + index + 1;
  5389.  
  5390.         if ((index<1) || (index>maxItems))
  5391.           myErr = errAEIllegalIndex;
  5392.     }
  5393.  
  5394.     if (form == formName) {
  5395.         myErr  = GetPStringFromDescriptor(selectionData, (char *)nameStr);
  5396.         myErr  = ItemNameToItemIndex(nameStr, theMenuToken.theTokenMenu, &index);
  5397.     }
  5398.  
  5399.     /*
  5400.         Combine the two into single token
  5401.     */
  5402.  
  5403.     theMenuItemToken.theMenuToken  = theMenuToken;
  5404.     theMenuItemToken.theTokenItem  = index;
  5405.  
  5406.     if (myErr==noErr)
  5407.         myErr = AECreateDesc(typeMyMenuItem, (Ptr)&theMenuItemToken, sizeof(theMenuItemToken), value);
  5408.  
  5409.     if (menuDesc.dataHandle)
  5410.         ignoreErr = AEDisposeDesc(&menuDesc);
  5411.  
  5412.     return myErr;
  5413. }    /* MenuItemFromMenuAccessor */
  5414.  
  5415. /*******************************************************************************/
  5416. /*
  5417.     Stuff for counting objects
  5418. */
  5419.  
  5420. pascal OSErr MyCountProc(
  5421.     DescType     desiredType,
  5422.     DescType     containerClass,
  5423.     const AEDesc *container,
  5424.     long         *result)
  5425. /* so far all I count is:
  5426.   (1) the number of active windows in the app;
  5427.   (2) the number of words in a window
  5428. */
  5429. {
  5430.     OSErr       myErr;
  5431.     WindowToken theWindowToken;
  5432.     DPtr        theDocument;
  5433.     TEHandle    theHTE;
  5434.     AEDesc      newDesc;
  5435.     short       wordStart;
  5436.     short       wordLength;
  5437.     Size        tokenSize;
  5438.     TextToken   theTextToken;
  5439.  
  5440.     *result = -1;    /* easily recognized illegal value */
  5441.  
  5442.     myErr = errAEWrongDataType;
  5443.  
  5444.     if (desiredType == cWindow || desiredType == cDocument) {
  5445.         if ((containerClass == typeNull) || (containerClass == cApplication))
  5446.             *result = CountWindows();
  5447.     }
  5448.  
  5449.     if ((desiredType == cWord) || (desiredType == cLine) || (desiredType == cChar)) {
  5450.         myErr = AECoerceDesc(container, typeMyWndw, &newDesc);
  5451.         if (newDesc.descriptorType!=typeNull) {
  5452.                 GetRawDataFromDescriptor(
  5453.                     &newDesc,
  5454.                     (Ptr)&theWindowToken,
  5455.                     sizeof(theWindowToken),
  5456.                     &tokenSize);
  5457.  
  5458.                 myErr = AEDisposeDesc(&newDesc);
  5459.  
  5460.                 if (theWindowToken==nil)
  5461.                     myErr = errAEIllegalIndex;
  5462.                 else {
  5463.                     theDocument = DPtrFromWindowPtr(theWindowToken);
  5464.                     theHTE      = theDocument->theText;
  5465.  
  5466.                     if (desiredType == cWord) {
  5467.                         wordStart   = 0;
  5468.                         wordLength  = (**theHTE).teLength;
  5469.                         *result     = CountWords(theHTE, wordStart, wordLength);
  5470.                     }
  5471.  
  5472.                     if (desiredType == cChar)
  5473.                         *result = (**theHTE).teLength;
  5474.  
  5475.                     if (desiredType == cLine)
  5476.                         *result = CountLines(theHTE);
  5477.                 }
  5478.             }
  5479.  
  5480.         myErr = AECoerceDesc(container, typeMyText, &newDesc);
  5481.         if (newDesc.descriptorType!=typeNull) {
  5482.             GetRawDataFromDescriptor(
  5483.                 &newDesc,
  5484.                 (Ptr)&theTextToken,
  5485.                 sizeof(theTextToken),
  5486.                 &tokenSize);
  5487.  
  5488.             myErr = AEDisposeDesc(&newDesc);
  5489.  
  5490.             theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  5491.             theHTE      = theDocument->theText;
  5492.  
  5493.             if (desiredType == cWord) {
  5494.                 wordStart   = theTextToken.tokenOffset-1;
  5495.                 wordLength  = theTextToken.tokenLength;
  5496.                 *result     = CountWords(theHTE, wordStart, wordLength);
  5497.             }
  5498.  
  5499.             if (desiredType == cChar)
  5500.                 *result = theTextToken.tokenLength;
  5501.  
  5502.             if (desiredType == cLine)
  5503.                 *result    =
  5504.                     LineOfOffset(theHTE,theTextToken.tokenOffset-1) -
  5505.                     LineOfOffset(theHTE,theTextToken.tokenOffset+theTextToken.tokenLength-1)
  5506.                     +1;
  5507.         }
  5508.     }
  5509.  
  5510.     return myErr;
  5511. }    /* MyCountProc */
  5512.  
  5513. /*******************************************************************************/
  5514. /*
  5515.     Coercion Handlers - Allow AEResolve to do the hard work
  5516. */
  5517. pascal OSErr CoerceObjToAnything(
  5518.     const AEDesc *theAEDesc,
  5519.     DescType     toType,
  5520.     long         handlerRefCon,
  5521.     AEDesc       *result)
  5522. /*
  5523.     CoerceObjToAnything functions by using AEResolve to do the hard
  5524.     work.
  5525. */
  5526. {
  5527. #if !defined(powerc) && !defined(__powerc)
  5528. #pragma unused (handlerRefCon)
  5529. #endif
  5530.  
  5531.     OSErr  myErr;
  5532.     AEDesc objDesc;
  5533.  
  5534.     myErr = errAECoercionFail;
  5535.  
  5536.     result->dataHandle = nil;
  5537.     objDesc.dataHandle = nil;
  5538.  
  5539.  
  5540.     if (theAEDesc->descriptorType != typeObjectSpecifier) {
  5541.         return errAEWrongDataType;
  5542.     }
  5543.  
  5544.     /* resolve the object specifier */
  5545.     myErr = AEResolve(theAEDesc, kAEIDoMinimum, &objDesc);
  5546.  
  5547.     /* hopefully it's the right type by now, but we'll give it a nudge */
  5548.     if (myErr==noErr) {
  5549.         myErr = AECoerceDesc(&objDesc, toType, result);
  5550.         myErr = AEDisposeDesc(&objDesc);
  5551.     }
  5552.  
  5553.     if (result->descriptorType!=toType) {
  5554.         /*DebugStr('COTA - Not of requested type');*/
  5555.     }
  5556.  
  5557.     return myErr;
  5558. }    /* CoerceObjToAnything */
  5559.  
  5560. /*******************************************************************************/
  5561.  
  5562. /*----------------------------------------------------------------------------------------------*/
  5563.  
  5564. /*now for the edition manager event handling code*/
  5565.  
  5566. pascal OSErr GetHandleFromEvent(const AppleEvent *theAppleEvent, SectionHandle *sectionH)
  5567. {
  5568.     DescType ignoreType;
  5569.     Size          ignoreSize;
  5570.  
  5571.     return
  5572.         AEGetKeyPtr(
  5573.             theAppleEvent,
  5574.             keyDirectObject,
  5575.             typeSectionH,
  5576.             &ignoreType,
  5577.             (Ptr)sectionH,
  5578.             sizeof(SectionHandle),
  5579.             &ignoreSize);
  5580. } /* GetHandleFromEvent */
  5581.  
  5582. /*----------------------------------------------------------------------------------------------*/
  5583. pascal OSErr DoReadSection(const AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  5584. {
  5585. #if !defined(powerc) && !defined(__powerc)
  5586. #pragma unused (reply, refCon)
  5587. #endif
  5588.  
  5589.     OSErr         err;
  5590.     SectionHandle sectionH;
  5591.  
  5592.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5593.     if (IsRegisteredSection(sectionH)==noErr)
  5594.         ReadAnEdition(sectionH);
  5595.     return err;
  5596. } /* DoReadSection */
  5597.  
  5598. /*----------------------------------------------------------------------------------------------*/
  5599. pascal OSErr DoWriteSection(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  5600. {
  5601. #if !defined(powerc) && !defined(__powerc)
  5602. #pragma unused (reply, refCon)
  5603. #endif
  5604.  
  5605.     OSErr         err;
  5606.     SectionHandle sectionH;
  5607.  
  5608.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5609.     if (IsRegisteredSection(sectionH) == noErr)
  5610.         WriteAnEdition(sectionH);
  5611.  
  5612.     return err;
  5613. } /* DoWriteSection */
  5614.  
  5615. /*----------------------------------------------------------------------------------------------*/
  5616. pascal OSErr DoScrollSection(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  5617. {
  5618. #if !defined(powerc) && !defined(__powerc)
  5619. #pragma unused (reply, refCon)
  5620. #endif
  5621.  
  5622.     OSErr         err;
  5623.     SectionHandle sectionH;
  5624.     SectHandle    aSectHandle;
  5625.  
  5626.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5627.     /*get at the sectHandle*/
  5628.     aSectHandle = (SectHandle)GetERefCon(sectionH);
  5629.     TESetSelect((**aSectHandle).fStart, (**aSectHandle).fEnd, ((**aSectHandle).fDocument)->theText);
  5630.     ShowSelect((**aSectHandle).fDocument);
  5631.     return err;
  5632. }
  5633.  
  5634. /*----------------------------------------------------------------------------------------------*/
  5635. pascal OSErr DoCancelSection(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  5636. {
  5637. #if !defined(powerc) && !defined(__powerc)
  5638. #pragma unused (reply, refCon)
  5639. #endif
  5640.  
  5641.     OSErr         err;
  5642.     SectionHandle sectionH;
  5643.     SectHandle    aSectHandle;
  5644.  
  5645.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5646.     aSectHandle = (SectHandle)GetERefCon(sectionH);
  5647.     err = UnRegisterSection(sectionH);
  5648.     DeleteASection(aSectHandle, (**aSectHandle).fDocument);
  5649.     return noErr;
  5650. } /* DoCancelSection */
  5651.  
  5652. pascal OSErr Text2FSSpec(
  5653.     DescType type, Ptr path, Size size, 
  5654.     DescType to, long refCon, AEDesc * result)
  5655. {
  5656.     OSErr            err;
  5657.     char            file[256];
  5658.     FSSpec        spec;
  5659.     CInfoPBRec    info;
  5660.     
  5661.     if (size > 255)
  5662.         return errAECoercionFail;
  5663.         
  5664.     memcpy(file, path, size);
  5665.     file[size] = 0;
  5666.     
  5667.     if (err = Path2FSSpec(file, &spec))
  5668.         return err;
  5669.     if (err = FSpCatInfo(&spec, &info))
  5670.         return err;
  5671.     
  5672.     return AECreateDesc(typeFSS, (Ptr) &spec, sizeof(FSSpec), result);
  5673. }
  5674.  
  5675. /* -----------------------------------------------------------------------
  5676.         Name:             InitAppleEvents
  5677.         Purpose:        Initialise the AppleEvent despatch table
  5678.      -----------------------------------------------------------------------**/
  5679.  
  5680. #if !defined(powerc) && !defined(__powerc)
  5681. #pragma segment Main
  5682. #endif
  5683.  
  5684. #define noRefCon -1
  5685.  
  5686. pascal void InitAppleEvents(void)
  5687. {
  5688.     OSErr aevtErr;
  5689.  
  5690.      gBigBrother = 0;
  5691.     gCharsInBuffer = 0;
  5692.     gTypingBuffer  = (char *)NewPtr(32000);
  5693.     gTypingTargetObject.dataHandle = 0;
  5694.  
  5695.     /*set up the dispatch table for the four standard apple events*/
  5696.  
  5697.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(DoOpenApp), noRefCon, false) ;
  5698.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments,   NewAEEventHandlerProc(DoOpenDocument), noRefCon, false) ;
  5699.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments,  NewAEEventHandlerProc(DoPrintDocuments), noRefCon, false) ;
  5700.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(MyQuit), noRefCon, false) ;
  5701.  
  5702.     aevtErr = AEInstallEventHandler( MPAppSig,           kAEOpenDocuments,   NewAEEventHandlerProc(DoOpenDocument), 1, false) ;
  5703.     aevtErr = AEInstallEventHandler( MPAppSig,           'DATA',                NewAEEventHandlerProc(Relay),              0, false) ;
  5704.  
  5705.     /* set up the dispatch table for the core AppleEvents for text */
  5706.  
  5707.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEDelete, NewAEEventHandlerProc(DoDeleteEdit),noRefCon, false);
  5708.  
  5709.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAECut,    NewAEEventHandlerProc(DoCutEdit),   noRefCon, false);
  5710.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAECopy,   NewAEEventHandlerProc(DoCopyEdit),  noRefCon, false);
  5711.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAEPaste,  NewAEEventHandlerProc(DoPasteEdit), noRefCon, false);
  5712.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAESetData,NewAEEventHandlerProc(DoSetData),   noRefCon, false);
  5713.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEGetData,NewAEEventHandlerProc(DoGetData),   noRefCon, false);
  5714.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEGetDataSize,NewAEEventHandlerProc(DoGetDataSize),   noRefCon, false);
  5715.  
  5716.     aevtErr = AEInstallEventHandler( kAECoreSuite, kAECountElements,   NewAEEventHandlerProc(HandleNumberOfElements),   noRefCon, false);
  5717.     aevtErr = AEInstallEventHandler( kAECoreSuite, kAECreateElement,   NewAEEventHandlerProc(DoNewElement),   noRefCon, false);
  5718.     aevtErr = AEInstallEventHandler( kAECoreSuite, kAEDoObjectsExist,  NewAEEventHandlerProc(DoIsThereA),   noRefCon, false);
  5719.  
  5720.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEClose,  NewAEEventHandlerProc(DoCloseWindow),noRefCon, false);
  5721.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAESave,   NewAEEventHandlerProc(DoSaveWindow),noRefCon, false);
  5722.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAERevert, NewAEEventHandlerProc(DoRevertWindow),noRefCon, false);
  5723.  
  5724.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAECreatePublisher,        NewAEEventHandlerProc(HandleCreatePub), noRefCon, false);
  5725.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAEMakeObjectsVisible,     NewAEEventHandlerProc(HandleShowSelection),   noRefCon, false);
  5726.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAESelect,                     NewAEEventHandlerProc(HandleSelect),   noRefCon, false);
  5727.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAEDoScript,               NewAEEventHandlerProc(DoScript), noRefCon, false);
  5728.  
  5729.     /* Now look for recording notifications */
  5730.  
  5731.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEStartedRecording, NewAEEventHandlerProc(HandleStartRecording), noRefCon, false);
  5732.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEStoppedRecording, NewAEEventHandlerProc(HandleStopRecording), noRefCon, false);
  5733.  
  5734.     /* Now Put in the required object accessors */
  5735.  
  5736.     aevtErr = AESetObjectCallbacks(nil,NewOSLCountProc(MyCountProc),nil,nil,nil,nil,nil);
  5737.  
  5738.  
  5739.     aevtErr = AEInstallObjectAccessor(cApplication, typeNull,   NewOSLAccessorProc(ApplicationFromNullAccessor),  0,false);
  5740.     aevtErr = AEInstallObjectAccessor(cProperty,    typeNull,     NewOSLAccessorProc(PropertyFromNullAccessor),0,false);
  5741.     aevtErr = AEInstallObjectAccessor(cProperty,    typeMyAppl, NewOSLAccessorProc(PropertyFromNullAccessor),0,false);
  5742.     aevtErr = AEInstallObjectAccessor(cWindow,      typeNull,   NewOSLAccessorProc(WindowFromNullAccessor),  0,false);
  5743.     aevtErr = AEInstallObjectAccessor(cWindow,        typeMyAppl, NewOSLAccessorProc(WindowFromNullAccessor),  0,false);
  5744.     aevtErr = AEInstallObjectAccessor(cDocument,    typeNull,   NewOSLAccessorProc(WindowFromNullAccessor),  0,false);
  5745.     aevtErr = AEInstallObjectAccessor(cDocument,        typeMyAppl, NewOSLAccessorProc(WindowFromNullAccessor),  0,false);
  5746.  
  5747.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyWndw,NewOSLAccessorProc(PropertyFromWndwAccessor),0,false);
  5748.     aevtErr = AEInstallObjectAccessor(cChar,            typeMyWndw,NewOSLAccessorProc(TextElemFromWndwAccessor),0,false);
  5749.     aevtErr = AEInstallObjectAccessor(cSpot,            typeMyWndw,NewOSLAccessorProc(TextElemFromWndwAccessor),0,false);
  5750.     aevtErr = AEInstallObjectAccessor(cWord,            typeMyWndw,NewOSLAccessorProc(TextElemFromWndwAccessor),0,false);
  5751.     aevtErr = AEInstallObjectAccessor(cLine,            typeMyWndw,NewOSLAccessorProc(TextElemFromWndwAccessor),0,false);
  5752.     aevtErr = AEInstallObjectAccessor(cText,            typeMyWndw,NewOSLAccessorProc(TextElemFromWndwAccessor),0,false);
  5753.  
  5754.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyWindowProp,NewOSLAccessorProc(PropertyFromWndwPropAccessor),0,false);
  5755.     aevtErr = AEInstallObjectAccessor(cChar,            typeMyWindowProp,NewOSLAccessorProc(TextElemFromWndwPropAccessor),0,false);
  5756.     aevtErr = AEInstallObjectAccessor(cSpot,            typeMyWindowProp,NewOSLAccessorProc(TextElemFromWndwPropAccessor),0,false);
  5757.     aevtErr = AEInstallObjectAccessor(cWord,            typeMyWindowProp,NewOSLAccessorProc(TextElemFromWndwPropAccessor),0,false);
  5758.     aevtErr = AEInstallObjectAccessor(cLine,            typeMyWindowProp,NewOSLAccessorProc(TextElemFromWndwPropAccessor),0,false);
  5759.     aevtErr = AEInstallObjectAccessor(cText,            typeMyWindowProp,NewOSLAccessorProc(TextElemFromWndwPropAccessor),0,false);
  5760.  
  5761.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyText,NewOSLAccessorProc(PropertyFromTextAccessor),0,false);
  5762.     aevtErr = AEInstallObjectAccessor(cChar,            typeMyText,NewOSLAccessorProc(TextElemFromTextAccessor),0,false);
  5763.     aevtErr = AEInstallObjectAccessor(cWord,            typeMyText,NewOSLAccessorProc(TextElemFromTextAccessor),0,false);
  5764.     aevtErr = AEInstallObjectAccessor(cSpot,            typeMyText,NewOSLAccessorProc(TextElemFromTextAccessor),0,false);
  5765.     aevtErr = AEInstallObjectAccessor(cLine,            typeMyText,NewOSLAccessorProc(TextElemFromTextAccessor),0,false);
  5766.     aevtErr = AEInstallObjectAccessor(cText,            typeMyText,NewOSLAccessorProc(TextElemFromTextAccessor),0,false);
  5767.  
  5768.     aevtErr = AEInstallObjectAccessor(cMenu,            typeNull,       NewOSLAccessorProc(MenuFromNullAccessor),    0,false);
  5769.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyMenu,     NewOSLAccessorProc(PropertyFromMenuAccessor),0,false);
  5770.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyMenuItem, NewOSLAccessorProc(PropertyFromMenuItemAccessor),0,false);
  5771.     aevtErr = AEInstallObjectAccessor(cMenuItem,        typeMyMenu,     NewOSLAccessorProc(MenuItemFromMenuAccessor),0,false);
  5772.  
  5773.     /* Now the coercion handlers */
  5774.  
  5775.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyAppl,      (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5776.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyWndw,      (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5777.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyText,      (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5778.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyTextProp,  (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5779.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyWindowProp,(AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5780.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyApplProp,  (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5781.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyMenu,      (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5782.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyMenuProp,  (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5783.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyMenuItem,  (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5784.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyItemProp,  (AECoercionHandlerUPP)NewAECoerceDescProc(CoerceObjToAnything),0,true,false);
  5785.  
  5786.     aevtErr = AEInstallCoercionHandler(typeChar,typeFSS,  (AECoercionHandlerUPP)NewAECoercePtrProc(Text2FSSpec),0,false,false);
  5787.         /*now install the appropriate edition manager events*/
  5788.  
  5789.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionReadMsgID,   NewAEEventHandlerProc(DoReadSection), noRefCon, false) ;
  5790.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionWriteMsgID,  NewAEEventHandlerProc(DoWriteSection), noRefCon, false) ;
  5791.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionScrollMsgID, NewAEEventHandlerProc(DoScrollSection), noRefCon, false) ;
  5792.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionCancelMsgID, NewAEEventHandlerProc(DoCancelSection), noRefCon, false) ;
  5793. } /* InitAppleEvents */
  5794.