home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Button / Sources / Actions.cpp next >
Encoding:
Text File  |  1996-09-17  |  16.1 KB  |  552 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Actions.h
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Author:                Jim Lloyd
  7. //
  8. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #ifndef ACTIONS_H
  13. #include "Actions.h"
  14. #endif
  15.  
  16. #ifndef DEFINES_K
  17. #include "Defines.k"
  18. #endif
  19.  
  20. #ifndef BINDING_K
  21. #include "Binding.k"
  22. #endif
  23.  
  24. #ifndef ENVIRONS_H
  25. #include "Environs.h"
  26. #endif
  27.  
  28. #ifndef FWKIND_H
  29. #include "FWKind.h"
  30. #endif
  31.  
  32. #ifndef FWUTIL_H
  33. #include "FWUtil.h"
  34. #endif
  35.  
  36. #ifndef FWSUUTIL_H
  37. #include "FWSUUtil.h"
  38. #endif
  39.  
  40. #ifndef FWALERT_H
  41. #include "FWAlert.h"
  42. #endif
  43.  
  44. #ifndef FWPART_H
  45. #include "FWPart.h"
  46. #endif
  47.  
  48. #ifndef FWBARRAY_H
  49. #include "FWBArray.h"
  50. #endif
  51.  
  52. #ifndef FWMEMMGR_H
  53. #include "FWMemMgr.h"
  54. #endif
  55.  
  56. #ifndef FWMEMHLP_H
  57. #include "FWMemHlp.h"
  58. #endif
  59.  
  60. #ifndef FWMEMHLP_H
  61. #include "FWMemHlp.h"
  62. #endif
  63.  
  64. #ifndef FWFILESP_H
  65. #include "FWFileSp.h"
  66. #endif
  67.  
  68. #ifndef FWRESOUR_H
  69. #include "FWResour.h"
  70. #endif
  71.  
  72. #ifndef FWACQUIR_H
  73. #include "FWAcquir.h"
  74. #endif
  75.  
  76. #ifndef FWSUSINK_H
  77. #include "FWSUSink.h"
  78. #endif
  79.  
  80. #ifndef FWSTRING_H
  81. #include "FWString.h"
  82. #endif
  83.  
  84. #ifndef FWODTYPS_H
  85. #include "FWODTyps.h"
  86. #endif
  87.  
  88. #ifndef SOM_Module_OpenDoc_StdProps_defined
  89. #include <StdProps.xh>
  90. #endif
  91.  
  92. #ifndef SOM_ODStorageUnit_xh
  93. #include <StorageU.xh>
  94. #endif
  95.  
  96. #ifndef SOM_ODTranslation_xh
  97. #include <Translt.xh>
  98. #endif
  99.  
  100. #ifndef SOM_ODSession_xh
  101. #include <ODSessn.xh>
  102. #endif
  103.  
  104. #ifndef SOM_ODDragItemIterator_xh
  105. #include <DgItmIt.xh>
  106. #endif
  107.  
  108. // ----- Macintosh Includes -----
  109.  
  110. #if defined(FW_BUILD_MAC) && !defined(__DRAG__)
  111. #include <Drag.h>
  112. #endif
  113.  
  114. #if defined(FW_BUILD_MAC) && !defined(__SOUND__)
  115. #include <Sound.h>
  116. #endif
  117.  
  118. //========================================================================================
  119. //    Static Allocations
  120. //========================================================================================
  121.  
  122. ComponentInstance CScriptAction::fgComponentInstance;
  123.  
  124. //========================================================================================
  125. //    Runtime information
  126. //========================================================================================
  127.  
  128. #ifdef FW_BUILD_MAC
  129. #pragma segment odfbutton
  130. #endif
  131.  
  132. //========================================================================================
  133. //    class CAction
  134. //========================================================================================
  135.  
  136. FW_DEFINE_CLASS_M0(CAction)
  137.  
  138. //----------------------------------------------------------------------------------------
  139. //    CAction::CAction
  140. //----------------------------------------------------------------------------------------
  141.  
  142. CAction::CAction(short actionType) :
  143.     fActionType(actionType)
  144. {
  145. }
  146.  
  147. //----------------------------------------------------------------------------------------
  148. //    CAction::~CAction
  149. //----------------------------------------------------------------------------------------
  150.  
  151. CAction::~CAction()
  152. {
  153. }
  154.  
  155. //========================================================================================
  156. //    class CSoundAction
  157. //========================================================================================
  158.  
  159. FW_DEFINE_CLASS_M1(CSoundAction, CAction)
  160.  
  161. const FW_ClassTypeConstant LSoundAction = FW_TYPE_CONSTANT('S','N','D','A');
  162. FW_REGISTER_ARCHIVABLE_CLASS(LSoundAction, CSoundAction, CSoundAction::Read, 0, 0, CSoundAction::Write)
  163.  
  164. //----------------------------------------------------------------------------------------
  165. //    CSoundAction::CSoundAction
  166. //----------------------------------------------------------------------------------------
  167.  
  168. CSoundAction::CSoundAction(Environment* ev, ODStorageUnit* storage, FW_CKind* kind):
  169.     CAction(kSound),
  170.     fSoundHandle(0)
  171. {
  172.     Internalize(ev, storage, kind);
  173. }
  174.  
  175. //----------------------------------------------------------------------------------------
  176. //    CSoundAction::CSoundAction
  177. //----------------------------------------------------------------------------------------
  178.  
  179. CSoundAction::CSoundAction(Environment* ev, FW_CReadableStream& stream) :
  180.     CAction(kSound),
  181.     fSoundHandle(0)
  182. {
  183.     InternalizeFromStream(ev, stream);
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. //    CSoundAction::~CSoundAction
  188. //----------------------------------------------------------------------------------------
  189.  
  190. CSoundAction::~CSoundAction()
  191. {
  192.     if (fSoundHandle)
  193.         ::DisposeHandle(fSoundHandle);
  194. }
  195.  
  196. //----------------------------------------------------------------------------------------
  197. //    CSoundAction::Internalize
  198. //----------------------------------------------------------------------------------------
  199.  
  200. void CSoundAction::Internalize(Environment* ev, ODStorageUnit* storage, FW_CKind* kind)
  201. {
  202.     if (kind->IsEqual(ev, 'snd ', kODPlatformDataType))
  203.     {
  204.         // Mac 'snd ' in Scrap
  205.         FW_PStorageUnitSink suSink(ev, storage, kODPropContents, kind->GetType(ev));
  206.         FW_CReadableStream stream(suSink);
  207.         InternalizeFromStream(ev, stream);
  208.     }
  209.     else if (kind->IsEqual(ev, 'sfil', kODPlatformFileType))    
  210.     {
  211.         InternalizeSoundFile(ev, storage);
  212.     }
  213. }
  214.  
  215. //----------------------------------------------------------------------------------------
  216. //    CSoundAction::InternalizeFromStream
  217. //----------------------------------------------------------------------------------------
  218.  
  219. void CSoundAction::InternalizeFromStream(Environment* ev, FW_CReadableStream& stream)
  220. {
  221.     unsigned long size = stream.GetSink()->GetReadableBytes(ev);
  222.     
  223.     if (size > 0)
  224.     {
  225.         FW_CAcquireTemporarySystemHandle handle(size);
  226.         stream.Read(handle.GetPointer(), size);
  227.         fSoundHandle = handle.GetPlatformHandle();
  228.         handle.Orphan();
  229.     }
  230. }
  231.  
  232. //----------------------------------------------------------------------------------------
  233. //    CSoundAction::InternalizeSoundFile
  234. //----------------------------------------------------------------------------------------
  235.  
  236. void CSoundAction::InternalizeSoundFile(Environment* ev, ODStorageUnit* storage)
  237. {
  238.     HFSFlavor hfsInfo;
  239.     if (FW_MacSUReadHFSFlavor(ev, storage, kODPropContents, hfsInfo))
  240.     {
  241.         // Create platform independent file spec
  242.         FW_PFileSpecification fileSpec(ev, hfsInfo.fileSpec);
  243.         
  244.         // Open the resource file
  245.         FW_PResourceFile resourceFile(ev, fileSpec);
  246.  
  247.         // Get any (i.e the first) sound resource
  248.         const FW_ResourceType resourceType = 'snd ';
  249.         const FW_ResourceID resourceID = 1;
  250.         Handle sound = ::Get1IndResource(resourceType, resourceID);
  251.                     
  252.         if (sound != NULL)
  253.         {
  254.             // if succeeded, detach the handle and keep it
  255.             ::DetachResource(sound);
  256.             fSoundHandle = sound;
  257.         }
  258.         else
  259.         {
  260.             // No sound resource loaded, throw an exception
  261.             FW_FailOnError(::ResError());
  262.             FW_Failure(resNotFound);
  263.         }
  264.     }
  265. }
  266.  
  267. //----------------------------------------------------------------------------------------
  268. //    CSoundAction::Externalize
  269. //----------------------------------------------------------------------------------------
  270.  
  271. void CSoundAction::Externalize(Environment* ev, ODStorageUnit* storage, FW_CKind* kind)
  272. {
  273.     if (fSoundHandle != NULL)
  274.     {
  275.         FW_PStorageUnitSink suSink(ev, storage, kODPropContents, kind->GetType(ev));
  276.         FW_CWritableStream stream(suSink);
  277.         ExternalizeToStream(ev, stream);
  278.         FW_SUDeleteEndOfFocusedValue(ev, storage);
  279.     }
  280.     else
  281.     {
  282.         FW_SURemoveValue(ev, storage, kODPropContents, kind->GetType(ev));
  283.     }
  284. }
  285.  
  286. //----------------------------------------------------------------------------------------
  287. //    CSoundAction::ExternalizeToStream
  288. //----------------------------------------------------------------------------------------
  289.  
  290. void CSoundAction::ExternalizeToStream(Environment* ev, FW_CWritableStream& stream)
  291. {
  292. FW_UNUSED(ev);
  293.     if (fSoundHandle != NULL)
  294.     {
  295.         FW_CAcquireLockedSystemHandle lock(fSoundHandle);
  296.         stream.Write(*fSoundHandle, FW_CMemoryManager::GetSystemHandleSize(fSoundHandle));
  297.     }
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. // CSoundAction::DoIt
  302. //----------------------------------------------------------------------------------------
  303.  
  304. void CSoundAction::DoIt()
  305. {
  306.     if (fSoundHandle != NULL)
  307.     {
  308.         FW_CAcquireLockedSystemHandle lock(fSoundHandle);
  309.         ::SndPlay(NULL, (SndListHandle)fSoundHandle, TRUE);
  310.     }
  311. }
  312.  
  313. //----------------------------------------------------------------------------------------
  314. // CSoundAction::Read
  315. //----------------------------------------------------------------------------------------
  316.  
  317. void* CSoundAction::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  318. {
  319. FW_UNUSED(type);
  320.     FW_SOMEnvironment ev;
  321.     return new CSoundAction(ev, stream);
  322. }
  323.  
  324. //----------------------------------------------------------------------------------------
  325. // CSoundAction::Write
  326. //----------------------------------------------------------------------------------------
  327.  
  328. void CSoundAction::Write(FW_CWritableStream& stream, FW_ClassTypeConstant type, const void *object)
  329. {
  330. FW_UNUSED(type);
  331.     FW_SOMEnvironment ev;
  332.     CSoundAction* action = (CSoundAction*) object;
  333.     action->ExternalizeToStream(ev, stream);
  334. }
  335.  
  336. //========================================================================================
  337. //    class CScriptAction
  338. //========================================================================================
  339.  
  340. FW_DEFINE_CLASS_M1(CScriptAction, CAction)
  341.  
  342. const FW_ClassTypeConstant LScriptAction = FW_TYPE_CONSTANT('S','C','R','A');
  343. FW_REGISTER_ARCHIVABLE_CLASS(LScriptAction, CScriptAction, CScriptAction::Read, 0, 0, CScriptAction::Write)
  344.  
  345. //----------------------------------------------------------------------------------------
  346. //    CScriptAction::CScriptAction
  347. //----------------------------------------------------------------------------------------
  348.  
  349. CScriptAction::CScriptAction(Environment* ev, ODStorageUnit* storage, FW_CKind* kind) :
  350.     CAction(kScript),
  351.     fScriptHandle(0)
  352. {
  353.     Internalize(ev, storage, kind);
  354. }
  355.  
  356. //----------------------------------------------------------------------------------------
  357. //    CScriptAction::CScriptAction
  358. //----------------------------------------------------------------------------------------
  359.  
  360. CScriptAction::CScriptAction(Environment* ev, FW_CReadableStream& stream) :
  361.     CAction(kScript),
  362.     fScriptHandle(0)
  363. {
  364.     InternalizeFromStream(ev, stream);
  365. }
  366.  
  367. //----------------------------------------------------------------------------------------
  368. //    CScriptAction::~CScriptAction
  369. //----------------------------------------------------------------------------------------
  370.  
  371. CScriptAction::~CScriptAction()
  372. {
  373.     if (fScriptHandle)
  374.         ::DisposeHandle(fScriptHandle);
  375.     ReleaseScriptingComponent();
  376. }
  377.  
  378. //----------------------------------------------------------------------------------------
  379. //    CScriptAction::Internalize
  380. //----------------------------------------------------------------------------------------
  381.  
  382. void CScriptAction::Internalize(Environment* ev, ODStorageUnit* storage, FW_CKind* kind)
  383. {
  384.     if (kind->IsEqual(ev, 'scpt', kODPlatformDataType))
  385.     {
  386.         // 'scpt' on Scrap
  387.         FW_PStorageUnitSink suSink(ev, storage, kODPropContents, kind->GetType(ev));
  388.         FW_CReadableStream stream(suSink);
  389.         InternalizeFromStream(ev, stream);
  390.     }
  391.     else if (kind->IsEqual(ev, 'osas', kODPlatformFileType))    // compiled script file
  392.     {
  393.         InternalizeScriptFile(ev, storage);
  394.     }
  395. }
  396.  
  397. //----------------------------------------------------------------------------------------
  398. //    CScriptAction::InternalizeFromStream
  399. //----------------------------------------------------------------------------------------
  400.  
  401. void CScriptAction::InternalizeFromStream(Environment* ev, FW_CReadableStream& stream)
  402. {
  403.     unsigned long size = stream.GetSink()->GetReadableBytes(ev);
  404.     if (size > 0)
  405.     {
  406.         FW_CAcquireTemporarySystemHandle handle(size);
  407.         stream.Read(handle.GetPointer(), size);
  408.         fScriptHandle = handle.GetPlatformHandle();
  409.         handle.Orphan();
  410.     }
  411. }
  412.  
  413. //----------------------------------------------------------------------------------------
  414. //    CScriptAction::InternalizeScriptFile
  415. //----------------------------------------------------------------------------------------
  416.  
  417. void CScriptAction::InternalizeScriptFile(Environment* ev, ODStorageUnit* storage)
  418. {
  419.     HFSFlavor hfsInfo;
  420.     if (FW_MacSUReadHFSFlavor(ev, storage, kODPropContents, hfsInfo))
  421.     {        
  422.         // Make the file specification
  423.         FW_PFileSpecification fileSpec(ev, hfsInfo.fileSpec);
  424.         
  425.         // Acquire an opened resource file, 
  426.         // will be closed automatically
  427.         FW_PResourceFile resourceFile(ev, fileSpec);
  428.         
  429.         // Acquire an opened resource, 
  430.         // will be released automatically
  431.         FW_PResource resource(ev, resourceFile, 128, 'scpt');
  432.         FW_CAcquireResourceData lockedResource(ev, resource);
  433.         
  434.         // Copy the resource data into a new handle
  435.         FW_CAcquireTemporarySystemHandle lockedHandle(lockedResource.GetSize());
  436.         FW_CMemoryManager::CopyMemory(lockedResource.GetData(), lockedHandle.GetPointer(), lockedResource.GetSize());
  437.         fScriptHandle = lockedHandle.GetPlatformHandle();
  438.         lockedHandle.Orphan();
  439.     }
  440. }
  441.  
  442. //----------------------------------------------------------------------------------------
  443. //    CScriptAction::Externalize
  444. //----------------------------------------------------------------------------------------
  445.  
  446. void CScriptAction::Externalize(Environment* ev, ODStorageUnit* storage, FW_CKind* kind)
  447. {
  448.     if (fScriptHandle != NULL)
  449.     {    
  450.         FW_PStorageUnitSink suSink(ev, storage, kODPropContents, kind->GetType(ev));
  451.         FW_CWritableStream stream(suSink);
  452.         ExternalizeToStream(ev, stream);
  453.         FW_SUDeleteEndOfFocusedValue(ev, storage);
  454.     }
  455.     else
  456.     {
  457.         FW_SURemoveValue(ev, storage, kODPropContents, kind->GetType(ev));
  458.     }
  459. }
  460.  
  461. //----------------------------------------------------------------------------------------
  462. //    CScriptAction::ExternalizeToStream
  463. //----------------------------------------------------------------------------------------
  464.  
  465. void CScriptAction::ExternalizeToStream(Environment* ev, FW_CWritableStream& stream)
  466. {
  467. FW_UNUSED(ev);
  468.     if (fScriptHandle != NULL)
  469.     {
  470.         FW_CAcquireLockedSystemHandle lock(fScriptHandle);
  471.         stream.Write(*fScriptHandle, FW_CMemoryManager::GetSystemHandleSize(fScriptHandle));
  472.     }
  473. }
  474.  
  475. //----------------------------------------------------------------------------------------
  476. //    LoadAndExecuteScript
  477. //----------------------------------------------------------------------------------------
  478. // This function was lifted almost verbatim from
  479. // IM:IAC, page 10-16. (Actually, I used MPTA, but it says 
  480. // the code is on the above page)
  481.  
  482. void CScriptAction::LoadAndExecuteScript(Handle scriptData)
  483. {
  484.     AEDesc scriptDesc;
  485.     OSAID scriptID;
  486.     OSAID resultID;
  487.     OSAError error;
  488.     
  489.     if (!HasAppleScript())
  490.     {
  491.         FW_CString32 name("ODFButton");
  492.         FW_CString message;
  493.         FW_SOMEnvironment ev;
  494.         FW_PSharedLibraryResourceFile resFile(ev);
  495.         
  496.         ::FW_LoadStringByID(ev, resFile, kButtonDialogStrings, FW_kMultiStringRes, kNoAppleScriptMsg, message);
  497.         ::FW_NoteAlert(name, message);
  498.     }
  499.     else
  500.     {    
  501.         // load the script data
  502.         scriptDesc.descriptorType = typeOSAGenericStorage;
  503.         scriptDesc.dataHandle = scriptData;
  504.         
  505.         ComponentInstance componentInstance = GetScriptingComponent();
  506.         
  507.         error = ::OSALoad(componentInstance, &scriptDesc, kOSAModeNull, &scriptID);
  508.         
  509.         if (error == noErr)
  510.         { 
  511.             // execute the compiled script in the default context                 
  512.             error = ::OSAExecute(componentInstance, scriptID, kOSANullScript, kOSAModeNull, &resultID);
  513.             error = ::OSADispose(componentInstance, scriptID);
  514.             error = ::OSADispose(componentInstance, resultID);
  515.         }
  516.     }
  517. }
  518.  
  519. //----------------------------------------------------------------------------------------
  520. // CScriptAction::DoIt
  521. //----------------------------------------------------------------------------------------
  522.  
  523. void CScriptAction::DoIt()
  524. {
  525.     if (fScriptHandle != NULL)
  526.         LoadAndExecuteScript(fScriptHandle);
  527. }
  528.  
  529. //----------------------------------------------------------------------------------------
  530. // CScriptAction::Read
  531. //----------------------------------------------------------------------------------------
  532.  
  533. void* CScriptAction::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  534. {
  535. FW_UNUSED(type);
  536.     FW_SOMEnvironment ev;
  537.     return new CScriptAction(ev, stream);
  538. }
  539.  
  540. //----------------------------------------------------------------------------------------
  541. // CScriptAction::Write
  542. //----------------------------------------------------------------------------------------
  543.  
  544. void CScriptAction::Write(FW_CWritableStream& stream, FW_ClassTypeConstant type, const void *object)
  545. {
  546. FW_UNUSED(type);
  547.     FW_SOMEnvironment ev;
  548.     CScriptAction* action = (CScriptAction*) object;
  549.     action->ExternalizeToStream(ev, stream);
  550. }
  551.  
  552.