home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / AppleScript / Development Tools / Sample Code / 7Edit 3.1 / Sources / SVAECreate.c < prev    next >
Encoding:
Text File  |  1995-11-20  |  11.7 KB  |  442 lines  |  [TEXT/CWIE]

  1. // SVAECreate.c
  2. //
  3. // 7Edit 3.1d1. Original version by Jon Lansdell and Nigel Humphreys.
  4. // 3.1 updates by Greg Sutton.
  5. // ©Apple Computer Inc 1995, all rights reserved.
  6.  
  7. #include "SVAECreate.h"
  8.  
  9. #include "SVEditGlobals.h"
  10. #include "SVEditWindow.h"
  11. #include "SVEditAEUtils.h"
  12. #include "SVAETextUtils.h"
  13. #include "SVAppleEvents.h"
  14.  
  15. #include "SVAEAccessors.h"
  16. #include "SVAERecording.h"
  17. #include "SVAESelect.h"
  18. #include "SVAEWindowUtils.h"
  19. #include "SVAESetData.h"
  20.  
  21.  
  22. #pragma segment AppleEvent
  23.  
  24.  
  25. // ------------------------------------------------------------------------
  26. //    Name:         DoNewElement
  27. //    Purpose:    Handles the NewElement AppleEvent. Creates windows and
  28. //                text.
  29. // ------------------------------------------------------------------------
  30.  
  31. pascal OSErr    DoNewElement(const AppleEvent    *theAppleEvent,
  32.                                     AppleEvent    *reply, 
  33.                                     long        handlerRefCon)
  34. {
  35. #pragma unused (handlerRefCon)
  36.  
  37.     DescType    returnedType,
  38.                 newElemClass;
  39.     Size        actualSize;
  40.     AEDesc        dataDesc = {typeNull, NULL},
  41.                 insertHereDesc = {typeNull, NULL},
  42.                 propertyDesc = {typeNull, NULL},
  43.                 insertData = {typeNull, NULL},
  44.                 resultDesc = {typeNull, NULL};
  45.     OSErr       ignoreErr,
  46.                 err;
  47.         
  48.     err = AEGetParamPtr(theAppleEvent, keyAEObjectClass, typeType,
  49.                             &returnedType, (Ptr)&newElemClass, sizeof(newElemClass), &actualSize);
  50.     if (noErr != err) goto done;        // We have to know what object to create
  51.     
  52.         // Get optional parameters
  53.     ignoreErr = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &dataDesc);
  54.     ignoreErr = AEGetParamDesc(theAppleEvent, keyAEInsertHere, typeWildCard, &insertHereDesc);
  55.     ignoreErr = AEGetParamDesc(theAppleEvent, keyAEPropData, typeWildCard, &propertyDesc);
  56.             
  57.         // check for missing required parameters
  58.     err = GotRequiredParams(theAppleEvent);
  59.     if (noErr != err) goto done;
  60.  
  61.     switch (newElemClass)
  62.     {
  63.         case cWindow:
  64.         case cDocument:
  65.             err = CreateWindow(&dataDesc, &insertHereDesc, &propertyDesc, &resultDesc);
  66.             break;
  67.             
  68.         case cChar:
  69.         case cText:
  70.         case cWord:
  71.         case cParagraph:
  72.             err = CreateText(newElemClass, &dataDesc, &insertHereDesc, &propertyDesc, &resultDesc);
  73.             break;
  74.             
  75.         default:
  76.             err = errAEWrongDataType;
  77.     }
  78.     
  79.     err = AddResultToReply(&resultDesc, reply, err);
  80.  
  81. done:            
  82.     if (dataDesc.dataHandle) 
  83.         AEDisposeDesc(&dataDesc);
  84.     if (insertHereDesc.dataHandle) 
  85.         AEDisposeDesc(&insertHereDesc);
  86.     if (propertyDesc.dataHandle) 
  87.         AEDisposeDesc(&propertyDesc);
  88.     if (resultDesc.dataHandle) 
  89.         AEDisposeDesc(&resultDesc);
  90.         
  91.     return(err);
  92. } // DoNewElement
  93.  
  94.  
  95. OSErr    CreateWindow(AEDesc* dataDesc, AEDesc* insertHereDesc,
  96.                                                 AEDesc* propertyDesc, AEDesc* result)
  97. {
  98.     AEDesc        insertDesc = {typeNull, NULL};
  99.     DescType     insertType;
  100.     DPtr        docPtr;
  101.     WindowPtr    behindWindow;
  102.     OSErr        err;
  103.  
  104.      err = GetInsertDescFromInsertHere(insertHereDesc, &insertDesc, &insertType);
  105.     if (noErr != err) goto done;
  106.     
  107.     err = GetBehindWindow(&insertDesc, insertType, &behindWindow);
  108.     if (noErr != err) goto done;
  109.     
  110.     docPtr = NewDocument(false, behindWindow);
  111.  
  112.     if (! docPtr)
  113.     {
  114.         err = errAENoSuchObject;
  115.         goto done;
  116.     }
  117.  
  118.     if (propertyDesc->dataHandle)
  119.         err = SetWindowPropertyRecord(docPtr->theWindow, propertyDesc);
  120.     if (noErr != err) goto done;
  121.  
  122.     if (dataDesc->dataHandle)
  123.     {
  124.         err = SetWindowData(docPtr->theWindow, dataDesc);
  125.         docPtr->dirty = true;
  126.     }
  127.     else
  128.         docPtr->dirty = false;
  129.     if (noErr != err) goto done;
  130.  
  131.     ShowWindow(docPtr->theWindow);
  132.     err = MakeWindowObj(docPtr->theWindow, result);
  133.  
  134. done:
  135.     if (insertDesc.dataHandle)
  136.         AEDisposeDesc(&insertDesc);
  137.  
  138.     return(err);
  139. }
  140.  
  141. OSErr    GetBehindWindow(AEDesc* insertDesc, DescType insertType, WindowPtr* behindWindow)
  142. {
  143.     AEDesc            windowDesc = {typeNull, NULL};
  144.     WindowToken        aWindowToken;
  145.     Size            actualSize;
  146.     short            index;
  147.     OSErr            err;
  148.  
  149.     if (typeNull == insertDesc->descriptorType)
  150.     {
  151.         *behindWindow = (WindowPtr) -1L;
  152.         return(noErr);
  153.     }
  154.     
  155.     err = AECoerceDesc(insertDesc, typeMyWndw, &windowDesc);
  156.     if (noErr != err) goto done;
  157.  
  158.     GetRawDataFromDescriptor(&windowDesc, (Ptr)&aWindowToken,
  159.                                     sizeof(aWindowToken), &actualSize);
  160.  
  161.     switch (insertType)
  162.     {
  163.         case kAEBeginning:
  164.             *behindWindow = (WindowPtr) -1L;
  165.             break;
  166.     
  167.         case kAEEnd:
  168.             *behindWindow = NULL;
  169.             break;
  170.         
  171.         case kAEBefore:
  172.             index = GetNthWindowOfWindowPtr(aWindowToken.tokenWindow);
  173.             if (index > 1)
  174.                 *behindWindow = GetWindowPtrOfNthWindow(index - 1);
  175.             else
  176.                 *behindWindow = (WindowPtr) -1L;    // Stick at front because no
  177.             break;                                    // windows before that.
  178.         
  179.         case kAEAfter:
  180.             *behindWindow = aWindowToken.tokenWindow;
  181.             break;
  182.         
  183.         case kAEReplace:
  184.         default:
  185.             err = errAEEventFailed;        // We won't allow a new window to replace an existing one
  186.     }
  187.     
  188. done:
  189.     if (windowDesc.dataHandle)
  190.         (void)AEDisposeDesc(&windowDesc);
  191.  
  192.     return(err);
  193. }
  194.  
  195. OSErr    SetWindowPropertyRecord(WindowPtr theWindow, AEDesc* propertyRecord)
  196. {
  197.     WindowPropToken        aWindowPropToken;
  198.     AEDesc                dataDesc = {typeNull, NULL},
  199.                         propertyDesc = {typeNull, NULL};
  200.     AEKeyword            theAEKeyword;
  201.     long                index;
  202.     OSErr                err;
  203.     
  204.     aWindowPropToken.tokenWindowToken.tokenWindow = theWindow;
  205.                                     
  206.     err = AECountItems(propertyRecord, &index);
  207.     if (noErr != err) goto done;
  208.     
  209.             // Step through each property - creating a window property token AEDesc
  210.             // and letting SetWindowProperty() do the work.
  211.     for (; index > 0; index--)
  212.     {
  213.         err = AEGetNthDesc(propertyRecord, index, typeWildCard, &theAEKeyword, &dataDesc);
  214.         if (noErr != err) goto done;
  215.  
  216.         aWindowPropToken.tokenProperty = theAEKeyword;
  217.         err = AECreateDesc(typeMyWindowProp, (Ptr)&aWindowPropToken, 
  218.                                         sizeof(aWindowPropToken), &propertyDesc);
  219.         if (noErr != err) goto done;
  220.         
  221.         err = SetWindowProperty(&propertyDesc, &dataDesc);
  222.         if (noErr != err) goto done;
  223.         
  224.         if (dataDesc.dataHandle)
  225.             AEDisposeDesc(&dataDesc);
  226.         if (propertyDesc.dataHandle)
  227.             AEDisposeDesc(&propertyDesc);
  228.     }
  229.     
  230. done:
  231.     if (dataDesc.dataHandle)
  232.         AEDisposeDesc(&dataDesc);
  233.     if (propertyDesc.dataHandle)
  234.         AEDisposeDesc(&propertyDesc);
  235.     
  236.     return(err);
  237. }
  238.  
  239. // We'll just assume it's text and put it through as the selection.
  240.  
  241. OSErr    SetWindowData(WindowPtr theWindow, AEDesc* dataDesc)
  242. {
  243.     WindowPropToken        aWindowPropToken;
  244.     AEDesc                propertyDesc = {typeNull, NULL};
  245.     OSErr                err;
  246.     
  247.     aWindowPropToken.tokenWindowToken.tokenWindow = theWindow;
  248.     aWindowPropToken.tokenProperty = pSelection;
  249.                                     
  250.     err = AECreateDesc(typeMyWindowProp, (Ptr)&aWindowPropToken, 
  251.                                     sizeof(aWindowPropToken), &propertyDesc);
  252.     if (noErr != err) goto done;
  253.         
  254.     err = SetWindowProperty(&propertyDesc, dataDesc);
  255.  
  256. done:
  257.     if (propertyDesc.dataHandle)
  258.         AEDisposeDesc(&propertyDesc);
  259.  
  260.     return(err);
  261. }
  262.  
  263.  
  264. OSErr    CreateText(DescType textType, AEDesc* dataDesc, AEDesc* insertHereDesc,
  265.                                                 AEDesc* propertyDesc, AEDesc* result)
  266. {
  267.     AEDesc        insertDesc = {typeNull, NULL};
  268.     DescType     insertType;
  269.     TextToken    anInsertToken;
  270.     short        ignore;
  271.     OSErr        err = noErr;
  272.  
  273.      err = GetInsertDescFromInsertHere(insertHereDesc, &insertDesc, &insertType);
  274.     if (noErr != err) goto done;
  275.     
  276.     if (typeNull == insertType)        // Default to setting the selection in the front window
  277.         err = GetWindowSelection(FrontWindow(), &anInsertToken, &ignore);
  278.     else                            // Otherwise get a selection from the insertDesc
  279.         err = GetInsertToken(&insertDesc, insertType, &anInsertToken);
  280.         
  281.     if (noErr != err) goto done;
  282.     
  283.     err = CreateAtTextToken(textType, dataDesc, &anInsertToken, propertyDesc, result);
  284.  
  285. done:
  286.     if (insertDesc.dataHandle)
  287.         AEDisposeDesc(&insertDesc);
  288.  
  289.     return(err);
  290. }
  291.  
  292. // Get a TextToken for the location of where to insert the text. If the insertType is
  293. // a relative position then work this out. Otherwise just use the insertDesc.
  294.  
  295. OSErr    GetInsertToken(AEDesc* insertDesc, DescType insertType, TextToken* resultToken)
  296. {
  297.     AEDesc        textDesc = {typeNull, NULL};
  298.     TextToken    aTextToken;
  299.     Size        actualSize;
  300.     OSErr        err;
  301.  
  302.     err = AECoerceDesc(insertDesc, typeMyText, &textDesc);
  303.     if (noErr != err) goto done;
  304.  
  305.     GetRawDataFromDescriptor(&textDesc, (Ptr)&aTextToken,
  306.                                     sizeof(aTextToken), &actualSize);
  307.     resultToken->tokenWindow = aTextToken.tokenWindow;
  308.  
  309.     switch (insertType)
  310.     {
  311.         case kAEBeginning:
  312.         case kAEBefore:
  313.             resultToken->tokenOffset = aTextToken.tokenOffset;
  314.             resultToken->tokenLength = 0;
  315.             break;
  316.     
  317.         case kAEEnd:
  318.         case kAEAfter:
  319.             resultToken->tokenOffset = aTextToken.tokenOffset + aTextToken.tokenLength;
  320.             resultToken->tokenLength = 0;
  321.             break;
  322.         
  323.         case kAEReplace:
  324.         default:            // default is probably some text token to replace
  325.                             // e.g make new word at middle word of document 1 with data "Iris"
  326.                             // It has been coerced to text so it's okay
  327.             resultToken->tokenOffset = aTextToken.tokenOffset;
  328.             resultToken->tokenLength = aTextToken.tokenLength;
  329.             break;
  330.     }
  331.  
  332. done:
  333.     if (textDesc.dataHandle)
  334.         (void)AEDisposeDesc(&textDesc);
  335.     
  336.     return(err);
  337. }
  338.  
  339. // Create text using the dataDesc (which could be text, styled text, etc…) at the
  340. // the location held in the TextToken.
  341. // Properties in the propertyDesc will be applied to the new text.
  342. // Returns an object specifier to the text.
  343.  
  344. OSErr       CreateAtTextToken(DescType textType, const AEDesc* dataDesc, TextToken* theToken,
  345.                                                     AEDesc* propertyDesc, AEDesc* result)
  346. {
  347. #pragma unused(textType)
  348.  
  349.     DPtr        docPtr;
  350.     TextToken    aSelectionToken;
  351.     short        oldLength;
  352.     OSErr        err;
  353.  
  354.     docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
  355.     
  356.     if (! docPtr)
  357.         return(errAENoSuchObject);
  358.  
  359.             // Copy the current selection - so we can restore it after
  360.     err = GetWindowSelection(theToken->tokenWindow, &aSelectionToken, &oldLength);
  361.     if (noErr != err) goto done;
  362.  
  363.             // Set the selection we want to insert the new text into
  364.     err = SelectTextToken(theToken);
  365.     if (noErr != err) goto done;
  366.  
  367.     err = PutStyledTextFromDescIntoTEHandle(dataDesc, docPtr->theText);
  368.     if (noErr != err) goto done;
  369.     
  370.             // Update the selection and get the length of the insertion
  371.     err = UpdateSelectionToken(theToken, &aSelectionToken, oldLength,
  372.                                                         &theToken->tokenLength);
  373.     if (noErr != err) goto done;
  374.     
  375.     // Need to check on token type in here and make what user wanted
  376.     // e.g. make sure a word is a word.
  377.     // Would have to remember to balance token for any chages to TEHandle.
  378.  
  379.     if (propertyDesc->dataHandle)
  380.     {                                    // I doubt we'll handle setting the text property
  381.                                         // or anything that changes the token length… oh well
  382.         err = SetTextPropertyRecord(theToken, propertyDesc);
  383.         if (noErr != err) goto done;
  384.     }
  385.             // Make the returned object
  386.     err = MakeTextObjFromToken(theToken, result);
  387.     
  388. done:
  389.     return(err);
  390. }
  391.  
  392.  
  393. // Take a TextToken and apply the properties in the propertyRecord descriptor
  394. // to the text.
  395. // e.g. make new word at beginning of document 1 with data "Bert" ¬
  396. //                                with properties {size:32, font:"Courier"}
  397. // The with properties part is the property record.
  398.  
  399. OSErr    SetTextPropertyRecord(TextToken* aTextToken, AEDesc* propertyRecord)
  400. {
  401.     TextPropToken        aTextPropToken;
  402.     AEDesc                dataDesc = {typeNull, NULL},
  403.                         propertyDesc = {typeNull, NULL};
  404.     AEKeyword            theAEKeyword;
  405.     long                index;
  406.     OSErr                err;
  407.     
  408.     aTextPropToken.tokenTextToken = *aTextToken;
  409.                                     
  410.     err = AECountItems(propertyRecord, &index);
  411.     if (noErr != err) goto done;
  412.     
  413.             // Step through each property - creating a window property token AEDesc
  414.             // and letting SetWindowProperty() do the work.
  415.     for (; index > 0; index--)
  416.     {
  417.         err = AEGetNthDesc(propertyRecord, index, typeWildCard, &theAEKeyword, &dataDesc);
  418.         if (noErr != err) goto done;
  419.  
  420.         aTextPropToken.tokenProperty = theAEKeyword;
  421.         err = AECreateDesc(typeMyTextProp, (Ptr)&aTextPropToken, 
  422.                                         sizeof(aTextPropToken), &propertyDesc);
  423.         if (noErr != err) goto done;
  424.         
  425.         err = SetTextProperty(&propertyDesc, &dataDesc);
  426.         if (noErr != err) goto done;
  427.         
  428.         if (dataDesc.dataHandle)
  429.             AEDisposeDesc(&dataDesc);
  430.         if (propertyDesc.dataHandle)
  431.             AEDisposeDesc(&propertyDesc);
  432.     }
  433.     
  434. done:
  435.     if (dataDesc.dataHandle)
  436.         AEDisposeDesc(&dataDesc);
  437.     if (propertyDesc.dataHandle)
  438.         AEDisposeDesc(&propertyDesc);
  439.     
  440.     return(err);
  441. }
  442.