home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Pascal / Libraries / WASTE 1.1a4 / Demo Source / WEDemoScripting.p < prev    next >
Encoding:
Text File  |  1994-10-30  |  8.7 KB  |  313 lines  |  [TEXT/PJMM]

  1. unit DemoScripting;
  2.  
  3. { WASTE DEMO PROJECT: }
  4. { Minimal Scripting Support: }
  5. { service "get data" and "set data" events }
  6. { in which the object descriptor is "contents of selection" }
  7.  
  8. { The code in this unit is partly based on public domain code written by: }
  9. { Ed Lai, Apple Computer Inc. }
  10.  
  11. { Copyright © 1993-1994 Merzwaren }
  12. { All Rights Reserved }
  13.  
  14. interface
  15.     uses
  16.         DemoIntf;
  17.  
  18.     function InstallCoreHandlers: OSErr;
  19.  
  20. implementation
  21.     uses
  22.         AEObjects, AERegistry;
  23.  
  24.     const
  25.  
  26.         kMaxPropLevel = 2;
  27.  
  28. { the following constants should be defined in AEObjects.p or AERegistry.p ??? }
  29.  
  30.         cProperty = 'prop';
  31.         pContents = 'pcnt';
  32.  
  33.     type
  34.  
  35.         PropArray = array[1..kMaxPropLevel] of DescType;
  36.  
  37.     procedure InitDesc (var desc: AEDesc);
  38.     begin
  39.         desc.descriptorType := typeNull;
  40.         desc.dataHandle := nil;
  41.     end;  { InitDesc }
  42.  
  43.     function PropertyOf (var spec: AERecord;
  44.                                     var propLevel: Integer;
  45.                                     var properties: PropArray): Boolean;
  46.         var
  47.             objSpec: AERecord;
  48.             theType: DescType;
  49.             actualType: DescType;
  50.             actualSize: LongInt;
  51.             key: AEKeyword;
  52.     begin
  53.         PropertyOf := false;            { we don't know this is a property yet }
  54.         InitDesc(objSpec);
  55.  
  56. { if spec is an Apple event (propLevel = 0), use its direct object }
  57. { otherwise use 'from' parameter of object specifier }
  58.         if (propLevel = 0) then
  59.             key := keyDirectObject
  60.         else
  61.             key := keyAEContainer;
  62.  
  63. { extract object specifier }
  64.         if (AEGetKeyDesc(spec, key, typeAERecord, objSpec) = noErr) then
  65.  
  66. { is this a property? -- get desired class }
  67.             if (AEGetKeyPtr(objSpec, keyAEDesiredClass, typeType, actualType, @theType, SizeOf(theType), actualSize) = noErr) then
  68.                 if (theType = cProperty) then
  69.  
  70. { this is redundunt, but won't hurt to make sure }
  71.                     if (AEGetKeyPtr(objSpec, keyAEKeyForm, typeEnumerated, actualType, @theType, SizeOf(theType), actualSize) = noErr) then
  72.                         if (theType = formPropertyID) then
  73.  
  74. { which property? }
  75.                             if (AEGetKeyPtr(objSpec, keyAEKeyData, typeType, actualType, @theType, SizeOf(theType), actualSize) = noErr) then
  76.                                 begin
  77.  
  78. { we now know what property }
  79.                                     propLevel := propLevel + 1;
  80.                                     properties[propLevel] := theType;
  81.  
  82. { property of what? }
  83.                                     if (AESizeOfKeyDesc(objSpec, keyAEContainer, actualType, actualSize) = noErr) then
  84.                                         if (actualType = typeNull) then
  85.  
  86. { property of application, we are done }
  87.                                             PropertyOf := true
  88.  
  89.                                         else if (actualType = typeObjectSpecifier) and (propLevel < kMaxPropLevel) then
  90.  
  91. { property of another object specifier, do a recursive call if we haven't reached max level }
  92.                                             PropertyOf := PropertyOf(objSpec, propLevel, properties);
  93.                                 end;
  94.  
  95.         if (AEDisposeDesc(objSpec) <> noErr) then
  96.             ;
  97.  
  98.     end;  { PropertyOf }
  99.  
  100.     function HandleGetData (var ae, reply: AppleEvent;
  101.                                     refCon: LongInt): OSErr;
  102.         var
  103.             propLevel: Integer;
  104.             properties: PropArray;
  105.             window: WindowPtr;
  106.             selStart, selEnd: LongInt;
  107.             textDesc, stylesDesc, recordDesc, styledTextDesc: AEDesc;
  108.             requestedType, actualType: DescType;
  109.             actualSize: Size;
  110.  
  111.         procedure CleanUp;
  112.         begin
  113.             if (AEDisposeDesc(textDesc) <> noErr) then
  114.                 ;
  115.             if (AEDisposeDesc(stylesDesc) <> noErr) then
  116.                 ;
  117.             if (AEDisposeDesc(recordDesc) <> noErr) then
  118.                 ;
  119.             if (AEDisposeDesc(styledTextDesc) <> noErr) then
  120.                 ;
  121.         end;  { CleanUp }
  122.  
  123.         procedure CheckErr (err: OSErr);
  124.         begin
  125.             if (err <> noErr) then
  126.                 begin
  127.                     HandleGetData := err;
  128.                     CleanUp;
  129.                     Exit(HandleGetData);
  130.                 end;
  131.         end;  { CheckErr }
  132.  
  133.     begin
  134.         HandleGetData := noErr;
  135.         InitDesc(textDesc);
  136.         InitDesc(stylesDesc);
  137.         InitDesc(recordDesc);
  138.         InitDesc(styledTextDesc);
  139.  
  140. { the only Get Data phrase we support is "Get the Contents of the Selection" }
  141.         propLevel := 0;                     { 0 means we are passing in an Apple Event }
  142.         if PropertyOf(ae, propLevel, properties) & ((propLevel = 2) and (properties[1] = pContents) and (properties[2] = pSelection)) then
  143.             begin
  144.  
  145. { make sure there is a window in front }
  146.                 window := FrontWindow;
  147.                 if (window = nil) then
  148.                     CheckErr(errAENoSuchObject);
  149.  
  150. { allocate a handle to hold a temporary copy of the selection text }
  151.                 CheckErr(NewHandleTemp(0, textDesc.dataHandle));
  152.                 textDesc.descriptorType := typeChar;
  153.  
  154. { extract the keyAERequestedType parameter, if present }
  155.                 if (AEGetParamPtr(ae, keyAERequestedType, typeType, actualType, @requestedType, SizeOf(requestedType), actualSize) = noErr) then
  156.                     if (requestedType = typeStyledText) then
  157.                         begin
  158.  
  159. { our client wants styled text: }
  160. { allocate a handle to hold a temporary copy of the selection text }
  161.                             CheckErr(NewHandleTemp(0, stylesDesc.dataHandle));
  162.                             stylesDesc.descriptorType := typeScrapStyles;
  163.                         end;
  164.  
  165. { make a copy of the selection in the frontmost window }
  166.                 WEGetSelection(selStart, selEnd, DocumentPeek(window)^.hWE);
  167.                 CheckErr(WECopyRange(selStart, selEnd, textDesc.dataHandle, StScrpHandle(stylesDesc.dataHandle), nil, DocumentPeek(window)^.hWE));
  168.  
  169. { fill in the reply Apple event }
  170.                 if (stylesDesc.dataHandle = nil) then
  171.  
  172. { UNSTYLED TEXT }
  173. { put the text descriptor into the reply Apple event }
  174.                     CheckErr(AEPutParamDesc(reply, keyDirectObject, textDesc))
  175.  
  176.                 else
  177.                     begin
  178.  
  179. { STYLED TEXT }
  180. { create an Apple event record to hold text + styles }
  181.                         CheckErr(AECreateList(nil, 0, true, recordDesc));
  182.  
  183. { add the text descriptor to the record }
  184.                         CheckErr(AEPutKeyDesc(recordDesc, keyAEText, textDesc));
  185.  
  186. { add the styles descriptor to the record }
  187.                         CheckErr(AEPutKeyDesc(recordDesc, keyAEStyles, stylesDesc));
  188.  
  189. { coerce the record into a styled text descriptor }
  190.                         CheckErr(AECoerceDesc(recordDesc, typeStyledText, styledTextDesc));
  191.  
  192. { put the styled text descriptor into the reply Apple event }
  193.                         CheckErr(AEPutParamDesc(reply, keyDirectObject, styledTextDesc));
  194.  
  195.                     end;
  196.             end
  197.         else
  198.             CheckErr(errAENoSuchObject);
  199.  
  200. { clean up }
  201.         CleanUp;
  202.  
  203.     end;  { HandleGetData }
  204.  
  205.     function HandleSetData (var ae, reply: AppleEvent;
  206.                                     refCon: LongInt): OSErr;
  207.         var
  208.             propLevel: Integer;
  209.             properties: PropArray;
  210.             window: WindowPtr;
  211.             textDesc, stylesDesc, recordDesc, styledTextDesc: AEDesc;
  212.             dataType: DescType;
  213.             dataSize: Size;
  214.  
  215.         procedure CleanUp;
  216.         begin
  217.             if (AEDisposeDesc(textDesc) <> noErr) then
  218.                 ;
  219.             if (AEDisposeDesc(stylesDesc) <> noErr) then
  220.                 ;
  221.             if (AEDisposeDesc(recordDesc) <> noErr) then
  222.                 ;
  223.             if (AEDisposeDesc(styledTextDesc) <> noErr) then
  224.                 ;
  225.         end;  { CleanUp }
  226.  
  227.         procedure CheckErr (err: OSErr);
  228.         begin
  229.             if (err <> noErr) then
  230.                 begin
  231.                     HandleSetData := err;
  232.                     CleanUp;
  233.                     Exit(HandleSetData);
  234.                 end;
  235.         end;  { CheckErr }
  236.  
  237.     begin
  238.         HandleSetData := noErr;
  239.         InitDesc(textDesc);
  240.         InitDesc(stylesDesc);
  241.         InitDesc(recordDesc);
  242.         InitDesc(styledTextDesc);
  243.  
  244. { the only Set Data phrase we support is "Set the Contents of the Selection" }
  245.         propLevel := 0;                 { 0 means we are passing in an Apple Event }
  246.         if PropertyOf(ae, propLevel, properties) & ((propLevel = 2) and (properties[1] = pContents) and (properties[2] = pSelection)) then
  247.             begin
  248.  
  249. { make sure there is a window in front }
  250.                 window := FrontWindow;
  251.                 if (window = nil) then
  252.                     CheckErr(errAENoSuchObject);
  253.  
  254. { we expect the data parameter to be either TEXT or STXT }
  255.                 CheckErr(AESizeOfParam(ae, keyAEData, dataType, dataSize));
  256.                 if (dataType = typeStyledText) then
  257.                     begin
  258.  
  259. { STYLED TEXT }
  260. { extract styled text data from the Apple event }
  261.                         CheckErr(AEGetParamDesc(ae, keyAEData, typeStyledText, styledTextDesc));
  262.  
  263. { coerce the styled text descriptor to an Apple event record }
  264.                         CheckErr(AECoerceDesc(styledTextDesc, typeAERecord, recordDesc));
  265.  
  266. { extract text + styles from the record descriptor }
  267.                         CheckErr(AEGetKeyDesc(recordDesc, keyAEText, typeChar, textDesc));
  268.                         CheckErr(AEGetKeyDesc(recordDesc, keyAEStyles, typeScrapStyles, stylesDesc));
  269.                     end
  270.                 else
  271.  
  272. { UNSTYLED TEXT }
  273. { extract text data from the Apple event }
  274.                     CheckErr(AEGetParamDesc(ae, keyAEData, typeChar, textDesc));
  275.  
  276. { insert the text }
  277.                 HLock(textDesc.dataHandle);
  278.                 CheckErr(WEInsert(textDesc.dataHandle^, GetHandleSize(textDesc.dataHandle), StScrpHandle(stylesDesc.dataHandle), nil, DocumentPeek(window)^.hWE));
  279.                 HUnlock(textDesc.dataHandle);
  280.  
  281.             end
  282.         else
  283.             CheckErr(errAENoSuchObject);
  284.  
  285. { clean up }
  286.         CleanUp;
  287.  
  288.     end;  { HandleSetData }
  289.  
  290. { THINK Pascal compiler directive: put the following code in the "Init" segment }
  291. {$S Init}
  292.  
  293.     function InstallCoreHandlers: OSErr;
  294.  
  295.         procedure CheckErr (err: OSErr);
  296.         begin
  297.             if (err <> noErr) then
  298.                 begin
  299.                     InstallCoreHandlers := err;
  300.                     Exit(InstallCoreHandlers);
  301.                 end;
  302.         end;  { CheckErr }
  303.  
  304.     begin
  305.         InstallCoreHandlers := noErr;
  306.  
  307. { install Apple event handlers for the Required Suite }
  308.         CheckErr(AEInstallEventHandler(kAECoreSuite, kAEGetData, @HandleGetData, 0, false));
  309.         CheckErr(AEInstallEventHandler(kAECoreSuite, kAESetData, @HandleSetData, 0, false));
  310.  
  311.     end;  { InstallCoreHandlers }
  312.  
  313. end.