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 / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Storage / LinkSrcB.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  31.9 KB  |  1,112 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkSrcB.cpp
  3.  
  4.     Contains:    Implementation of ODBaseLinkSource class
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <3>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  13.          <2>     3/26/96    CC        1332880: kODLinkContent should use std ISO
  14.                                     prefix.
  15.  
  16.     To Do: 
  17.     In Progress:
  18.         
  19. */
  20.  
  21. #define VARIABLE_MACROS
  22.  
  23. #define ODBaseLinkSource_Class_Source
  24. #include <LinkSrcB.xih>
  25.  
  26. #include <LinkSrc.xh>
  27.  
  28. #ifndef _EXCEPT_
  29. #include <Except.h>
  30. #endif
  31.  
  32. #ifndef _ODMEMORY_
  33. #include <ODMemory.h>
  34. #endif
  35.  
  36. #ifndef _CONSTDEF_
  37. #include <ConstDef.h>
  38. #endif
  39.  
  40. #ifndef SOM_ODLink_xh
  41. #include <Link.xh>
  42. #endif
  43.  
  44. #ifndef _LINKDLGS_
  45. #include <LinkDlgs.h>
  46. #endif
  47.  
  48. #ifndef SOM_ODPart_xh
  49. #include <Part.xh>
  50. #endif
  51.  
  52. #ifndef SOM_ODFrame_xh
  53. #include <Frame.xh>
  54. #endif
  55.  
  56. #ifndef SOM_ODContainer_xh
  57. #include <ODCtr.xh>
  58. #endif
  59.  
  60. #ifndef SOM_ODDocument_xh
  61. #include <Document.xh>
  62. #endif
  63.  
  64. #ifndef SOM_ODDraft_xh
  65. #include <Draft.xh>
  66. #endif
  67.  
  68. #ifndef SOM_ODSession_xh
  69. #include <ODSessn.xh>
  70. #endif
  71.  
  72. #ifndef SOM_ODArbitrator_xh
  73. #include <Arbitrat.xh>
  74. #endif
  75.  
  76. #ifndef SOM_ODWindowState_xh
  77. #include <WinStat.xh>
  78. #endif
  79.  
  80. #ifndef SOM_Module_OpenDoc_Foci_defined
  81. #include <Foci.xh>
  82. #endif
  83.  
  84. #ifndef SOM_ODStorageSystem_xh
  85. #include <ODStor.xh>
  86. #endif
  87.  
  88. #ifndef SOM_ODStorageUnit_xh
  89. #include <StorageU.xh>
  90. #endif
  91.  
  92. #ifndef SOM_Module_OpenDoc_StdProps_defined
  93. #include <StdProps.xh>
  94. #endif
  95.  
  96. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  97. #include <StdTypes.xh>
  98. #endif
  99.  
  100. #ifndef __ERRORS__
  101. #include <Errors.h>
  102. #endif
  103.  
  104. #ifndef _ODUTILS_
  105. #include <ODUtils.h>
  106. #endif
  107.  
  108. /* Adkins -- added to provide prototype for ODUnused and LMGetBufPtr */
  109. /* Adkins -- LMGetBufPtr is in LowMem.h, which PlfmDef.h conditionaly includes */
  110. #ifndef _PLFMDEF_
  111. #include <PlfmDef.h>
  112. #endif
  113.  
  114. #ifndef _ISOSTR_
  115. #include <ISOStr.h>
  116. #endif
  117.  
  118. #ifndef _DOCUTILS_
  119. #include <DocUtils.h>
  120. #endif
  121.  
  122. #ifndef _STDTYPIO_
  123. #include <StdTypIO.h>
  124. #endif
  125.  
  126. #ifndef _ODDEBUG_
  127. #include <ODDebug.h>
  128. #endif
  129.  
  130. #ifndef _POUTILS_
  131. #include <POUtils.h>
  132. #endif
  133.  
  134. #ifndef SOM_ODTypeList_xh
  135. #include <TypeList.xh>
  136. #endif
  137.  
  138. #ifndef SOM_LinkMgr_xh
  139. #include <LinkMgr.xh>
  140. #endif
  141.  
  142. #ifndef SOM_ODTypeListIterator_xh
  143. #include <TypLsItr.xh>
  144. #endif
  145.  
  146. #ifndef _STORUTIL_
  147. #include <StorUtil.h>
  148. #endif
  149.  
  150. #ifndef _TEMPOBJ_
  151. #include "TempObj.h"
  152. #endif
  153.  
  154. #pragma segment ODBaseLinkSource
  155.  
  156. //==============================================================================
  157. // Constants
  158. //==============================================================================
  159.  
  160. const    ODType    kODLinkContent    = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:ObjectType:LinkContent";
  161. const    ODULong    kODNullKey         = 0;
  162.  
  163. // dirty masks
  164. const ODULong kNotDirty                    = 0x0000UL;
  165. const ODULong kLinkDirty                = 0x0001UL;
  166. const ODULong kSourcePartDirty            = 0x0002UL;
  167. const ODULong kAutoUpdateDirty            = 0x0004UL;
  168. const ODULong kUpdateIDDirty            = 0x0008UL;
  169. const ODULong kChangeTimeDirty            = 0x0010UL;
  170. const ODULong kKindsUsedDirty            = 0x0020UL;
  171. const ODULong kContentSUDirty            = 0x0040UL;
  172. const ODULong kChangeLimitDirty            = 0x0080UL;
  173. const ODULong kAllDirty                    = 0xFFFFUL;
  174.  
  175. //==============================================================================
  176. // Local functions
  177. //==============================================================================
  178.  
  179. static void RemovePromisedContent(Environment *ev, ODStorageUnit* su);
  180.  
  181. //==============================================================================
  182. // ODBaseLinkSource
  183. //==============================================================================
  184.  
  185. //------------------------------------------------------------------------------
  186. // ODBaseLinkSource: somInit
  187. //------------------------------------------------------------------------------
  188.  
  189. SOM_Scope void  SOMLINK ODBaseLinkSourcesomInit(ODBaseLinkSource *somSelf)
  190. {
  191.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  192.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","somInit");
  193.  
  194.     parent_somInit(somSelf);
  195.  
  196.     _fContentSU = (ODStorageUnit*) kODNULL;
  197.     _fLink = (ODLink*) kODNULL;
  198.     _fSourcePartSU = (ODStorageUnit*) kODNULL;
  199.     _fAutoUpdate = kODFalse;
  200.     _fNewUpdateID = kODUnknownUpdate;
  201.     _fUpdateID = kODUnknownUpdate;
  202.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  203.     _fChangeTime = 0;
  204.     _fChangeCount = 1;
  205.     _fChangeLimit = 1;
  206.     _fDirty = kNotDirty;
  207.     _fKindsUsed = (ODTypeList*) kODNULL;
  208.     _fCleared = kODFalse;
  209. }
  210.  
  211. //------------------------------------------------------------------------------
  212. // ODBaseLinkSource: somUninit
  213. //------------------------------------------------------------------------------
  214.  
  215. SOM_Scope void  SOMLINK ODBaseLinkSourcesomUninit(ODBaseLinkSource *somSelf)
  216. {
  217.     /* ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf); */
  218.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","somUninit");
  219.  
  220.     parent_somUninit(somSelf);
  221. }
  222.  
  223. //------------------------------------------------------------------------------
  224. // ODBaseLinkSource: InitBaseLinkSource
  225. //------------------------------------------------------------------------------
  226.  
  227. SOM_Scope void  SOMLINK ODBaseLinkSourceInitBaseLinkSource(ODBaseLinkSource *somSelf, Environment *ev,
  228.         ODStorageUnit* storageUnit,
  229.         ODPart* sourcePart)
  230. {
  231.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  232.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","InitBaseLinkSource");
  233.  
  234.     SOM_TRY
  235.  
  236.     somSelf->InitPersistentObject(ev, storageUnit);
  237.     InitDateInfo(ev, storageUnit);
  238.  
  239.     _fUpdateID = storageUnit->GetSession(ev)->UniqueUpdateID(ev);
  240.  
  241.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  242.  
  243.     if ( sourcePart != (ODPart*) kODNULL )
  244.     {
  245.         _fSourcePartSU = sourcePart->GetStorageUnit(ev);
  246.         _fSourcePartSU->Acquire(ev);
  247.         _fAutoUpdate = kODTrue;
  248.     }
  249.  
  250.     ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  251.  
  252.     _fContentSU = su->GetDraft(ev)->CreateStorageUnit(ev);
  253.     ODSetISOStrProp(ev, _fContentSU, kODPropStorageUnitType, kODISOStr, kODLinkContent);
  254.  
  255.     ODSUAddPropValue(ev, su, kODPropUpdateID, kODULong);
  256.     ODSUAddPropValue(ev, su, kODPropChangeLimit, kODULong);
  257.     ODSUAddPropValue(ev, su, kODPropChangeTime, kODTime_T);
  258.     ODSUAddPropValue(ev, su, kODPropAutoUpdate, kODBoolean);
  259.     ODSUAddPropValue(ev, su, kODPropLinkContentSU, kODStrongStorageUnitRef);
  260.     ODSUAddPropValue(ev, su, kODPropLink, kODWeakStorageUnitRef);
  261.  
  262.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  263.         ODSUAddPropValue(ev, su, kODPropSourcePart, kODWeakStorageUnitRef);
  264.  
  265.     somSelf->SetBaseLinkSourceDirty(ev, kAllDirty);
  266.  
  267.     SOM_CATCH_ALL
  268.     SOM_ENDTRY
  269. }
  270.  
  271. //------------------------------------------------------------------------------
  272. // ODBaseLinkSource: InitBaseLinkSourceFromStorage
  273. //------------------------------------------------------------------------------
  274.  
  275. SOM_Scope void  SOMLINK ODBaseLinkSourceInitBaseLinkSourceFromStorage(ODBaseLinkSource *somSelf, Environment *ev,
  276.         ODStorageUnit* storageUnit)
  277. {
  278.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  279.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","InitBaseLinkSourceFromStorage");
  280.  
  281.     SOM_TRY
  282.  
  283.     somSelf->InitPersistentObjectFromStorage(ev, storageUnit);
  284.     InitDateInfo(ev, storageUnit);
  285.  
  286.     _fContentSU = storageUnit->GetDraft(ev)->AcquireStorageUnit(ev, ODGetStrongSURefProp(ev, storageUnit, kODPropLinkContentSU, kODStrongStorageUnitRef));
  287.     _fUpdateID = ODGetULongProp(ev, storageUnit, kODPropUpdateID, kODULong);
  288.     _fChangeLimit = ODGetULongProp(ev, storageUnit, kODPropChangeLimit, kODULong);
  289.     _fChangeTime = ODGetTime_TProp(ev, storageUnit, kODPropChangeTime, kODTime_T);
  290.     _fAutoUpdate = ODGetBooleanProp(ev, storageUnit, kODPropAutoUpdate, kODBoolean);
  291.  
  292.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  293.  
  294.     if ( storageUnit->Exists(ev, kODPropContentKindsUsed, 0, 0) )
  295.     {
  296.         _fKindsUsed = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetStorageSystem(ev)->CreateTypeList(ev, kODNULL);
  297.         ODGetTypeListProp(ev, storageUnit, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  298.     }
  299.  
  300.     if ( storageUnit->Exists(ev, kODPropLink, 0, 0) )
  301.     {
  302.         ODID linkID = ODGetWeakSURefProp(ev, storageUnit, kODPropLink, kODWeakStorageUnitRef);
  303.         if ( linkID == kODNULLID )
  304.             somSelf->SetBaseLinkSourceDirty(ev, kLinkDirty);
  305.         else
  306.             _fLink = storageUnit->GetDraft(ev)->AcquireLink(ev, linkID, (ODLinkSpec*) kODNULL);
  307.     }
  308.  
  309.     if ( storageUnit->Exists(ev, kODPropSourcePart, 0, 0) )
  310.     {
  311.         ODID sourcePartID = ODGetWeakSURefProp(ev, storageUnit, kODPropSourcePart, kODWeakStorageUnitRef);
  312.         if ( sourcePartID == kODNULLID )
  313.             somSelf->SetBaseLinkSourceDirty(ev, kSourcePartDirty);
  314.         else
  315.             _fSourcePartSU = storageUnit->GetDraft(ev)->AcquireStorageUnit(ev, sourcePartID);
  316.     }
  317.  
  318.     SOM_CATCH_ALL
  319.     SOM_ENDTRY
  320. }
  321.  
  322. //------------------------------------------------------------------------------
  323. // ODBaseLinkSource::Externalize (OVERRIDE)
  324. //------------------------------------------------------------------------------
  325.  
  326. SOM_Scope void  SOMLINK ODBaseLinkSourceExternalize(ODBaseLinkSource *somSelf, Environment *ev)
  327. {
  328.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  329.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Externalize");
  330.  
  331.     SOM_TRY
  332.  
  333.     parent_Externalize(somSelf,ev);
  334.  
  335.     RemovePromisedContent(ev, _fContentSU);
  336.  
  337.     if ( _fDirty )
  338.     {
  339.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  340.  
  341.         if ( _fDirty & kContentSUDirty )
  342.             ODSetStrongSURefProp(ev, su, kODPropLinkContentSU, kODStrongStorageUnitRef, _fContentSU->GetID(ev));
  343.  
  344.         if ( _fDirty & kUpdateIDDirty )
  345.             ODSetULongProp(ev, su, kODPropUpdateID, kODULong, _fUpdateID);
  346.  
  347.         if ( _fDirty & kChangeLimitDirty )
  348.             ODSetULongProp(ev, su, kODPropChangeLimit, kODULong, _fChangeLimit);
  349.  
  350.         if ( _fDirty & kChangeTimeDirty )
  351.             ODSetTime_TProp(ev, su, kODPropChangeTime, kODTime_T, _fChangeTime);
  352.  
  353.         if ( _fDirty & kAutoUpdateDirty )
  354.             ODSetBooleanProp(ev, su, kODPropAutoUpdate, kODBoolean, _fAutoUpdate);
  355.     
  356.         if ( _fDirty & kKindsUsedDirty )
  357.         {
  358.             if ( _fKindsUsed == kODNULL )
  359.                 ODSURemoveProperty(ev, su, kODPropContentKindsUsed);
  360.             else
  361.                 ODSetTypeListProp(ev, su, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  362.         }
  363.         
  364.         if ( _fDirty & kLinkDirty )
  365.         {
  366.             if ( _fLink == (ODLink*) kODNULL )
  367.                 ODSURemoveProperty(ev, su, kODPropLink);
  368.             else
  369.                 ODSetWeakSURefProp(ev, su, kODPropLink, kODWeakStorageUnitRef, _fLink->GetStorageUnit(ev)->GetID(ev));
  370.         }
  371.  
  372.         if ( _fDirty & kSourcePartDirty )
  373.         {
  374.             if ( _fSourcePartSU == (ODStorageUnit*) kODNULL )
  375.                 ODSURemoveProperty(ev, su, kODPropSourcePart);
  376.             else
  377.                 ODSetWeakSURefProp(ev, su, kODPropSourcePart, kODWeakStorageUnitRef, _fSourcePartSU->GetID(ev));
  378.         }
  379.  
  380.         _fDirty = kNotDirty;
  381.     }
  382.  
  383.     SOM_CATCH_ALL
  384.     SOM_ENDTRY
  385. }
  386.  
  387. //------------------------------------------------------------------------------
  388. // ODBaseLinkSource: CloneInto (OVERRIDE)
  389. //------------------------------------------------------------------------------
  390.  
  391. SOM_Scope void  SOMLINK ODBaseLinkSourceCloneInto(ODBaseLinkSource *somSelf, Environment *ev,
  392.         ODDraftKey key,
  393.         ODStorageUnit* toSU,
  394.         ODFrame* scopeFrame)
  395. {
  396.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  397.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","CloneInto");
  398.  
  399.     SOM_TRY
  400.     
  401.     // If one of our properties already exists, this object has been cloned already
  402.     if ( toSU->Exists(ev, kODPropLink, kODWeakStorageUnitRef, 0) )
  403.         return;
  404.  
  405.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  406.  
  407.     RemovePromisedContent(ev, _fContentSU);
  408.  
  409.     CloneDateInfo(ev, somSelf->GetStorageUnit(ev), toSU);
  410.     
  411.     ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  412.  
  413.     ODSetULongProp(ev, toSU, kODPropUpdateID, kODULong, _fUpdateID);
  414.     ODSetULongProp(ev, toSU, kODPropChangeLimit, kODULong, 1);
  415.     ODSetTime_TProp(ev, toSU, kODPropChangeTime, kODTime_T, _fChangeTime);
  416.     ODSetBooleanProp(ev, toSU, kODPropAutoUpdate, kODBoolean, _fAutoUpdate);
  417.  
  418.     ODID clonedLinkContentID = draft->Clone(ev, key, _fContentSU->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  419.     ODSetStrongSURefProp(ev, toSU, kODPropLinkContentSU, kODStrongStorageUnitRef, clonedLinkContentID);
  420.  
  421.     if ( _fKindsUsed != kODNULL )
  422.         ODSetTypeListProp(ev, toSU, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  423.  
  424.     if ( _fLink != (ODLink*) kODNULL )
  425.     {
  426.         ODID clonedLinkSourceID = draft->WeakClone(ev, key, _fLink->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  427.         ODSetWeakSURefProp(ev, toSU, kODPropLink, kODWeakStorageUnitRef, clonedLinkSourceID);
  428.     }
  429.  
  430.     // The source part should only be kODNULL for links imported from another draft.
  431.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  432.     {
  433.         ODID clonedSourcePartID = draft->WeakClone(ev, key, _fSourcePartSU->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  434.         ODSetWeakSURefProp(ev, toSU, kODPropSourcePart, kODWeakStorageUnitRef, clonedSourcePartID);
  435.     }
  436.  
  437.     SOM_CATCH_ALL
  438.     SOM_ENDTRY
  439. }
  440.  
  441. //------------------------------------------------------------------------------
  442. // ODBaseLinkSource: ReleaseAll (OVERRIDE)
  443. //------------------------------------------------------------------------------
  444.  
  445. SOM_Scope void  SOMLINK ODBaseLinkSourceReleaseAll(ODBaseLinkSource *somSelf, Environment *ev)
  446. {
  447.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  448.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ReleaseAll");
  449.  
  450.     SOM_TRY
  451.  
  452.     parent_ReleaseAll(somSelf,ev);
  453.  
  454.     ODReleaseObject(ev, _fContentSU);
  455.     ODReleaseObject(ev, _fLink);
  456.     ODReleaseObject(ev, _fSourcePartSU);
  457.  
  458.     SOM_CATCH_ALL
  459.     SOM_ENDTRY
  460. }
  461.  
  462. //------------------------------------------------------------------------------
  463. // ODBaseLinkSource: SetBaseLinkSourceDirty
  464. //------------------------------------------------------------------------------
  465.  
  466. SOM_Scope void  SOMLINK ODBaseLinkSourceSetBaseLinkSourceDirty(ODBaseLinkSource *somSelf, Environment *ev,
  467.     ODULong dirtyProperty)
  468. {
  469.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  470.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetBaseLinkSourceDirty");
  471.  
  472.     SOM_TRY    
  473.         _fDirty |= dirtyProperty;
  474.  
  475.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  476.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  477.             draft->SetChangedFromPrev(ev);
  478.     SOM_CATCH_ALL
  479.     SOM_ENDTRY
  480. }
  481.  
  482. //------------------------------------------------------------------------------
  483. // ODBaseLinkSource: ShowLinkSourceInfo
  484. //------------------------------------------------------------------------------
  485.  
  486. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceShowLinkSourceInfo(ODBaseLinkSource *somSelf, Environment *ev,
  487.         ODFacet* facet,
  488.         ODUpdateID change,
  489.         ODBoolean changesAllowed,
  490.         ODLinkInfoResult* infoResult)
  491. {
  492.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  493.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ShowLinkSourceInfo");
  494.  
  495.     ODBoolean result = kODFalse;
  496.  
  497.     SOM_TRY
  498.     
  499.     THROW_IF_NULL(facet, kODErrNullFacetInput);
  500.     THROW_IF_NULL(infoResult, kODErrNullLinkInfoResultInput);
  501.     THROW_IF_NULL(_fLink, kODErrBrokenLink);
  502.  
  503.     ODSession* session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  504.     ODTypeToken modalFocus = session->Tokenize(ev, kODModalFocus);
  505.     ODArbitrator* arbitrator = session->GetArbitrator(ev);
  506.     TempODFrame currentOwner = arbitrator->AcquireFocusOwner(ev, modalFocus);
  507.  
  508.     if ( arbitrator->RequestFocus(ev, modalFocus, facet->GetFrame(ev)) )
  509.     {
  510.         infoResult->autoUpdate = _fAutoUpdate;
  511.     
  512.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  513.  
  514.         result = ShowLinkSourceInfo(somSelf, change, changesAllowed, infoResult);
  515.  
  516.         session->GetWindowState(ev)->ActivateFrontWindows(ev);
  517.  
  518.         arbitrator->TransferFocus(ev, modalFocus, facet->GetFrame(ev), currentOwner);
  519.     }
  520.     else
  521.     {
  522.         SysBeep(2);
  523.     }
  524.     return result;
  525.  
  526.     SOM_CATCH_ALL
  527.     SOM_ENDTRY
  528.     return kODFalse;
  529. }
  530.  
  531. //------------------------------------------------------------------------------
  532. // ODBaseLinkSource: Lock
  533. //------------------------------------------------------------------------------
  534.  
  535. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceLock(ODBaseLinkSource *somSelf, Environment *ev,
  536.         ODULong wait,
  537.         ODLinkKey* key)
  538. {
  539.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  540.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Lock");
  541.  
  542.     ODUnused(wait);
  543.  
  544.     if ( _fLink == (ODLink*) kODNULL )
  545.     {
  546.         ODSetSOMException(ev, kODErrBrokenLink);
  547.         return kODFalse;
  548.     }
  549.  
  550.     TRY    // Don't use SOM_TRY as we do _not_ want to return an exception!
  551.  
  552.     *key = (ODLinkKey) somSelf->GetStorageUnit(ev)->Lock(ev, 0);
  553.     
  554.     _fCleared = kODFalse;
  555.     _fNewUpdateID = kODUnknownUpdate;
  556.     
  557.     CATCH_ALL
  558.         *key = kODNullKey;
  559.         // Don't reraise, just return
  560.     ENDTRY
  561.  
  562.     return (*key != kODNullKey);
  563. }
  564.  
  565. //------------------------------------------------------------------------------
  566. // ODBaseLinkSource: Unlock
  567. //------------------------------------------------------------------------------
  568.  
  569. SOM_Scope void  SOMLINK ODBaseLinkSourceUnlock(ODBaseLinkSource *somSelf, Environment *ev,
  570.         ODLinkKey key)
  571. {
  572.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  573.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Unlock");
  574.  
  575.     SOM_TRY
  576.  
  577.         // Force fulfilling of promises for content kinds used by current destinations
  578.         if ( _fCleared && _fKindsUsed )
  579.         {
  580.             ODBoolean allUsedKindsPresent = kODTrue; ODVolatile(allUsedKindsPresent);
  581.         
  582.             ODTypeListIterator* iter = kODNULL; ODVolatile(iter);
  583.             TRY
  584.                 iter = _fKindsUsed->CreateTypeListIterator(ev);
  585.         
  586.                 for (ODType kind = iter->First(ev);
  587.                     iter->IsNotComplete(ev);
  588.                     kind = iter->Next(ev))
  589.                 {
  590.                     if ( ODSUExistsThenFocus(ev, _fContentSU, kODPropContents, kind) )
  591.                     {
  592.                         if ( _fContentSU->IsPromiseValue(ev) )
  593.                         {
  594.                             // Force part to fulfill its promise
  595.                             TRY
  596.                                 ODULong size = _fContentSU->GetSize(ev);
  597.                             CATCH_ALL
  598.                                 allUsedKindsPresent = kODFalse;
  599.                             ENDTRY
  600.                         }
  601.                     }
  602.                     else
  603.                     {
  604.                         allUsedKindsPresent = kODFalse;
  605.                     }
  606.                     ODDisposePtr(kind);
  607.                 }
  608.             CATCH_ALL
  609.                 allUsedKindsPresent = kODFalse;
  610.             ENDTRY
  611.             ODDeleteObject(iter);
  612.         
  613.             if ( allUsedKindsPresent )
  614.             {
  615.                 ODDeleteObject(_fKindsUsed);
  616.                 somSelf->SetBaseLinkSourceDirty(ev, kKindsUsedDirty);
  617.             }
  618.         }
  619.  
  620.         _fCleared = kODFalse;
  621.  
  622.         // Any unlocking action needs to be performed before calling UpdateDependents(),
  623.         // since that will cause dependents to lock and unlock their link, which delegates
  624.         // to this object. 
  625.     
  626.         somSelf->GetStorageUnit(ev)->Unlock(ev, (ODStorageUnitKey) key);
  627.     
  628.         if ( _fNewUpdateID != kODUnknownUpdate )
  629.         {
  630.             ODBoolean notifyDependents = kODFalse;
  631.     
  632.             time(&_fChangeTime);
  633.             somSelf->SetBaseLinkSourceDirty(ev, kChangeTimeDirty);
  634.  
  635.             if ( _fUpdateID != _fNewUpdateID )
  636.             {
  637.                 // Link updated with different change ID than last time
  638.                 _fChangeCount = 1;
  639.                 _fUpdateID = _fNewUpdateID;
  640.                 somSelf->SetBaseLinkSourceDirty(ev, kUpdateIDDirty);
  641.                 notifyDependents = kODTrue;
  642.                 
  643.                 if ( _fSuspended )
  644.                     _fUpdatedAfterSuspended = kODTrue;
  645.             }
  646.             else if ( ++_fChangeCount <= _fChangeLimit )
  647.             {
  648.                 // Same change but user previously continued beyond this iteration
  649.                 notifyDependents = kODTrue;
  650.             }
  651.             else
  652.             {
  653.                 ODLinkManager* linkMgr = 
  654.                     somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  655.                 ODLinkUpdateResult updateResult = linkMgr->ShowLinkUpdateAlert(ev, somSelf);
  656.                     
  657.                 if ( updateResult == kODLinkUpdateContinue )
  658.                 {
  659.                     // User continued propagating this update
  660.                     ++_fChangeLimit;
  661.                     somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  662.                     notifyDependents = kODTrue;
  663.                 }
  664.                 else if ( updateResult == kODLinkUpdateStop )
  665.                 {
  666.                     // User cancelled propagating this update
  667.                     _fChangeLimit = 1;
  668.                     somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  669.                 }
  670.                 else // updateResult == kODLinkUpdateSuspend
  671.                 {
  672.                     _fSuspended = kODTrue;
  673.                 }
  674.             }
  675.     
  676.             _fNewUpdateID = kODUnknownUpdate;
  677.     
  678.             if ( notifyDependents && !_fSuspended && (_fLink != (ODLink*) kODNULL) )
  679.             {
  680.                 // Ignore errors returned by UpdateDependents
  681.                 TRY
  682.                     _fLink->UpdateDependents(ev);
  683.                 CATCH_ALL
  684.                 ENDTRY
  685.             }
  686.         }
  687.     
  688.     SOM_CATCH_ALL
  689.     
  690.     SOM_ENDTRY
  691. }
  692.  
  693.  
  694. //------------------------------------------------------------------------------
  695. // ODBaseLinkSource: LinkUpdateAlertCompleted
  696. //------------------------------------------------------------------------------
  697.  
  698. SOM_Scope void  SOMLINK ODBaseLinkSourceLinkUpdateAlertCompleted(ODBaseLinkSource *somSelf, Environment *ev,
  699.         ODLinkUpdateResult updateResult)
  700. {
  701.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  702.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","LinkUpdateAlertCompleted");
  703.  
  704.     ODBoolean notifyDependents = kODFalse;
  705.     
  706.     SOM_TRY
  707.     
  708.         // Get and reset these booleans atomically here to avoid possible 
  709.         // confusion from setting them again while updating dependents:
  710.         ODBoolean suspended = _fSuspended;
  711.         ODBoolean updatedAfterSuspended = _fUpdatedAfterSuspended;
  712.         _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  713.         
  714.         if ( updateResult == kODLinkUpdateContinue )
  715.         {
  716.             // User continued propagating this update
  717.             ++_fChangeLimit;
  718.             somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  719.             notifyDependents = kODTrue;
  720.         }
  721.         else if ( updateResult == kODLinkUpdateStop )
  722.         {
  723.             // User cancelled propagating this update
  724.             _fChangeLimit = 1;
  725.             somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  726.             
  727.             if ( updatedAfterSuspended )
  728.                 notifyDependents = kODTrue;
  729.         }
  730.  
  731.         if ( notifyDependents && (_fLink != (ODLink*) kODNULL) )
  732.         {
  733.             // Ignore errors returned by UpdateDependents
  734.             TRY
  735.                 _fLink->UpdateDependents(ev);
  736.             CATCH_ALL
  737.             ENDTRY
  738.         }
  739.  
  740.     SOM_CATCH_ALL
  741.     
  742.     SOM_ENDTRY
  743. }
  744.  
  745. //------------------------------------------------------------------------------
  746. // ODBaseLinkSource: KeyValid
  747. //------------------------------------------------------------------------------
  748.  
  749. SOM_Scope void  SOMLINK ODBaseLinkSourceKeyValid(ODBaseLinkSource *somSelf, Environment *ev,
  750.         ODLinkKey key)
  751. {
  752.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  753.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","KeyValid");
  754.  
  755.     SOM_TRY
  756.  
  757.     if (key == kODNullKey)
  758.         ODSetSOMException(ev, kODErrInvalidLinkKey);
  759.     else
  760.     {
  761.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  762.         ODStorageUnitKey suKey = su->Lock(ev, (ODStorageUnitKey) key);
  763.         su->Unlock(ev, suKey);
  764.     }
  765.  
  766.     SOM_CATCH_ALL
  767.     SOM_ENDTRY
  768. }
  769.  
  770. //------------------------------------------------------------------------------
  771. // ODBaseLinkSource: GetContentStorageUnit
  772. //------------------------------------------------------------------------------
  773.  
  774. SOM_Scope ODStorageUnit*  SOMLINK ODBaseLinkSourceGetContentStorageUnit(ODBaseLinkSource *somSelf, Environment *ev,
  775.         ODLinkKey key)
  776. {
  777.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  778.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetContentStorageUnit");
  779.  
  780.     SOM_TRY
  781.  
  782.     somSelf->KeyValid(ev, key);
  783.  
  784.     return _fContentSU;
  785.  
  786.     SOM_CATCH_ALL
  787.     SOM_ENDTRY
  788.     return (ODStorageUnit*) kODNULL;
  789. }
  790.  
  791. //------------------------------------------------------------------------------
  792. // ODBaseLinkSource: ContentUpdated
  793. //------------------------------------------------------------------------------
  794.  
  795. SOM_Scope void  SOMLINK ODBaseLinkSourceContentUpdated(ODBaseLinkSource *somSelf, Environment *ev,
  796.         ODUpdateID id,
  797.         ODLinkKey key)
  798. {
  799.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  800.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ContentUpdated");
  801.  
  802.     SOM_TRY
  803.  
  804.         somSelf->KeyValid(ev, key);
  805.  
  806.         if ( id == kODUnknownUpdate )
  807.             THROW(kODErrUnknownUpdateID);
  808.  
  809.         _fNewUpdateID = id;
  810.     
  811.     SOM_CATCH_ALL
  812.     
  813.     SOM_ENDTRY
  814. }
  815.  
  816. //------------------------------------------------------------------------------
  817. // ODBaseLinkSource: Clear
  818. //------------------------------------------------------------------------------
  819.  
  820. SOM_Scope void  SOMLINK ODBaseLinkSourceClear(ODBaseLinkSource *somSelf, Environment *ev,
  821.         ODUpdateID id,
  822.         ODLinkKey key)
  823. {
  824.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  825.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Clear");
  826.  
  827.     ODValueType kind = kODNULL;    ODVolatile(kind);
  828.  
  829.     SOM_TRY
  830.  
  831.         somSelf->KeyValid(ev, key);
  832.  
  833.         // Fail immediately if this draft can't be changed
  834.         ODDraftPermissions permissions = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetPermissions(ev);
  835.         if (!HAS_WRITE_ACCESS(permissions))
  836.             THROW(kODErrInvalidPermissions);
  837.  
  838.         if ( id == kODUnknownUpdate )
  839.             THROW(kODErrUnknownUpdateID);
  840.  
  841.         // If id is the current id, don't notify destinations unless ContentUpdated is called.
  842.         if ( id != _fUpdateID )
  843.             _fNewUpdateID = id;
  844.         
  845.         // Add each non-promise value type in the contents property to _fKindsUsed,
  846.         // then remove the contents property.
  847.         if (ODSUExistsThenFocus(ev, _fContentSU, kODPropContents, kODNULL) )
  848.         {
  849.             ODULong numValues = _fContentSU->CountValues(ev);    
  850.             ODULong kindIndex;
  851.             
  852.             for (kindIndex = 0; kindIndex < numValues; kindIndex++)
  853.             {
  854.                 _fContentSU->Focus(ev, kODPropContents, kODPosUndefined, kODTypeAll, 0, kODPosNextSib);
  855.                 if ( !_fContentSU->IsPromiseValue(ev) )
  856.                 {
  857.                     if ( _fKindsUsed == kODNULL )
  858.                         _fKindsUsed = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetStorageSystem(ev)
  859.                                         ->CreateTypeList(ev, kODNULL);
  860.                     kind = _fContentSU->GetType(ev);
  861.                     _fKindsUsed->AddLast(ev, kind);
  862.                     ODDisposePtr(kind);
  863.                     kind = kODNULL;
  864.                     somSelf->SetBaseLinkSourceDirty(ev, kKindsUsedDirty);
  865.                 }
  866.             }
  867.             ODSURemoveProperty(ev, _fContentSU, kODPropContents);
  868.  
  869.             RemoveDataInterchangeProperties(ev, _fContentSU, kODFalse);
  870.             
  871.             _fCleared = kODTrue;
  872.         }
  873.  
  874.     SOM_CATCH_ALL
  875.     
  876.         ODDisposePtr(kind);
  877.  
  878.     SOM_ENDTRY
  879. }
  880.  
  881. //------------------------------------------------------------------------------
  882. // ODBaseLinkSource: GetUpdateID
  883. //------------------------------------------------------------------------------
  884.  
  885. SOM_Scope ODUpdateID  SOMLINK ODBaseLinkSourceGetUpdateID(ODBaseLinkSource *somSelf, Environment *ev)
  886. {
  887.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  888.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetUpdateID");
  889.  
  890.     return _fUpdateID;
  891. }
  892.  
  893. //------------------------------------------------------------------------------
  894. // ODBaseLinkSource: SetUpdateID
  895. //------------------------------------------------------------------------------
  896.  
  897. SOM_Scope void  SOMLINK ODBaseLinkSourceSetUpdateID(ODBaseLinkSource *somSelf, Environment *ev,
  898.         ODUpdateID updateID,
  899.         ODLinkKey key)
  900. {
  901.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  902.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetUpdateID");
  903.  
  904.     SOM_TRY
  905.  
  906.     somSelf->KeyValid(ev, key);
  907.  
  908.     if ( updateID != _fUpdateID )
  909.     {
  910.         _fUpdateID = updateID;
  911.         somSelf->SetBaseLinkSourceDirty(ev, kUpdateIDDirty);
  912.     }
  913.  
  914.     SOM_CATCH_ALL
  915.     SOM_ENDTRY
  916. }
  917.  
  918. //------------------------------------------------------------------------------
  919. // ODBaseLinkSource: GetChangeTime
  920. //------------------------------------------------------------------------------
  921.  
  922. SOM_Scope ODTime  SOMLINK ODBaseLinkSourceGetChangeTime(ODBaseLinkSource *somSelf, Environment *ev)
  923. {
  924.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  925.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetChangeTime");
  926.  
  927.     return _fChangeTime;
  928. }
  929.  
  930. //------------------------------------------------------------------------------
  931. // ODBaseLinkSource: SetChangeTime
  932. //------------------------------------------------------------------------------
  933.  
  934. SOM_Scope void  SOMLINK ODBaseLinkSourceSetChangeTime(ODBaseLinkSource *somSelf, Environment *ev,
  935.         ODTime changeTime,
  936.         ODLinkKey key)
  937. {
  938.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  939.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetChangeTime");
  940.  
  941.     SOM_TRY
  942.  
  943.     somSelf->KeyValid(ev, key);
  944.  
  945.     _fChangeTime = changeTime;
  946.     somSelf->SetBaseLinkSourceDirty(ev, kChangeTimeDirty);
  947.  
  948.     SOM_CATCH_ALL
  949.     SOM_ENDTRY
  950. }
  951.  
  952. //------------------------------------------------------------------------------
  953. // ODBaseLinkSource: IsAutoUpdate
  954. //------------------------------------------------------------------------------
  955.  
  956. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceIsAutoUpdate(ODBaseLinkSource *somSelf, Environment *ev)
  957. {
  958.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  959.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","IsAutoUpdate");
  960.  
  961.     return _fAutoUpdate;
  962. }
  963.  
  964. //------------------------------------------------------------------------------
  965. // ODBaseLinkSource: SetAutoUpdate
  966. //------------------------------------------------------------------------------
  967.  
  968. SOM_Scope void  SOMLINK ODBaseLinkSourceSetAutoUpdate(ODBaseLinkSource *somSelf, Environment *ev,
  969.         ODBoolean automatic)
  970. {
  971.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  972.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetAutoUpdate");
  973.  
  974.     SOM_TRY
  975.     _fAutoUpdate = automatic;
  976.     somSelf->SetBaseLinkSourceDirty(ev, kAutoUpdateDirty);
  977.     SOM_CATCH_ALL
  978.     SOM_ENDTRY
  979. }
  980.  
  981. //------------------------------------------------------------------------------
  982. // ODBaseLinkSource: GetLink
  983. //------------------------------------------------------------------------------
  984.  
  985. SOM_Scope ODLink*  SOMLINK ODBaseLinkSourceGetLink(ODBaseLinkSource *somSelf, Environment *ev)
  986. {
  987.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  988.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetLink");
  989.  
  990.     if ( _fLink == (ODLink*) kODNULL )
  991.     {
  992.         ODSetSOMException(ev, kODErrBrokenLink);
  993.         return (ODLink*) kODNULL;
  994.     }
  995.  
  996.     return _fLink;
  997. }
  998.  
  999. //------------------------------------------------------------------------------
  1000. // ODBaseLinkSource: SetLink
  1001. //------------------------------------------------------------------------------
  1002.  
  1003. SOM_Scope void  SOMLINK ODBaseLinkSourceSetLink(ODBaseLinkSource *somSelf, Environment *ev,
  1004.         ODLink* link)
  1005. {
  1006.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1007.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetLink");
  1008.  
  1009.     SOM_TRY
  1010.     
  1011.     if ( !ODObjectsAreEqual(ev, _fLink, link) )
  1012.     {
  1013.         ODReleaseObject(ev, _fLink);
  1014.     
  1015.         _fLink = link;
  1016.         if ( _fLink != (ODLink*) kODNULL )
  1017.             _fLink->Acquire(ev);
  1018.  
  1019.         somSelf->SetBaseLinkSourceDirty(ev, kLinkDirty);
  1020.     }
  1021.     
  1022.     SOM_CATCH_ALL
  1023.     SOM_ENDTRY
  1024. }
  1025.  
  1026. //------------------------------------------------------------------------------
  1027. // ODBaseLinkSource: AcquireSourcePart
  1028. //------------------------------------------------------------------------------
  1029.  
  1030. SOM_Scope ODStorageUnit*  SOMLINK ODBaseLinkSourceAcquireSourcePart(ODBaseLinkSource *somSelf, Environment *ev)
  1031. {
  1032.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1033.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","AcquireSourcePart");
  1034.  
  1035.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL ) {
  1036.         SOM_TRY
  1037.         _fSourcePartSU->Acquire(ev);
  1038.         SOM_CATCH_ALL
  1039.         SOM_ENDTRY
  1040.     }
  1041.     return _fSourcePartSU;
  1042. }
  1043.  
  1044. //------------------------------------------------------------------------------
  1045. // ODBaseLinkSource: SetSourcePart
  1046. //------------------------------------------------------------------------------
  1047.  
  1048. SOM_Scope void  SOMLINK ODBaseLinkSourceSetSourcePart(ODBaseLinkSource *somSelf, Environment *ev,
  1049.         ODStorageUnit* sourcePartSU)
  1050. {
  1051.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1052.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetSourcePart");
  1053.  
  1054.     SOM_TRY
  1055.  
  1056.     if ( !ODObjectsAreEqual(ev, _fSourcePartSU, sourcePartSU) )
  1057.     {
  1058.         ODReleaseObject(ev, _fSourcePartSU);
  1059.     
  1060.         _fSourcePartSU = sourcePartSU;
  1061.         if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  1062.             _fSourcePartSU->Acquire(ev);
  1063.     
  1064.         somSelf->SetBaseLinkSourceDirty(ev, kSourcePartDirty);
  1065.     }
  1066.  
  1067.     SOM_CATCH_ALL
  1068.     SOM_ENDTRY
  1069. }
  1070.  
  1071. //------------------------------------------------------------------------------
  1072. // ODBaseLinkSource: ShowSourceContent
  1073. //------------------------------------------------------------------------------
  1074.  
  1075. SOM_Scope void  SOMLINK ODBaseLinkSourceShowSourceContent(ODBaseLinkSource *somSelf, Environment *ev)
  1076. {
  1077.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1078.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ShowSourceContent");
  1079.  
  1080.     SOM_TRY
  1081.  
  1082.     if ( _fSourcePartSU == (ODStorageUnit*) kODNULL )
  1083.         THROW(kODErrBrokenLinkSource);
  1084.     
  1085.     TempODPart part = somSelf->GetStorageUnit(ev)->GetDraft(ev)->AcquirePart(ev, _fSourcePartSU->GetID(ev));
  1086.     part->RevealLink(ev, (ODLinkSource*) somSelf);
  1087.  
  1088.     SOM_CATCH_ALL
  1089.     SOM_ENDTRY
  1090. }
  1091.  
  1092. //------------------------------------------------------------------------------
  1093. // RemovePromisedContent
  1094. //------------------------------------------------------------------------------
  1095.  
  1096. static void RemovePromisedContent(Environment *ev, ODStorageUnit* su)
  1097. {
  1098.     // Remove value types that still contain promises
  1099.     if ( su && ODSUExistsThenFocus(ev, su, kODPropContents, kODNULL) )
  1100.     {
  1101.         ODULong numValues = su->CountValues(ev);    
  1102.         ODULong kindIndex;
  1103.         
  1104.         for (kindIndex = 0; kindIndex < numValues; kindIndex++)
  1105.         {
  1106.             su->Focus(ev, kODPropContents, kODPosUndefined, kODTypeAll, 0, kODPosNextSib);
  1107.             if ( su->IsPromiseValue(ev) )
  1108.                 su->Remove(ev);
  1109.         }
  1110.     }
  1111. }
  1112.