home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / Sources / FWLnkMgr.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  15.9 KB  |  522 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWLnkMgr.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWLNKMGR_H
  13. #include "FWLnkMgr.h"
  14. #endif
  15.  
  16. // ----- Framework Includes -----
  17.  
  18. #ifndef FWPART_H
  19. #include "FWPart.h"
  20. #endif
  21.  
  22. #ifndef FWPRESEN_H
  23. #include "FWPresen.h"
  24. #endif
  25.  
  26. #ifndef FWITERS_H
  27. #include "FWIters.h"
  28. #endif
  29.  
  30. #ifndef FWUTIL_H
  31. #include "FWUtil.h"
  32. #endif
  33.  
  34. // ----- Foundation Includes -----
  35.  
  36. #ifndef FWPRIDEB_H
  37. #include "FWPriDeb.h"
  38. #endif
  39.  
  40. #ifndef FWMEMMGR_H
  41. #include "FWMemMgr.h"
  42. #endif
  43.  
  44. // ----- OS Includes -----
  45.  
  46. #ifndef FWTIME_H
  47. #include "FWTime.h"
  48. #endif
  49.  
  50. // ----- OpenDoc Includes -----
  51.  
  52. #ifndef SOM_Module_OpenDoc_StdProps_defined
  53. #include <StdProps.xh>
  54. #endif
  55.  
  56. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  57. #include <StdTypes.xh>
  58. #endif
  59.  
  60. #ifndef SOM_ODStorageUnit_xh
  61. #include <StorageU.xh>
  62. #endif
  63.  
  64. #ifndef SOM_ODSession_xh
  65. #include <ODSessn.xh>
  66. #endif
  67.  
  68. #ifndef SOM_ODDraft_xh
  69. #include <Draft.xh>
  70. #endif
  71.  
  72. #ifndef SOM_ODClipboard_xh
  73. #include <Clipbd.xh>
  74. #endif
  75.  
  76. #ifndef SOM_ODLink_xh
  77. #include <Link.xh>
  78. #endif
  79.  
  80. #ifndef SOM_ODLinkSpec_xh
  81. #include <LinkSpec.xh>
  82. #endif
  83.  
  84. #ifndef SOM_ODLinkSource_xh
  85. #include <LinkSrc.xh>
  86. #endif
  87.  
  88. //========================================================================================
  89. //    Runtime information
  90. //========================================================================================
  91.  
  92. #if FW_LIB_EXPORT_PRAGMAS
  93. #pragma lib_export on
  94. #endif
  95.  
  96. #ifdef FW_BUILD_MAC
  97. #pragma segment framework
  98. #endif
  99.  
  100. FW_DEFINE_CLASS_M0(FW_CLinkManager)
  101.  
  102. //========================================================================================
  103. //    class FW_CLinkManager
  104. //========================================================================================
  105.  
  106. //---------------------------------------------------------------------------------------
  107. //    FW_CLinkManager constructor
  108. //---------------------------------------------------------------------------------------
  109.  
  110. FW_CLinkManager::FW_CLinkManager(Environment *ev, FW_CPart* thePart) :
  111.     fPart(thePart),
  112.     fPendingPublishLink(NULL),
  113.     fPendingDropLink(NULL),
  114.     fPublishLinkList(NULL),
  115.     fSubscribeLinkList(NULL)
  116. {
  117. }
  118.  
  119. //---------------------------------------------------------------------------------------
  120. //    FW_CLinkManager destructor
  121. //---------------------------------------------------------------------------------------
  122.  
  123. FW_CLinkManager::~FW_CLinkManager()
  124. {
  125.     delete fSubscribeLinkList;
  126.     fSubscribeLinkList = NULL;
  127.  
  128.     delete fPublishLinkList;
  129.     fPublishLinkList = NULL;
  130. }
  131.  
  132. //---------------------------------------------------------------------------------------
  133. //    FW_CLinkManager::RemoveAllLinks
  134. //---------------------------------------------------------------------------------------
  135.  
  136. void FW_CLinkManager::RemoveAllLinks(Environment *ev)
  137. {
  138.     // ----- Delete publishers -----
  139.     if (fPublishLinkList)
  140.     {
  141.         FW_CPublishLink* link;
  142.         while ((link = (FW_CPublishLink*)fPublishLinkList->First()) != NULL)
  143.         {
  144.             fPublishLinkList->Remove(link);
  145.             delete link;
  146.         }        
  147.     }
  148.     
  149.     // ----- Delete subscribers -----
  150.     if (fSubscribeLinkList)
  151.     {
  152.         FW_CSubscribeLink* link;
  153.         while ((link = (FW_CSubscribeLink*)fSubscribeLinkList->First()) != NULL)
  154.         {
  155.             fSubscribeLinkList->Remove(link);
  156.             delete link;
  157.         }        
  158.     }
  159. }
  160.  
  161. //---------------------------------------------------------------------------------------
  162. //    FW_CLinkManager::AddToPublishLinkList
  163. //---------------------------------------------------------------------------------------
  164.  
  165. void FW_CLinkManager::AddToPublishLinkList(Environment* ev, FW_CPublishLink* publishLink)
  166. {
  167.     if (fPublishLinkList == NULL)
  168.         fPublishLinkList = new FW_CPrivOrderedCollection;
  169.     
  170.     fPublishLinkList->AddLast(publishLink);
  171. }
  172.  
  173. //---------------------------------------------------------------------------------------
  174. //    FW_CLinkManager::AddToSubscribeLinkList
  175. //---------------------------------------------------------------------------------------
  176.  
  177. void FW_CLinkManager::AddToSubscribeLinkList(Environment* ev, FW_CSubscribeLink* subscribeLink)
  178. {
  179.     if (fSubscribeLinkList == NULL)
  180.         fSubscribeLinkList = new FW_CPrivOrderedCollection;
  181.     
  182.     fSubscribeLinkList->AddLast(subscribeLink);
  183. }
  184.  
  185. //---------------------------------------------------------------------------------------
  186. //    FW_CLinkManager::BreakPublishLink
  187. //---------------------------------------------------------------------------------------
  188. void FW_CLinkManager::BreakPublishLink(Environment* ev, FW_CPublishLink* publishLink)
  189. {
  190.     publishLink->BreakLink(ev);
  191.     this->RemoveFromPublishLinkList(ev, publishLink);
  192. }
  193.  
  194. //---------------------------------------------------------------------------------------
  195. //    FW_CLinkManager::BreakSubscribeLink
  196. //---------------------------------------------------------------------------------------
  197. void FW_CLinkManager::BreakSubscribeLink(Environment* ev, FW_CSubscribeLink* subscribeLink)
  198. {
  199.     subscribeLink->BreakLink(ev);
  200.     this->RemoveFromSubscribeLinkList(ev, subscribeLink);
  201. }
  202.  
  203. //---------------------------------------------------------------------------------------
  204. //    FW_CLinkManager::CountPublishers
  205. //---------------------------------------------------------------------------------------
  206.  
  207. unsigned long FW_CLinkManager::CountPublishers(Environment* ev) const
  208. {
  209.     if (fPublishLinkList)
  210.         return fPublishLinkList->Count();
  211.  
  212.     return 0;
  213. }
  214.  
  215. //---------------------------------------------------------------------------------------
  216. //    FW_CLinkManager::CountSubscribers
  217. //---------------------------------------------------------------------------------------
  218.  
  219. unsigned long FW_CLinkManager::CountSubscribers(Environment* ev) const
  220. {
  221.     if (fSubscribeLinkList)
  222.         return fSubscribeLinkList->Count();
  223.  
  224.     return 0;
  225. }
  226.  
  227. //---------------------------------------------------------------------------------------
  228. //    FW_CLinkManager::CreateLink
  229. //---------------------------------------------------------------------------------------
  230.  
  231. ODLinkSource* FW_CLinkManager::CreateLink(Environment *ev, ODByteArray* data)
  232. {
  233.     ODLinkSource* odLinkSource = NULL;
  234.     ODUpdateID updateID = *((ODUpdateID*)(data->_buffer));
  235.  
  236.     // The link spec is either on the clipboard or saved from a Drag&Drop operation.
  237.     // Determine which one to use by checking the ids
  238.  
  239.     // --- Check the clipboard link spec first, since it's the most likely candidate ---
  240.     FW_CPublishLink* pendingPublishLink = this->GetPendingPublish(ev);
  241.     if (pendingPublishLink && (pendingPublishLink->GetPendingID(ev) == updateID))
  242.     {
  243.         // Get the link if it already exists
  244.         odLinkSource = pendingPublishLink->GetODLinkSource(ev);
  245.     }
  246.     else    // check for a Drag&Drop link spec
  247.     {
  248.         pendingPublishLink = this->GetPendingDropLink(ev);
  249.         FW_ASSERT(pendingPublishLink != NULL);
  250.         FW_ASSERT(pendingPublishLink->GetPendingID(ev) == updateID);
  251.  
  252.         // The Drag&Drop link spec is only good for creating one link
  253.         this->SetPendingDropLink(ev, NULL);
  254.     }
  255.  
  256.     if (odLinkSource == NULL)        // link does not yet exist
  257.     {
  258.         odLinkSource = fPart->GetStorageUnit(ev)->GetDraft(ev)->CreateLinkSource(ev, fPart->GetODPart(ev));
  259.  
  260.         pendingPublishLink->SetODLinkSource(ev, odLinkSource);
  261.         this->AddToPublishLinkList(ev, pendingPublishLink);
  262.         pendingPublishLink->Publish(ev);
  263.         // Don't DeletePendingPublish, because more links may be created from it
  264.     }
  265.     else
  266.     {
  267.         pendingPublishLink->ContentUpdated(ev, kODUnknownUpdate, TRUE);
  268.         odLinkSource->Acquire(ev);
  269.     }
  270.     
  271.     return odLinkSource;
  272. }
  273.  
  274. //---------------------------------------------------------------------------------------
  275. //    FW_CLinkManager::DeletePendingPublish
  276. //---------------------------------------------------------------------------------------
  277.  
  278. void FW_CLinkManager::DeletePendingPublish(Environment *ev)
  279. {
  280.     if (fPendingPublishLink != NULL)
  281.     {
  282.         ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  283.         
  284.         if (fPendingPublishLink->GetPendingID(ev) == clipboard->GetUpdateID(ev)) 
  285.         {
  286.             ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
  287.             if (clipboardSU->Exists(ev, kODPropLinkSpec, (ODValueType) NULL, 0) == TRUE) 
  288.             {
  289.                 clipboardSU->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType) NULL, 0, kODPosUndefined);
  290.                 clipboardSU->Remove(ev);
  291.             }
  292.         }
  293.         
  294.         if (fPendingPublishLink->IsPending(ev))    // CreateLink was never called
  295.             delete fPendingPublishLink;
  296.  
  297.         fPendingPublishLink = NULL;
  298.     }
  299. }
  300.  
  301. //---------------------------------------------------------------------------------------
  302. //    FW_CLinkManager::DoChangeLinkStatus
  303. //---------------------------------------------------------------------------------------
  304.  
  305. void FW_CLinkManager::DoChangeLinkStatus(Environment* ev, ODFrame* odFrame)
  306. {
  307.     // Embedding parts should override to call ODFrame::ChangeLinkStatus for any 
  308.     // embedded frames that are involved in a link when a link is created, broken, moved, etc.
  309.     // odFrame is the frame whose link status has changed.
  310. }
  311.  
  312. //---------------------------------------------------------------------------------------
  313. //    FW_CLinkManager::DoUpdateLinks
  314. //---------------------------------------------------------------------------------------
  315.  
  316. void FW_CLinkManager::DoUpdateLinks(Environment *ev,
  317.                                     ODFrame* odEmbeddedFrame,
  318.                                     ODUpdateID updateID)
  319. {
  320.     // An embedded frame has changed. (Formerly named EmbeddedFrameUpdated)
  321.     // Embedding parts should override to do the following:
  322.     //    1) If odEmbeddedFrame is involved in one of my link sources, update the link with new data.
  323.     //    2) Call ContentUpdated on display frames as appropriate.
  324. }
  325.  
  326. //---------------------------------------------------------------------------------------
  327. //    FW_CLinkManager::EditInLinkAttempted
  328. //---------------------------------------------------------------------------------------
  329.  
  330. FW_Boolean FW_CLinkManager::EditInLinkAttempted(Environment *ev, ODFrame* odFrame)
  331. {
  332.     // Not yet implemented
  333.     return FALSE;
  334. }
  335.  
  336. //---------------------------------------------------------------------------------------
  337. //    FW_CLinkManager::ODtoPublishLink
  338. //---------------------------------------------------------------------------------------
  339.  
  340. FW_CPublishLink* FW_CLinkManager::ODtoPublishLink(Environment* ev, ODLinkSource* linkSource) const
  341. {
  342.     FW_COrderedCollectionIterator iter(fPublishLinkList);
  343.     for (FW_CPublishLink* link = (FW_CPublishLink*)iter.First(); iter.IsNotComplete(); link = (FW_CPublishLink*)iter.Next()) 
  344.     {
  345.         if (linkSource->IsEqualTo(ev, link->GetODLinkSource(ev)))
  346.             return link;
  347.     }
  348.     return NULL;
  349. }
  350.  
  351. //---------------------------------------------------------------------------------------
  352. //    FW_CLinkManager::ODtoSubscribeLink
  353. //---------------------------------------------------------------------------------------
  354.  
  355. FW_CSubscribeLink* FW_CLinkManager::ODtoSubscribeLink(Environment* ev, ODLink* odLink) const
  356. {
  357.     FW_COrderedCollectionIterator iter(fSubscribeLinkList);
  358.     for (FW_CSubscribeLink* link = (FW_CSubscribeLink*)iter.First(); iter.IsNotComplete(); link = (FW_CSubscribeLink*)iter.Next())
  359.     {
  360.         if (odLink->IsEqualTo(ev, link->GetODLink(ev)))
  361.             return link;
  362.     }
  363.     return NULL;
  364. }
  365.  
  366. //---------------------------------------------------------------------------------------
  367. //    FW_CLinkManager::RevealLink
  368. //---------------------------------------------------------------------------------------
  369.  
  370. void FW_CLinkManager::RevealLink(Environment* ev, ODLinkSource* linkSource)
  371. {
  372.     FW_DEBUG_MESSAGE("RevealLink: Not Yet Implemented");
  373. }
  374.  
  375. //---------------------------------------------------------------------------------------
  376. //    FW_CLinkManager::RemoveFromPublishLinkList
  377. //---------------------------------------------------------------------------------------
  378.  
  379. void FW_CLinkManager::RemoveFromPublishLinkList(Environment* ev, FW_CPublishLink* publishLink)
  380. {
  381.     fPublishLinkList->Remove(publishLink);
  382.  
  383.     if (publishLink == fPendingPublishLink)
  384.         this->DeletePendingPublish(ev);
  385.     
  386.     if (fPublishLinkList->Count() == 0)
  387.     {
  388.         delete fPublishLinkList;
  389.         fPublishLinkList = NULL;
  390.     }
  391. }
  392.  
  393. //---------------------------------------------------------------------------------------
  394. //    FW_CLinkManager::RemoveFromSubscribeLinkList
  395. //---------------------------------------------------------------------------------------
  396.  
  397. void FW_CLinkManager::RemoveFromSubscribeLinkList(Environment* ev, FW_CSubscribeLink* subscribeLink)
  398. {
  399.     fSubscribeLinkList->Remove(subscribeLink);
  400.     
  401.     if (fSubscribeLinkList->Count() == 0)
  402.     {
  403.         delete fSubscribeLinkList;
  404.         fSubscribeLinkList = NULL;
  405.     }
  406. }
  407.  
  408. //---------------------------------------------------------------------------------------
  409. //    FW_CLinkManager::RestorePublishLink
  410. //---------------------------------------------------------------------------------------
  411. void FW_CLinkManager::RestorePublishLink(Environment* ev, FW_CPublishLink* publishLink)
  412. {
  413.     this->AddToPublishLinkList(ev, publishLink);
  414.     publishLink->RestoreLink(ev, fPart);
  415.     publishLink->Publish(ev);
  416. }
  417.  
  418. //---------------------------------------------------------------------------------------
  419. //    FW_CLinkManager::RestoreSubscribeLink
  420. //---------------------------------------------------------------------------------------
  421. void FW_CLinkManager::RestoreSubscribeLink(Environment* ev, FW_CSubscribeLink* subscribeLink)
  422. {
  423.     this->AddToSubscribeLinkList(ev, subscribeLink);
  424.     subscribeLink->RestoreLink(ev, fPart);
  425.     subscribeLink->HandleSubscribe(ev);
  426. }
  427.  
  428. //---------------------------------------------------------------------------------------
  429. //    FW_CLinkManager::PasteWithLink
  430. //---------------------------------------------------------------------------------------
  431. FW_Boolean FW_CLinkManager::PasteWithLink(Environment* ev, ODStorageUnit* storageUnit, 
  432.                                           ODPasteAsResult& pasteAsResult,
  433.                                           FW_CPresentation* presentation)
  434. {
  435.     FW_Boolean result = FALSE;
  436.     ODLinkSpec* linkSpec = NULL;
  437.     ODLink* odLink = NULL;
  438.     ODDraft* draft = fPart->GetStorageUnit(ev)->GetDraft(ev);
  439.     if (!storageUnit->Exists(ev, kODPropLinkSpec, (ODValueType)NULL, 0))
  440.         return FALSE;
  441.  
  442.     FW_VOLATILE(result);
  443.     FW_VOLATILE(linkSpec);
  444.     FW_VOLATILE(odLink);
  445.  
  446.     FW_TRY
  447.     {
  448.         linkSpec = draft->CreateLinkSpec(ev, NULL, NULL);
  449.  
  450.         storageUnit->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType)NULL, 0, kODPosUndefined);
  451.         linkSpec->ReadLinkSpec(ev, storageUnit);
  452.  
  453.         // ---- Establish the Link ----
  454.         odLink = draft->AcquireLink(ev, (ODStorageUnitID)0, linkSpec);    // use linkSpec to retrieve the link
  455.  
  456.         if (odLink)
  457.         {
  458.             ODLinkInfo linkInfo;
  459.             linkInfo.change = kODUnknownUpdate;    // not yet updated
  460.             FW_CTime time = FW_CTime::GetCurrentTime();
  461.             linkInfo.creationTime = time.GetTime();
  462.             linkInfo.changeTime = linkInfo.creationTime;
  463.             linkInfo.autoUpdate = pasteAsResult.autoUpdateSetting;
  464.  
  465.             unsigned long length = strlen(pasteAsResult.selectedKind);
  466.             linkInfo.kind = (ODValueType)FW_CMemoryManager::AllocateBlock(length+1);
  467.             FW_CMemoryManager::CopyMemory(pasteAsResult.selectedKind, linkInfo.kind, length);
  468.  
  469.             // --- Embed or incorporate the link ---
  470.             this->MakeSubscribeLink(ev, odLink, &linkInfo, presentation);
  471.             result = TRUE;
  472.  
  473.             odLink->Release(ev);    // to balance AcquireLink
  474.         }
  475.     }
  476.     FW_CATCH_BEGIN
  477.     FW_CATCH_EVERYTHING()
  478.     {
  479.         if (linkSpec)
  480.             delete linkSpec;
  481.         if (odLink)
  482.             odLink->Release(ev);
  483.         FW_THROW_SAME();
  484.     }
  485.     FW_CATCH_END
  486.  
  487.     if (linkSpec)
  488.         delete linkSpec;
  489.                     
  490.     return result;
  491. }
  492.  
  493. //---------------------------------------------------------------------------------------
  494. //    FW_CLinkManager::MakeSubscribeLink
  495. //---------------------------------------------------------------------------------------
  496. void FW_CLinkManager::MakeSubscribeLink(Environment* ev,
  497.                                         ODLink* odLink,
  498.                                         ODLinkInfo* linkInfo,
  499.                                         FW_CPresentation* presentation)
  500. {
  501.     FW_CSubscribeLink* subscribeLink = NULL;
  502.     FW_VOLATILE(subscribeLink);
  503.  
  504.     FW_TRY
  505.     {
  506.         subscribeLink = this->NewSubscribeLink(ev, odLink, linkInfo, presentation);
  507.         this->AddToSubscribeLinkList(ev, subscribeLink);
  508.         subscribeLink->Register(ev, fPart);    // causes LinkUpdated to be called
  509.         if (subscribeLink->GetUpdateID(ev) != kODUnknownUpdate)    // LinkUpdated succeeded
  510.             subscribeLink->HandleSubscribe(ev);
  511.     }
  512.     FW_CATCH_BEGIN
  513.     FW_CATCH_EVERYTHING()
  514.     {
  515.         if (subscribeLink)
  516.             delete subscribeLink;
  517.         FW_THROW_SAME();
  518.     }
  519.     FW_CATCH_END
  520. }
  521.  
  522.