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 / ODF / Framewrk / FWPart / FWInter.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  14.8 KB  |  496 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWInter.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWINTER_H
  13. #include "FWInter.h"
  14. #endif
  15.  
  16. #ifndef FWPART_H
  17. #include "FWPart.h"
  18. #endif
  19.  
  20. #ifndef FWPRMISE_H
  21. #include "FWPrmise.h"
  22. #endif
  23.  
  24. #ifndef FWCLNINF_H
  25. #include "FWClnInf.h"
  26. #endif
  27.  
  28. #ifndef FWBARRAY_H
  29. #include "FWBArray.h"
  30. #endif
  31.  
  32. #ifndef FWFRAME_H
  33. #include "FWFrame.h"
  34. #endif
  35.  
  36. #ifndef FWUTIL_H
  37. #include "FWUtil.h"
  38. #endif
  39.  
  40. #ifndef FWCONTNT_H
  41. #include "FWContnt.h"
  42. #endif
  43.  
  44. #ifndef FWPRMISE_H
  45. #include "FWPrmise.h"
  46. #endif
  47.  
  48. #ifndef FWLNKSRC_H
  49. #include "FWLnkSrc.h"
  50. #endif
  51.  
  52. #ifndef FWSESION_H
  53. #include "FWSesion.h"
  54. #endif
  55.  
  56. #ifndef FWSUUTIL_H
  57. #include "FWSUUtil.h"
  58. #endif
  59.  
  60. // ----- OpenDoc Includes -----
  61.  
  62. #ifndef SOM_ODStorageUnit_xh
  63. #include <StorageU.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODClipboard_xh
  67. #include <Clipbd.xh>
  68. #endif
  69.  
  70. #ifndef SOM_Module_OpenDoc_StdProps_defined
  71. #include <StdProps.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODTranslation_xh
  75. #include <Translt.xh>
  76. #endif
  77.  
  78. //========================================================================================
  79. // RunTime Info
  80. //========================================================================================
  81.  
  82. #ifdef FW_BUILD_MAC
  83. #pragma segment FWFrameworkContent
  84. #endif
  85.  
  86. //========================================================================================
  87. //    class FW_CDataInterchange
  88. //========================================================================================
  89.  
  90. //----------------------------------------------------------------------------------------
  91. //    FW_CDataInterchange constructor
  92. //----------------------------------------------------------------------------------------
  93.  
  94. FW_CDataInterchange::FW_CDataInterchange(Environment* ev, FW_CPart* part) :
  95.     fPart(part),
  96.     fClipboardPromise(NULL),
  97.     fDragAndDropPromise(NULL),
  98.     fLinkPromise(NULL),
  99.     fClipboardUpdateID(0)
  100. {
  101. FW_UNUSED(ev);
  102. }
  103.  
  104. //----------------------------------------------------------------------------------------
  105. //    FW_CDataInterchange destructor
  106. //----------------------------------------------------------------------------------------
  107.  
  108. FW_CDataInterchange::~FW_CDataInterchange()
  109. {
  110.     FW_ASSERT(fClipboardPromise == NULL);    // Should be NULL by now
  111.     FW_ASSERT(fDragAndDropPromise == NULL);    // Should be NULL by now
  112.     FW_ASSERT(fLinkPromise == NULL);    // Should be NULL by now
  113. }
  114.  
  115. //---------------------------------------------------------------------------------------
  116. //    FW_CDataInterchange::ExternalizeData
  117. //---------------------------------------------------------------------------------------
  118. //    Note: Even if I am not an embedding part I still need to call BeginClone/EndClone
  119. //    otherwise OpenDoc's OriginalCloneKind property in the draft is not set correctly
  120.  
  121. void FW_CDataInterchange::ExternalizeData(Environment* ev, 
  122.                                           FW_CContent* content,
  123.                                          FW_CFrame* scopeFrame,
  124.                                           ODStorageUnit* destinationSU, 
  125.                                           FW_StorageKinds storageKind, 
  126.                                           ODCloneKind cloneKind)
  127. {
  128.     if (content == NULL)
  129.         return;
  130.         
  131.     ODDraft* fromDraft = fPart->GetDraft(ev);
  132.     ODDraft* dstDraft = destinationSU->GetDraft(ev);
  133.  
  134.     FW_CCloneInfo cloneInfo(ev, fromDraft, scopeFrame, cloneKind);
  135.     
  136.     cloneInfo.BeginClone(ev, dstDraft);            
  137.     
  138.     PrivHandleExternalizeData(ev, content, destinationSU, storageKind, &cloneInfo);
  139.  
  140.     cloneInfo.EndClone(ev);
  141. }
  142.     
  143. //----------------------------------------------------------------------------------------
  144. //    FW_CDataInterchange::PrivHandleExternalizeData
  145. //----------------------------------------------------------------------------------------
  146.  
  147. void FW_CDataInterchange::PrivHandleExternalizeData(Environment* ev,
  148.                                                       FW_CContent* content,
  149.                                                     ODStorageUnit* destinationSU, 
  150.                                                     FW_StorageKinds storageKind,
  151.                                                     FW_CCloneInfo* cloneInfo)
  152. {
  153.     if (storageKind == FW_kClipboardStorage || storageKind == FW_kDragAndDropStorage)
  154.         PrivDeletePromises(ev, storageKind);
  155.  
  156.     // ----- Add the needed properties first -----
  157.     fPart->PrepContentProperty(ev, destinationSU, storageKind, FALSE);
  158.     
  159.     content->Externalize(ev, destinationSU, storageKind, cloneInfo);
  160.  
  161.     // ----- If supported, write a shape property -----
  162.     FW_CAcquiredODShape aqSuggestedFrameShape = content->AcquireSuggestedFrameShape(ev);
  163.     if (((ODShape*)aqSuggestedFrameShape) != NULL)
  164.     {
  165.         // ----- Add the property. WriteShape will add the value
  166.         if (destinationSU->Exists(ev, kODPropSuggestedFrameShape, (ODValueType)NULL, 0))
  167.         {
  168.             destinationSU->Focus(ev, kODPropSuggestedFrameShape, 
  169.                                 kODPosUndefined, 
  170.                                    (ODValueType)NULL, 
  171.                                 (ODValueIndex)1, 
  172.                                 kODPosUndefined);
  173.             destinationSU->Remove(ev);                // remove the first value
  174.         }
  175.         else
  176.             destinationSU->AddProperty(ev, kODPropSuggestedFrameShape);
  177.             
  178.         aqSuggestedFrameShape->WriteShape(ev, destinationSU);
  179.     }
  180. }
  181.  
  182. //---------------------------------------------------------------------------------------
  183. //    FW_CDataInterchange::InternalizeData
  184. //---------------------------------------------------------------------------------------
  185. //    Note: Even if I am not an embedding part I still need to call BeginClone/EndClone
  186. //    otherwise OpenDoc's OriginalCloneKind property in the draft is not set correctly
  187.  
  188. FW_EInternalizeResult FW_CDataInterchange::InternalizeData(Environment* ev, 
  189.                                                             FW_CContent* content,
  190.                                                             FW_CFrame* scopeFrame,
  191.                                                             ODStorageUnit* sourceSU,
  192.                                                             FW_StorageKinds storageKind, 
  193.                                                             ODCloneKind cloneKind,
  194.                                                             ODPasteAsResult* embedAsInfo)
  195. {
  196.     ODDraft* fromDraft = sourceSU->GetDraft(ev);
  197.     ODDraft* dstDraft = fPart->GetDraft(ev);
  198.  
  199.     FW_EInternalizeResult result = FW_kInternalizeFailed;
  200.  
  201.     FW_CCloneInfo cloneInfo(ev, fromDraft, scopeFrame, cloneKind);
  202.     
  203.     if (embedAsInfo && embedAsInfo->mergeSetting == kODFalse)
  204.     {
  205.         result = PrivHandleEmbedAs(ev, content, sourceSU, &cloneInfo, embedAsInfo);
  206.     }
  207.     else
  208.     {
  209.         cloneInfo.BeginClone(ev, dstDraft);
  210.  
  211.         result = PrivHandleInternalizeData(ev, content, sourceSU, storageKind, &cloneInfo);        
  212.  
  213.         if (result == FW_kInternalizeFailed) 
  214.         {
  215.             cloneInfo.AbortClone(ev);
  216.             return result;
  217.         }
  218.  
  219.         cloneInfo.EndClone(ev);
  220.  
  221.         PrivPostInternalizeData(ev, content, &cloneInfo, result);
  222.     }
  223.     
  224.     return result;
  225. }
  226.     
  227. //----------------------------------------------------------------------------------------
  228. //    FW_CDataInterchange::PrivPostInternalizeData
  229. //----------------------------------------------------------------------------------------
  230.  
  231. void FW_CDataInterchange::PrivPostInternalizeData(Environment* ev, 
  232.                                                 FW_CContent* content,
  233.                                                   FW_CCloneInfo* cloneInfo, 
  234.                                                   FW_EInternalizeResult result)
  235. {
  236. FW_UNUSED(ev);
  237. FW_UNUSED(content);
  238. FW_UNUSED(result);
  239. FW_UNUSED(cloneInfo);
  240.  
  241.     // Nothing to do. See: FW_CEmbeddingDataInterchange::PrivPostInternalizeData
  242. }
  243.  
  244. //----------------------------------------------------------------------------------------
  245. //    FW_CDataInterchange::PrivHandleInternalizeData
  246. //----------------------------------------------------------------------------------------
  247.  
  248. FW_EInternalizeResult FW_CDataInterchange::PrivHandleInternalizeData(Environment* ev, 
  249.                                                                     FW_CContent* content,
  250.                                                                      ODStorageUnit* sourceSU, 
  251.                                                                     FW_StorageKinds storageKind, 
  252.                                                                      FW_CCloneInfo* cloneInfo)
  253. {
  254.     
  255.     FW_Boolean result = content->Internalize(ev, sourceSU, storageKind, cloneInfo);
  256.     return result ? FW_kInternalizeContent : FW_kInternalizeFailed;
  257. }
  258.  
  259. //----------------------------------------------------------------------------------------
  260. //    FW_CDataInterchange::PrivHandleEmbedAs
  261. //----------------------------------------------------------------------------------------
  262.  
  263. FW_EInternalizeResult FW_CDataInterchange::PrivHandleEmbedAs(Environment* ev, 
  264.                                                             FW_CContent* content,
  265.                                                              ODStorageUnit* sourceSU,
  266.                                                              FW_CCloneInfo* cloneInfo,
  267.                                                              ODPasteAsResult* embedAsInfo)
  268. {
  269. FW_UNUSED(ev);
  270. FW_UNUSED(content);
  271. FW_UNUSED(sourceSU);
  272. FW_UNUSED(cloneInfo);
  273. FW_UNUSED(embedAsInfo);
  274.  
  275.     FW_DEBUG_MESSAGE("FW_CDataInterchange::PrivHandleEmbedAs should never be called");
  276.     return FW_kInternalizeFailed;
  277. }
  278.  
  279. //----------------------------------------------------------------------------------------
  280. // FW_CDataInterchange::ResolveClipboardPromise
  281. //----------------------------------------------------------------------------------------
  282.  
  283. void FW_CDataInterchange::ResolveClipboardPromise(Environment* ev)
  284. {
  285.     if (fClipboardPromise == NULL)
  286.         return;
  287.  
  288.     ODClipboard* clipboard = FW_CSession::GetClipboard(ev);
  289.     ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
  290.     if (clipboard->GetUpdateID(ev) == fClipboardPromise->GetUpdateID(ev))
  291.         clipboardSU->ResolveAllPromises(ev);
  292.     else
  293.         PrivDeletePromises(ev, FW_kClipboardStorage);
  294.         
  295.     FW_ASSERT(fClipboardPromise == NULL);
  296. }
  297.  
  298. //----------------------------------------------------------------------------------------
  299. // FW_CDataInterchange::ResolveAllPromises
  300. //----------------------------------------------------------------------------------------
  301. //    Will resolve all promises (clipboard and all link promises)
  302.  
  303. void FW_CDataInterchange::ResolveAllPromises(Environment* ev)
  304. {
  305.     // ----- I should never have to resolve a drag and drop promise or a link  promise -----
  306.     PrivDeletePromises(ev, FW_kDragAndDropStorage);
  307.     PrivDeletePromises(ev, FW_kLinkStorage);
  308.  
  309.     // ----- resolve Clipboard promise -----
  310.     ResolveClipboardPromise(ev);
  311.     
  312.     // ----- Should be NULL by now
  313.     FW_ASSERT(fClipboardPromise == NULL);
  314.     FW_ASSERT(fDragAndDropPromise == NULL);
  315. }
  316.  
  317. //---------------------------------------------------------------------------------------
  318. //    FW_CDataInterchange::PrivDeletePromises
  319. //---------------------------------------------------------------------------------------
  320.  
  321. void FW_CDataInterchange::PrivDeletePromises(Environment* ev, FW_StorageKinds storageKind)
  322. {
  323. FW_UNUSED(ev);
  324.     switch(storageKind)
  325.     {
  326.         
  327.         case FW_kClipboardStorage:
  328.             delete fClipboardPromise;        // Will call PrivPromiseDeleted
  329.             FW_ASSERT(fClipboardPromise == NULL);
  330.             break;
  331.         case FW_kDragAndDropStorage:
  332.             delete fDragAndDropPromise;        // Will call PrivPromiseDeleted
  333.             FW_ASSERT(fDragAndDropPromise == NULL);
  334.             break;
  335.         case FW_kLinkStorage:
  336.             delete fLinkPromise;
  337.             FW_ASSERT(fLinkPromise == NULL);
  338.             break;
  339.         
  340.         default:
  341.         FW_DEBUG_MESSAGE("FW_CDataInterchange::PrivDeletePromises - Unknown storageKind");
  342.     }
  343. }
  344.  
  345. //----------------------------------------------------------------------------------------
  346. //    FW_CDataInterchange::PrivPromise
  347. //----------------------------------------------------------------------------------------
  348.  
  349. void FW_CDataInterchange::PrivPromise(Environment* ev, 
  350.                                     FW_CPromise* promise,
  351.                                     ODStorageUnit* storageUnit, 
  352.                                     ODPropertyName propertyName, 
  353.                                     ODValueType valueType)
  354. {    
  355.     FW_ASSERT(propertyName != NULL);
  356.     FW_ASSERT(valueType != NULL);
  357.  
  358.     storageUnit->Focus(ev, propertyName, kODPosUndefined, NULL, 0, kODPosUndefined);
  359.  
  360.     FW_CPromise* buffer = promise;
  361.     FW_CByteArray bArray(&buffer, sizeof(FW_CPromise*));
  362.     storageUnit->SetPromiseValue(ev,
  363.                                 valueType,
  364.                                 0,
  365.                                 bArray,
  366.                                 fPart->GetODPart(ev));    
  367.     
  368.     // ----- add the promise -----
  369.     //     Note that a promise object can be promised multiple times
  370.     
  371.     FW_StorageKinds storageKind = promise->GetStorageKind(ev);
  372.  
  373.     if (storageKind == FW_kLinkStorage)
  374.     {
  375.         FW_CLinkSource* linkSrc = promise->PrivGetLinkSource(ev);
  376.         if (linkSrc != NULL)
  377.             linkSrc->SetLinkPromise(ev, promise);
  378.         else if (fLinkPromise != promise)
  379.         {
  380.             PrivDeletePromises(ev, FW_kLinkStorage);
  381.             fLinkPromise = promise;
  382.         }
  383.     }
  384.     else if (storageKind == FW_kClipboardStorage)
  385.     {
  386.         if (fClipboardPromise != promise)
  387.         {
  388.             PrivDeletePromises(ev, FW_kClipboardStorage);
  389.             fClipboardPromise = promise;
  390.         }
  391.     }
  392.     else if (storageKind == FW_kDragAndDropStorage)
  393.     {
  394.         if (fDragAndDropPromise != promise)
  395.         {
  396.             PrivDeletePromises(ev, FW_kDragAndDropStorage);
  397.             fDragAndDropPromise = promise;
  398.         }
  399.     }
  400.     else
  401.     {
  402.         FW_DEBUG_MESSAGE("FW_CDataInterchange::PrivPromise - Unknown storageKind");
  403.     }
  404. }
  405.  
  406. //----------------------------------------------------------------------------------------
  407. //    FW_CDataInterchange::PrivPromiseDeleted
  408. //----------------------------------------------------------------------------------------
  409. //    called by the destructor of FW_CPromise
  410.  
  411. void FW_CDataInterchange::PrivPromiseDeleted(Environment *ev, FW_CPromise* promise)
  412. {
  413.     FW_StorageKinds storageKind = promise->GetStorageKind(ev);
  414.  
  415.     if (storageKind == FW_kLinkStorage)
  416.     {
  417.         if ( promise == fLinkPromise)
  418.             fLinkPromise = NULL;
  419.         else
  420.         {
  421.             FW_ASSERT(promise->PrivGetLinkSource(ev) != NULL);
  422.             FW_ASSERT(promise->PrivGetLinkSource(ev)->GetLinkPromise(ev) == promise);
  423.         }
  424.     }
  425.     else if (storageKind == FW_kClipboardStorage)
  426.     {
  427.         FW_ASSERT(fClipboardPromise == promise);
  428.         fClipboardPromise = NULL;
  429.     }
  430.     else if (storageKind == FW_kDragAndDropStorage)
  431.     {
  432.         FW_ASSERT(fDragAndDropPromise == promise);
  433.         fDragAndDropPromise = NULL;
  434.     }
  435.     else
  436.     {
  437.         FW_DEBUG_MESSAGE("FW_CDataInterchange::PrivPromiseDeleted - Unknown storageKind");
  438.     }
  439. }
  440.  
  441. //---------------------------------------------------------------------------------------
  442. // FW_CDataInterchange::TranslateData
  443. //---------------------------------------------------------------------------------------
  444.  
  445. ODTranslateResult FW_CDataInterchange::TranslateData(Environment* ev, 
  446.                                             ODStorageUnit* storageUnit,
  447.                                             ODType translateKind,
  448.                                             ODType desiredKind)
  449. {
  450.     // Translation was requested from translateKind to desiredKind
  451.  
  452.     //--- Add desiredKind value and create the destination storage unit view
  453.     FW_SUForceFocus(ev, storageUnit, kODPropContents, desiredKind);
  454.     FW_CAcquireODStorageUnitView toView(ev, storageUnit);
  455.  
  456.     //--- Create the source storage unit view
  457.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, translateKind, 0, kODPosUndefined);
  458.     FW_CAcquireODStorageUnitView fromView(ev, storageUnit);
  459.  
  460.     //--- Get the translation object and perform the translation
  461.     ODTranslation* translation = FW_CSession::GetTranslation(ev);
  462.     ODTranslateResult translateResult = translation->TranslateView(ev, fromView, toView);
  463.  
  464.     return translateResult;
  465. }
  466.  
  467. //---------------------------------------------------------------------------------------
  468. // FW_CDataInterchange::PrivHandleFulfillPromise
  469. //---------------------------------------------------------------------------------------
  470.  
  471. void FW_CDataInterchange::PrivHandleFulfillPromise(     Environment* ev, 
  472.                                                             FW_CPromise* promise,
  473.                                                             ODStorageUnitView* promiseSUView)
  474. {
  475.     long count = promise->PrivHandleFulfillPromise(ev, fPart, promiseSUView);
  476.     
  477.     if (count == 0)
  478.     {
  479.         if (promise->GetStorageKind(ev) == FW_kLinkStorage)
  480.         {
  481.             if (promise == fLinkPromise)
  482.                 delete  promise;
  483.             else
  484.             {
  485.                 FW_CLinkSource* linkSrc = promise->PrivGetLinkSource(ev);
  486.                 FW_ASSERT(linkSrc != NULL);
  487.                 linkSrc->SetLinkPromise(ev, NULL);
  488.             }
  489.         }
  490.         else
  491.             delete promise;
  492.     }
  493. }
  494.  
  495.  
  496.