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