home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / LinkMgr.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  55.8 KB  |  1,903 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkMgr.cpp
  3.  
  4.     Contains:    Implementation for ODLinkManager 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>     3/26/96    CC        1288720: Removed kODULongSequence value
  13.                                     type.
  14.          <2>     3/15/96    CC        1328345: Extracted code from
  15.                                     GetLinkAEHandler to make GetLink;
  16.                                     Extracted code from RequestLinkAEHandler to
  17.                                     make UseLinkEdition.
  18.         <44>     10/8/95    TJ        Fixes Recomended by Refball
  19.         <43>     10/4/95    jpa        Added missing ODVolatiles [1285799]
  20.         <42>     10/3/95    TJ        Changes done by RefBall Team
  21.         <41>     9/27/95    eeh        1284465: use ClipStringToBytes
  22.         <40>      9/1/95    CC        1278590: Added RequestLinkAEHandler.
  23.                                     Call SetStatus and UpdateDependents if link
  24.                                     cannot be established.
  25.                                     1190727: GetLinkAEHandler: Update Edition
  26.                                     file if waiting for save.
  27.         <39>     8/30/95    EL        1279582: Storage ODVolatile problems.
  28.                                     1279832: Storage THROW_IF_NULL problems.
  29.         <38>     8/29/95    DM        1221778, 1276165:  add SuspendResume(),
  30.                                     ShowLinkUpdateAlert(), and _fSuspended-
  31.                                     UpdateLinks to let LinkMgr do update
  32.                                     alerts.
  33.         <37>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  34.         <36>     8/22/95    eeh        1276821:
  35.                                     kOpenDocShellSignature->kODShellSignature
  36.         <35>     8/15/95    CC        1275241: Moved declaration of DraftInfo
  37.                                     struct into LinkMgr.cpp.
  38.         <34>     8/12/95    TÇ        1276812 Need to use TempObjs and TempRefs
  39.                                     for exception safety and to avoid TRY
  40.                                     blocks, 1276807 Opt./Bug: use StdTypIO
  41.                                     routines for portable streaming & smaller
  42.                                     footprint
  43.         <33>      8/3/95    RR        #1257260: Collapse B classes. Remove
  44.                                     somInit methods. Don't call IsInitialized
  45.                                     or SubclassResponsibility
  46.         <32>     7/28/95    VL        1270320: Do not create draft info in
  47.                                     DraftSaved if the draft has not been opened
  48.                                     yet.
  49.         <31>     7/25/95    CC        1212338: Created class ODObjectCollection;
  50.                                     inherits from OrderedCollection but
  51.                                     overrides ElementsMatch to use
  52.                                     ODObjectsAreEqual macro.
  53.         <30>     6/26/95    TÇ        1242642 BB:Fix refcounting bugs
  54.         <29>      6/7/95    CC        1242442: CreateLink: Don't add link to
  55.                                     kODPropImportedLinkSources draft property.
  56.                                     GetLinkAEHandler: Don' t add linkSource to
  57.                                     kODPropExportedLinks draft property.
  58.                                     Removed local function
  59.                                     AppendStrongReferenceToDraftProperty.
  60.         <28>      6/2/95    CC        1255474: AcquireLinkAEHandler restored to
  61.                                     GetLinkAEHandler
  62.                                     1255474: kODAcquireLinkEventID restored to
  63.                                     kODGetLinkEventID
  64.         <27>     5/26/95    VL        1251403: Multithreading naming support.
  65.         <26>     5/22/95    CC        1251802: Added TruncateFileName.
  66.         <25>     4/25/95    CC        1242555: DeleteEditionFiles: $5 entered as
  67.                                     bug 1242448.
  68.                                     1242555: CreateLink,AcquireLinkAEHandler: $5
  69.                                     entered as bug 1242442.
  70.                                     1242625: GetDraftInfo: Use ODDeleteObject
  71.                                     instead of delete operator.
  72.         <24>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  73.                                     should take Environment* and SU* when
  74.                                     possible
  75.         <23>      3/7/95    CC        1224121 ODPart::CreateLink() and
  76.                                     ODLinkManager::CreateLink() return
  77.                                     ODLinkSource object.
  78.         <22>      3/3/95    CC        1223667 ExportOnSave() and DeleteOnSave
  79.                                     return previous setting as boolean result.
  80.         <21>     2/24/95    CC        1153783: Made edition name localizable by
  81.                                     using ReplaceIntoString.
  82.         <20>     2/15/95    CC        1220327 InitLinkManager: Call
  83.                                     InitLinkDialogs to set session global.
  84.                                     1196831 Use PStrToText; remove static
  85.                                     function NumToText.
  86.                                     1220318 BuildErrorString calls
  87.                                     ReplaceIntoString.
  88.         <19>      2/1/95    CC        1153347, 1154916, 1213004:
  89.                                     GetSectionFromEvent returns error rather
  90.                                     than throwing.
  91.                                     SectionScrollAEHandler: Alert the user via
  92.                                     the notification manager.
  93.                                     Added BuildErrorString() and NumToText().
  94.                                     Support fNMResponseUPP and fNMRecPtr
  95.                                     fields.
  96.         <18>     1/27/95    TJ        VL: some stuff.
  97.         <17>     1/26/95    VL        #???: Use updated Storage Unit Ref API.
  98.         <16>     1/19/95    CC        1210935, 1207937 Add DeleteOnSave() method.
  99.                                     1212315 Use shell's signature for Apple
  100.                                     event class.
  101.                                     1191890 - Code review changes.
  102.         <15>    12/22/94    CC        1154916  SectionScrollAEHandler: Let part
  103.                                     make process frontmost.
  104.                                     1153780 Implemented ReserveSectionID; fixed
  105.                                     bug in
  106.                                     AppendStrongReferenceToDraftProperty.
  107.         <14>    12/20/94    VL        1195012: Make Storage calls be
  108.                                     marshallable.
  109.         <13>    12/15/94    CC        1197221 Changed call to
  110.                                     ODPart::CreateLink().
  111.         <12>     12/8/94    CC        1201906 somUninit: fixed parameters to
  112.                                     AEGetEventHandler.
  113.         <11>    11/28/94    RR        Fix for Eric - check AE errors
  114.         <10>     10/4/94    CC        1190068 - Add ODLink publishers and
  115.                                     ODLinkSource subscribers to draft
  116.                                     properties.
  117.          <9>     9/29/94    RA        1189812: Mods for 68K build.
  118.          <8>     9/23/94    VL        1184272: ContainerID is now a sequence of
  119.                                     octets.
  120.          <7>     9/19/94    CC        1187316 - somUninit() must call parent
  121.                                     method last.
  122.          <6>     8/19/94    TÇ        #1159233 Remove references to j3di
  123.          <5>     8/11/94    CC        Call ODDraft::CreateLinkIterator() and
  124.                                     ODDraft::CreateLinkSourceIterator() rather
  125.                                     than ugly cast from ODDraft to CMDraft.
  126.          <4>     7/31/94    CC        Changed ODDocument parameters to ODDraft
  127.                                     since document properties have been
  128.                                     eliminated.
  129.          <3>     7/27/94    CC        Added SOM_CATCH; use
  130.                                     GetOriginatingProcessID() method of
  131.                                     ODLinkSpec class.
  132.          <2>      7/6/94    CC        Temporary work-around for nil result from
  133.                                     GetODLinkIterator(),
  134.                                     GetODLinkSourceIterator(), and
  135.                                     AcquireDocumentProperties().
  136.          <1>     6/21/94    CC        first checked in
  137.  
  138.         ------------------- CC ---- Converted to SOM
  139.  
  140.          <4>      5/9/94    MB        #1162181: Changes necessary to install MMM.
  141.          <3>      4/4/94    CC        SectionScrollAEHandler: Call link source's
  142.                                     ShowSourceContent() method for registered
  143.                                     sections. (1153347)
  144.          <2>     3/28/94    CG        1153547: XMPSessn.h renamed to XMPSessM.h
  145.          <1>     3/25/94    CC        first checked in
  146.  
  147.         ------------------- CC ---- Moved from Core to Storage subsystem and
  148.                                     renamed from LinkMgr.cpp
  149.  
  150.          <8>     3/25/94    eeh        bug #1153053: Changes for PPC nativity.
  151.          <7>     3/25/94    VL        #1147173: Draft.h to CMDraft.
  152.          <6>     3/17/94    CG        #1151392: Moved kOpenDocShellSignature from
  153.                                     ContsDef.h to StdDefs.h
  154.          <5>     3/15/94    MB        Changes to support SCpp/ASLM builds,
  155.                                     #1150864.
  156.          <4>      3/2/94    CC        CreateLink: Increment ref count of returned
  157.                                     object (1144936).  Removed DebugStrs
  158.                                     (1144942).
  159.          <3>      3/1/94    CC        Declared local functions static.
  160.          <2>     2/15/94    CC        Bug #1142928 - Added document parameter to
  161.                                     ReserveSectionID.
  162.         <12>      2/8/94    JA        Minor tweaks for CodeWarrior.
  163.         <11>      2/8/94    TÇ        Throw -> THROW & some code clean up
  164.         <10>      2/7/94    TÇ        more fixes to compile with PPC Headers
  165.          <9>      2/4/94    TÇ        fixes to compile with PPC Universal headers
  166.          <8>     1/21/94    CC        Moved InitEditionPack() call into shell;
  167.                                     ExportOnSave takes doExport parameter; made
  168.                                     RemoveAllLinksInCollection and
  169.                                     DeleteEditionFiles non-class functions.
  170.          <7>     1/18/94    CC        Added AnyLinkImported(); removed 'j3di'
  171.                                     literal.
  172.          <6>     1/14/94    CC        Added methods UnsavedExportedLinks(),
  173.                                     DraftOpened(), DraftSaved(), DraftClosed(),
  174.                                     and private support routines; added
  175.                                     DraftInfo type and fDraftInfos field.
  176.          <5>    12/22/93    CC        CreateLink - dispose targetAddress
  177.                                     descriptor.
  178.          <4>    12/22/93    CC        Added DraftOpened(); Dispose Apple event
  179.                                     descriptors in CreateLink().
  180.          <3>    12/22/93    CC        NextGlobalID() and callers uses XMPDocument
  181.                                     instead of XMPDraft.  Handle section write
  182.                                     events by calling links WriteEditionFile()
  183.                                     method.  Improved error handling in several
  184.                                     methods.
  185.          <2>    12/16/93    CC        Install handlers for Edition Manager
  186.                                     events.  Moved code from
  187.                                     XMPDraft::AcquireLink() into CreateLink().
  188.                                     Calls link objects on receiving AcquireLink and
  189.                                     Edition Manager events.
  190.          <1>     12/8/93    CC        first checked in
  191.          <2>     12/3/93    TÇ        Stop including XMPError.h, it is included
  192.                                     as ErrorDef.h inside Except.h
  193.          <1>    11/15/93    CC        first checked in
  194.     To Do:
  195.     In Progress:
  196. */
  197.  
  198. #define VARIABLE_MACROS
  199.  
  200. #define ODLinkManager_Class_Source
  201. #include <LinkMgr.xih>
  202.  
  203. #ifndef _EXCEPT_
  204. #include <Except.h>
  205. #endif
  206.  
  207. #ifndef _ODMEMORY_
  208. #include <ODMemory.h>
  209. #endif
  210.  
  211. #ifndef _ISOSTR_
  212. #include <ISOStr.h>
  213. #endif
  214.  
  215. #ifndef _PASCLSTR_
  216. #include <PasclStr.h>
  217. #endif
  218.  
  219. #ifndef SOM_Module_OpenDoc_StdProps_defined
  220. #include <StdProps.xh>
  221. #endif
  222.  
  223. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  224. #include <StdTypes.xh>
  225. #endif
  226.  
  227. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  228. #include <StdDefs.xh>
  229. #endif
  230.  
  231. #ifndef SOM_ODPart_xh
  232. #include <Part.xh>
  233. #endif
  234.  
  235. #ifndef SOM_ODSession_xh
  236. #include <ODSessn.xh>
  237. #endif
  238.  
  239. #ifndef SOM_ODContainer_xh
  240. #include <ODCtr.xh>
  241. #endif
  242.  
  243. #ifndef SOM_ODDocument_xh
  244. #include <Document.xh>
  245. #endif
  246.  
  247. #ifndef SOM_ODDraft_xh
  248. #include <Draft.xh>
  249. #endif
  250.  
  251. #ifndef SOM_ODStorageUnit_xh
  252. #include <StorageU.xh>
  253. #endif
  254.  
  255. #ifndef SOM_ODLink_xh
  256. #include <Link.xh>
  257. #endif
  258.  
  259. #ifndef SOM_ODLinkSource_xh
  260. #include <LinkSrc.xh>
  261. #endif
  262.  
  263. #ifndef SOM_ODLinkSpec_xh
  264. #include <LinkSpec.xh>
  265. #endif
  266.  
  267. #ifndef SOM_ODLinkIterator_xh
  268. #include <LinkItr.xh>
  269. #endif
  270.  
  271. #ifndef SOM_ODLinkSourceIterator_xh
  272. #include <LkSrcItr.xh>
  273. #endif
  274.  
  275. #ifndef _LINKDEFS_
  276. #include <LinkDefs.h>
  277. #endif
  278.  
  279. #ifndef _LINKDLGS_
  280. #include <LinkDlgs.h>
  281. #endif
  282.  
  283. #ifndef _ORDCOLL_
  284. #include <OrdColl.h>
  285. #endif
  286.  
  287. #ifndef _PLFMFILE_
  288. #include <PlfmFile.h>
  289. #endif
  290.  
  291. #ifndef SOM_Module_OpenDoc_Errors_defined
  292. #include <ErrorDef.xh>
  293. #endif
  294.  
  295. #ifndef __ERRORS__
  296. #include <Errors.h>
  297. #endif
  298.  
  299. #ifndef _BARRAY_
  300. #include <BArray.h>
  301. #endif
  302.  
  303. #ifndef _REFCTCOL_
  304. #include "RefCtCol.h"
  305. #endif
  306.  
  307. #ifndef _TEMPOBJ_
  308. #include <TempObj.h>
  309. #endif
  310.  
  311. #ifndef _STORUTIL_
  312. #include <StorUtil.h>
  313. #endif
  314.  
  315. #ifndef _USERSRCM_
  316. #include <UseRsrcM.h>
  317. #endif
  318.  
  319. // For smSystemScript
  320. #ifndef __SCRIPT__
  321. #include <Script.h>
  322. #endif
  323.  
  324. #ifndef __TEXTUTILS__
  325. #include <TextUtils.h>
  326. #endif
  327.  
  328. #ifndef _DLOGUTIL_
  329. #include <DlogUtil.h>
  330. #endif
  331.  
  332. #ifndef _STDTYPIO_
  333. #include <StdTypIO.h>
  334. #endif
  335.  
  336. #ifndef __GESTALT__
  337. #include <Gestalt.h>
  338. #endif
  339.  
  340. #ifndef __TOOLUTILS__
  341. #include <ToolUtils.h>
  342. #endif
  343.  
  344. #ifndef __NOTIFICATION__
  345. #include <Notification.h>
  346. #endif
  347.  
  348. #pragma segment ODLinkManager
  349.  
  350. //==============================================================================
  351. // Constants
  352. //==============================================================================
  353.  
  354. const Boolean kNotSysHandler = false;
  355.  
  356. // Apple event constants
  357. #define kODGetLinkEventID        'gtln'
  358. #define kODRequestLinkEventID    'rqln'
  359. #define keyEditionAlias            'edas'
  360. #define kODLinkSourceKey        'lksr'
  361.  
  362. const    ODUShort    kODStorageUnitRefLen    = 4;
  363. const    ODUShort    kODULongSize            = 4;
  364.  
  365. //==============================================================================
  366. // Local Function Prototypes
  367. //==============================================================================
  368. ODStatic StringPtr BuildErrorString(ODSShort strResourceID, ODError error);
  369.  
  370. ODStatic EditionContainerSpec NewEditionFile(Environment* ev,
  371.             PlatformFile* documentFile,
  372.             ODDraft* draft);
  373.     
  374. ODStatic void EditionFileName(Str255 fileName, ODUShort numb);
  375. ODStatic void TruncateFileName(Str255 fileName, Str63 numberString);
  376.     
  377. ODStatic ODULong NewEditionID(Environment *ev, ODDraft* draft);
  378.     
  379. ODStatic void RegisterPublishingLinks(Environment *ev, ODDraft* draft);
  380. ODStatic void RegisterSubscribingLinks(Environment *ev, ODDraft* draft);
  381. ODStatic void UpdateEditionFiles(Environment *ev, ODRefCntCollection* collection);
  382. ODStatic void DeleteEditionFiles(Environment *ev, ODRefCntCollection* collection);
  383. // ODStatic void RemoveAllLinksInCollection(Environment *ev, OrderedCollection* collection);
  384. ODStatic OSErr GetSectionFromEvent(const AppleEvent* theAppleEvent,
  385.                 SectionHandle* section);
  386. ODStatic void AppendULongToDraftProperty(Environment *ev,
  387.     ODDraft* draft, ODPropertyName prop, ODULong value);
  388. ODStatic ODBoolean SectionIDReserved(Environment *ev,
  389.     ODDraft* draft, ODULong requestedID);
  390. ODStatic ODULong PeekNextGlobalID(Environment *ev,
  391.     ODDraft* draft,
  392.     ODPropertyName globalProp);
  393. ODStatic ODULong ReserveGlobalID(Environment *ev,
  394.     ODDraft* draft,
  395.     ODPropertyName globalProp);
  396.  
  397. ODStatic OSErr ODPascal GetLinkAEHandler(
  398.                             const AppleEvent* theAppleEvent,
  399.                             AppleEvent* reply,
  400.                             long refCon);
  401. ODStatic OSErr ODPascal RequestLinkAEHandler(
  402.                             const AppleEvent* theAppleEvent,
  403.                             AppleEvent* reply,
  404.                             long refCon);
  405. ODStatic OSErr ODPascal SectionReadAEHandler(
  406.                             const AppleEvent* theAppleEvent,
  407.                             const AppleEvent* reply,
  408.                             long refCon);
  409. ODStatic OSErr ODPascal SectionWriteAEHandler(
  410.                             const AppleEvent* theAppleEvent,
  411.                             const AppleEvent* reply,
  412.                             long refCon);
  413. ODStatic OSErr ODPascal SectionScrollAEHandler(
  414.                             const AppleEvent* theAppleEvent,
  415.                             const AppleEvent* reply,
  416.                             long refCon);
  417.  
  418.  
  419. //==============================================================================
  420. // struct DraftInfo
  421. //==============================================================================
  422.  
  423. struct DraftInfo
  424. {
  425.     ODDraft*              draft;
  426.     ODRefCntCollection*    linksToExport;
  427.     ODRefCntCollection*    linksToDelete;
  428.     ODRefCntCollection*    newExportedLinks;
  429.     ODBoolean            linksImported;
  430. };
  431.  
  432. // ODObjectCollection is replaced by ODObjectOrdColl in RefCtCol.h in Utilities
  433.  
  434. //==============================================================================
  435. // class ODObjectCollection
  436. //==============================================================================
  437. // 
  438. // class ODObjectCollection : public OrderedCollection
  439. // {
  440. //     public:
  441. //         ODObjectCollection() : OrderedCollection()    {}
  442. //         ODVMethod ~ODObjectCollection()                {}
  443. // 
  444. //         ODMethod ODBoolean ElementsMatch(ElementType v1,ElementType v2) const;
  445. // };
  446.  
  447. //------------------------------------------------------------------------------
  448. // ODObjectCollection::ElementsMatch (OVERRIDE)
  449. //------------------------------------------------------------------------------
  450.  
  451. // ODBoolean ODObjectCollection::ElementsMatch(ElementType v1,ElementType v2) const
  452. // {
  453. //     Environment* ev = somGetGlobalEnvironment();
  454. //     return ODObjectsAreEqual(ev, (ODObject*) v1, (ODObject*) v2);
  455. // }
  456.  
  457. //==============================================================================
  458. // Static functions
  459. //==============================================================================
  460.  
  461. //------------------------------------------------------------------------------
  462. // LinkMgrNMResponse
  463. //------------------------------------------------------------------------------
  464.  
  465. ODStatic void ODPascal LinkMgrNMResponse(NMRecPtr theNMRecPtr)
  466. {
  467.     OSErr error = NMRemove(theNMRecPtr);
  468. }
  469.  
  470. //==============================================================================
  471. // class ODLinkManager
  472. //==============================================================================
  473.  
  474. //------------------------------------------------------------------------------
  475. // ODLinkManager::InitLinkManager
  476. //------------------------------------------------------------------------------
  477.  
  478. SOM_Scope void  SOMLINK ODLinkManagerInitLinkManager(ODLinkManager *somSelf, Environment *ev,
  479.         ODSession* session)
  480. {
  481.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  482.     ODLinkManagerMethodDebug("ODLinkManager","InitLinkManager");
  483.  
  484.     SOM_CATCH return;
  485.  
  486.     /* Moved from somInit. SOM itself sets fields to zero
  487.     _fSuspendedUpdateLinks = (ODRefCntCollection*) kODNULL;
  488.     _fDraftInfos = (OrderedCollection*) kODNULL;
  489.     _fNMResponseUPP = (NMUPP) kODNULL;
  490.     _fNMRecPtr = (NMRecPtr) kODNULL;
  491.     */
  492.     somSelf->InitObject(ev);
  493.     
  494.     long  gestaltResult;
  495.     OSErr result;
  496.  
  497.     // Check if the Edition manager is present
  498.     result = Gestalt(gestaltEditionMgrAttr, &gestaltResult);
  499.     THROW_IF_ERROR (result, "Error from Gestalt");
  500.  
  501.     // The mysterious 31 is the bit position as BitTst uses a convention opposite to MC68000
  502.     if ( BitTst(&gestaltResult, (31 - gestaltEditionMgrPresent)) == false )
  503.         THROW(kODErrNoEditionManager);
  504.  
  505.     InitLinkDialogs(session);
  506.  
  507.     _fSuspendedUpdateLinks = new ODRefCntCollection(ev);
  508.     _fDraftInfos = new OrderedCollection;
  509.     _fNMResponseUPP = NewNMProc(LinkMgrNMResponse);
  510.     _fNMRecPtr = (NMRecPtr) ODNewPtr(sizeof(NMRec));
  511.     THROW_IF_NULL(_fNMRecPtr);
  512.     _fNMRecPtr->nmStr = kODNULL;    
  513.  
  514.     AEEventHandlerUPP theHandlerUPP ;
  515.     theHandlerUPP = NewAEEventHandlerProc( GetLinkAEHandler ) ;
  516.     THROW_IF_ERROR(AEInstallEventHandler(kODShellSignature,
  517.             kODGetLinkEventID, theHandlerUPP, (long)somSelf, kNotSysHandler));
  518.  
  519.     theHandlerUPP = NewAEEventHandlerProc( RequestLinkAEHandler ) ;
  520.     THROW_IF_ERROR(AEInstallEventHandler(kODShellSignature,
  521.             kODRequestLinkEventID, theHandlerUPP, (long)somSelf, kNotSysHandler));
  522.  
  523.     theHandlerUPP = NewAEEventHandlerProc( SectionReadAEHandler ) ;
  524.     THROW_IF_ERROR(AEInstallEventHandler(sectionEventMsgClass, sectionReadMsgID,
  525.             theHandlerUPP, (long)somSelf, kNotSysHandler));
  526.  
  527.     theHandlerUPP = NewAEEventHandlerProc( SectionWriteAEHandler );
  528.     THROW_IF_ERROR(AEInstallEventHandler(sectionEventMsgClass, sectionWriteMsgID,
  529.             theHandlerUPP, (long)somSelf, kNotSysHandler));
  530.  
  531.     theHandlerUPP = NewAEEventHandlerProc( SectionScrollAEHandler );
  532.     THROW_IF_ERROR(AEInstallEventHandler(sectionEventMsgClass, sectionScrollMsgID,
  533.             theHandlerUPP, (long)somSelf, kNotSysHandler));
  534. }
  535.  
  536. //------------------------------------------------------------------------------
  537. // ODLinkManager::NewSectionID
  538. //------------------------------------------------------------------------------
  539.  
  540. SOM_Scope ODULong  SOMLINK ODLinkManagerNewSectionID(ODLinkManager *somSelf, Environment *ev,
  541.         ODDraft* draft)
  542. {
  543.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  544.     ODLinkManagerMethodDebug("ODLinkManager","NewSectionID");
  545.  
  546.     ODULong sectionID;
  547.  
  548.     SOM_CATCH return 0;
  549.  
  550.     do 
  551.         sectionID = ReserveGlobalID(ev, draft, kODPropSectionID);
  552.     while
  553.         ( SectionIDReserved(ev, draft, sectionID) );
  554.         
  555.     return sectionID;
  556. }
  557.  
  558. //------------------------------------------------------------------------------
  559. // ODLinkManager::ReserveSectionID
  560. //------------------------------------------------------------------------------
  561.  
  562. SOM_Scope ODBoolean  SOMLINK ODLinkManagerReserveSectionID(ODLinkManager *somSelf, Environment *ev,
  563.         ODULong sectionID,
  564.         ODDraft* draft)
  565. {
  566.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  567.     ODLinkManagerMethodDebug("ODLinkManager","ReserveSectionID");
  568.  
  569.     SOM_CATCH return kODFalse;
  570.  
  571.     ODBoolean result = kODFalse;
  572.     
  573.     if ( sectionID >= PeekNextGlobalID(ev, draft, kODPropSectionID) )
  574.         if ( !SectionIDReserved(ev, draft, sectionID) )
  575.         {
  576.             AppendULongToDraftProperty(ev, draft, kODPropReservedSectionIDs, sectionID);
  577.             result = kODTrue;
  578.         }
  579.  
  580.     return result;
  581. }
  582.  
  583. //-------------------------------------------------------------------------------------
  584. // ODLinkManager: ShowLinkUpdateAlert
  585. //-------------------------------------------------------------------------------------
  586.  
  587. SOM_Scope ODLinkUpdateResult  SOMLINK ODLinkManagerShowLinkUpdateAlert(ODLinkManager *somSelf, Environment *ev,
  588.         ODBaseLinkSource* link)
  589. {
  590.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  591.     ODLinkManagerMethodDebug("ODLinkManager","ShowLinkUpdateAlert");
  592.     
  593.     ODLinkUpdateResult result = kODLinkUpdateContinue; ODVolatile(result);
  594.  
  595.     SOM_TRY
  596.     
  597.         // When we leave the background, iterate over all the link sources
  598.         // that attempted to call ShowLinkUpdateAlert() in the background,
  599.         // showing the alert now and calling the links back with the
  600.         // resulting information.
  601.         
  602.         if ( _fInBackground )
  603.         {
  604.             result = kODLinkUpdateStop;
  605.             if ( !_fSuspendedUpdateLinks->Contains(link) )
  606.                 _fSuspendedUpdateLinks->AddLastAndAcquire(link);
  607.             result = kODLinkUpdateSuspend;
  608.         }
  609.         else
  610.         {
  611.             result = ( ::ShowLinkUpdateAlert() )? 
  612.                 kODLinkUpdateContinue : kODLinkUpdateStop;
  613.         }
  614.  
  615.     SOM_CATCH_ALL
  616.     
  617.     SOM_ENDTRY
  618.     
  619.     return result;
  620. }
  621.  
  622. //-------------------------------------------------------------------------------------
  623. // ODLinkManager: SuspendResume
  624. //-------------------------------------------------------------------------------------
  625.  
  626. #if ODDebug
  627. extern int gODButtonKeyNoEnterOkay;
  628. #endif
  629.  
  630. SOM_Scope void  SOMLINK ODLinkManagerSuspendResume(ODLinkManager *somSelf, Environment *ev,
  631.         ODEventData* event)
  632. {
  633.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  634.     ODLinkManagerMethodDebug("ODLinkManager","SuspendResume");
  635.  
  636.     const short kResumeMask = 0x01;    // High byte suspend/resume event 
  637.  
  638.     ODBoolean inBackground = (event->message & kResumeMask) == 0;
  639.     _fInBackground = inBackground;
  640.  
  641.     SOM_TRY
  642.     
  643.         // When we leave the background, show the alert and iterate over all the
  644.         // link sources that attempted to call ShowLinkUpdateAlert() in the 
  645.         // background, calling the links back with the resulting alert information.
  646.         
  647.         if ( !inBackground )
  648.         {
  649.             ODBaseLinkSource* link = (ODBaseLinkSource*) _fSuspendedUpdateLinks->RemoveFirst();
  650.             if (link)
  651.             {
  652.  
  653.                 ODLinkUpdateResult result = ( ::ShowLinkUpdateAlert() )? 
  654.                     kODLinkUpdateContinue : kODLinkUpdateStop;
  655.  
  656.                 while ( link )
  657.                 {
  658.                     TempODRefCntObject tempLink = link; // ensure it is released
  659.                     
  660.                     // Ignore errors returned by LinkUpdateAlertCompleted
  661.                     TRY
  662.                         link->LinkUpdateAlertCompleted(ev, result);
  663.                     CATCH_ALL
  664.                     ENDTRY
  665.                     
  666.                     link = (ODBaseLinkSource*) _fSuspendedUpdateLinks->RemoveFirst();
  667.                 }
  668.             }
  669.         }
  670.  
  671.     SOM_CATCH_ALL
  672.     
  673.     SOM_ENDTRY
  674. }
  675.  
  676. //------------------------------------------------------------------------------
  677. // ODLinkManager::UnsavedExportedLinks
  678. //------------------------------------------------------------------------------
  679.  
  680. SOM_Scope ODBoolean  SOMLINK ODLinkManagerUnsavedExportedLinks(ODLinkManager *somSelf, Environment *ev,
  681.         ODDraft* draft)
  682. {
  683.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  684.     ODLinkManagerMethodDebug("ODLinkManager","UnsavedExportedLinks");
  685.  
  686.     SOM_CATCH return kODFalse;
  687.  
  688.     DraftInfo* info = somSelf->GetDraftInfo(ev, draft);
  689.  
  690.     if ( info != (DraftInfo*) kODNULL ) 
  691.     {
  692.         return info->newExportedLinks->Count() > 0;
  693.     }
  694.     else
  695.         return kODFalse;
  696. }
  697.  
  698. //------------------------------------------------------------------------------
  699. // ODLinkManager::AnyLinkImported
  700. //------------------------------------------------------------------------------
  701.  
  702. SOM_Scope ODBoolean  SOMLINK ODLinkManagerAnyLinkImported(ODLinkManager *somSelf, Environment *ev,
  703.         ODDraft* draft)
  704. {
  705.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  706.     ODLinkManagerMethodDebug("ODLinkManager","AnyLinkImported");
  707.  
  708.     SOM_CATCH return kODFalse;
  709.  
  710.     DraftInfo* info = somSelf->GetDraftInfo(ev, draft);
  711.  
  712.     if ( info != (DraftInfo*) kODNULL ) 
  713.     {
  714.         return info->linksImported;
  715.     }
  716.     else
  717.         return kODFalse;
  718. }
  719.  
  720. //------------------------------------------------------------------------------
  721. // ODLinkManager::DraftOpened
  722. //------------------------------------------------------------------------------
  723.  
  724. SOM_Scope void  SOMLINK ODLinkManagerDraftOpened(ODLinkManager *somSelf, Environment *ev,
  725.         ODDraft* draft)
  726. {
  727.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  728.     ODLinkManagerMethodDebug("ODLinkManager","DraftOpened");
  729.  
  730.     SOM_CATCH return;
  731.  
  732.     DraftInfo* info = somSelf->GetDraftInfo(ev, draft);
  733.     
  734.     if ( info == (DraftInfo*) kODNULL ) 
  735.     {
  736.         somSelf->NewDraftInfo(ev, draft);
  737.         RegisterSubscribingLinks(ev, draft);
  738.         RegisterPublishingLinks(ev, draft);
  739.     }
  740. }
  741.  
  742. //------------------------------------------------------------------------------
  743. // ODLinkManager::DraftSaved
  744. //------------------------------------------------------------------------------
  745.  
  746. SOM_Scope void  SOMLINK ODLinkManagerDraftSaved(ODLinkManager *somSelf, Environment *ev,
  747.         ODDraft* draft)
  748. {
  749.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  750.     ODLinkManagerMethodDebug("ODLinkManager","DraftSaved");
  751.  
  752.     SOM_CATCH return;
  753.  
  754.     DraftInfo* info = somSelf->GetDraftInfo(ev, draft);
  755.     
  756.     if ( info != (DraftInfo*) kODNULL ) 
  757.     {
  758.         UpdateEditionFiles(ev, info->linksToExport);
  759.         // old: RemoveAllLinksInCollection(ev, info->linksToExport);
  760.         info->linksToExport->RemoveAndReleaseAll();
  761.  
  762.         DeleteEditionFiles(ev, info->linksToDelete);
  763.         // old: RemoveAllLinksInCollection(ev, info->linksToDelete);
  764.         info->linksToDelete->RemoveAndReleaseAll();
  765.  
  766.         // old: RemoveAllLinksInCollection(ev, info->newExportedLinks);
  767.         info->newExportedLinks->RemoveAndReleaseAll();
  768.         
  769.         info->linksImported = kODFalse;
  770.     }
  771.     else 
  772.     {
  773.         WARN("Draft is not opened yet.");
  774.     }
  775. }
  776.  
  777. //------------------------------------------------------------------------------
  778. // ODLinkManager::DraftClosing
  779. //------------------------------------------------------------------------------
  780.  
  781. SOM_Scope void  SOMLINK ODLinkManagerDraftClosing(ODLinkManager *somSelf, Environment *ev,
  782.         ODDraft* draft)
  783. {
  784.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  785.     ODLinkManagerMethodDebug("ODLinkManager","DraftClosing");
  786.  
  787.     SOM_CATCH return;
  788.  
  789.     DraftInfo* info = somSelf->GetDraftInfo(ev, draft);
  790.  
  791.     if ( info != (DraftInfo*) kODNULL ) 
  792.     {
  793.         // old: RemoveAllLinksInCollection(ev, info->linksToExport);
  794.         // new: info->linksToExport->RemoveAndReleaseAll();
  795.         ODDeleteObject(info->linksToExport); // calls RemoveAndReleaseAll()
  796.  
  797.         // old: RemoveAllLinksInCollection(ev, info->linksToDelete);
  798.         // new: info->linksToDelete->RemoveAndReleaseAll();
  799.         ODDeleteObject(info->linksToDelete); // calls RemoveAndReleaseAll()
  800.  
  801.         DeleteEditionFiles(ev, info->newExportedLinks);
  802.         // old: RemoveAllLinksInCollection(ev, info->newExportedLinks);
  803.         // new: info->newExportedLinks->RemoveAndReleaseAll();
  804.         ODDeleteObject(info->newExportedLinks); // calls RemoveAndReleaseAll()
  805.  
  806.         _fDraftInfos->Remove(info);
  807.         delete info;
  808.     }
  809. }
  810.  
  811. //------------------------------------------------------------------------------
  812. // ODLinkManager::ExportOnSave
  813. //------------------------------------------------------------------------------
  814.  
  815. SOM_Scope ODBoolean  SOMLINK ODLinkManagerExportOnSave(ODLinkManager *somSelf, Environment *ev,
  816.         ODLink* link,
  817.         ODBoolean doExport)
  818. {
  819.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  820.     ODLinkManagerMethodDebug("ODLinkManager","ExportOnSave");
  821.  
  822.     ODBoolean wereToExport = kODFalse;
  823.  
  824.     SOM_CATCH return kODFalse;
  825.  
  826.     DraftInfo* info = somSelf->GetDraftInfo(ev, link->GetStorageUnit(ev)->GetDraft(ev));
  827.     if ( info != (DraftInfo*) kODNULL ) 
  828.     {
  829.         wereToExport = info->linksToExport->Contains(link);
  830.         if ( wereToExport && !doExport ) 
  831.         {
  832.             info->linksToExport->RemoveAndRelease(link);
  833.             // link->Release(ev);
  834.         }
  835.         else if ( !wereToExport && doExport ) 
  836.         {
  837.             info->linksToExport->AddLastAndAcquire(link);
  838.             // link->Acquire(ev);
  839.         }
  840.     }
  841.  
  842.     return wereToExport;
  843. }
  844.  
  845. //------------------------------------------------------------------------------
  846. // ODLinkManager::DeleteOnSave
  847. //------------------------------------------------------------------------------
  848.  
  849. SOM_Scope ODBoolean  SOMLINK ODLinkManagerDeleteOnSave(ODLinkManager *somSelf, Environment *ev,
  850.         ODLink* link,
  851.         ODBoolean doDelete)
  852. {
  853.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  854.     ODLinkManagerMethodDebug("ODLinkManager","DeleteOnSave");
  855.  
  856.     ODBoolean wereToDelete = kODFalse;
  857.  
  858.     SOM_CATCH return kODFalse;
  859.  
  860.     DraftInfo* info = somSelf->GetDraftInfo(ev, link->GetStorageUnit(ev)->GetDraft(ev));
  861.     if ( info != (DraftInfo*) kODNULL ) 
  862.     {
  863.         wereToDelete = info->linksToDelete->Contains(link);
  864.         if ( wereToDelete && !doDelete ) 
  865.         {
  866.             info->linksToDelete->RemoveAndRelease(link);
  867.             // link->Release(ev);
  868.         }
  869.         else if ( !wereToDelete && doDelete )
  870.         {
  871.             info->linksToDelete->AddLastAndAcquire(link);
  872.             // link->Acquire(ev);
  873.         }
  874.     }
  875.  
  876.     return wereToDelete;
  877. }
  878.  
  879. //------------------------------------------------------------------------------
  880. // ODLinkManager::CreateLink
  881. //------------------------------------------------------------------------------
  882.  
  883. SOM_Scope ODLinkSource*  SOMLINK ODLinkManagerCreateLink(ODLinkManager *somSelf, Environment *ev,
  884.         ODDraft* draft,
  885.         ODLinkSpec* linkSpec)
  886. {
  887.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  888.     ODLinkManagerMethodDebug("ODLinkManager","CreateLink");
  889.  
  890.     ODLinkSource*            linkSource = kODNULL;    ODVolatile(linkSource);
  891.     AppleEvent                theAppleEvent, replyAppleEvent;
  892.     AEAddressDesc            targetAddress;
  893.     OSErr                    error;
  894.     ProcessSerialNumber     psn;
  895.     ProcessSerialNumber     psnLinkSource;
  896.     ODBoolean                isSamePSN;
  897.  
  898.     SOM_TRY
  899.  
  900.         // Create a link source to return
  901.         linkSource = draft->CreateLinkSource(ev, (ODPart*) kODNULL);
  902.  
  903.         // If the draft was created by this process, call the part directly
  904.         GetCurrentProcess(&psn);
  905.         linkSpec->GetOriginatingProcessID(ev, &psnLinkSource);
  906.         SameProcess(&psn, &psnLinkSource, &isSamePSN);
  907.         if ( isSamePSN )
  908.         {
  909.             TempODByteArrayStruct aliasBA;
  910.             somSelf->GetLink(ev, linkSpec, (ODByteArray*) aliasBA);
  911.             somSelf->UseLinkEdition(ev, linkSource, (ODByteArray*) aliasBA);
  912.         }
  913.         else
  914.         {
  915.             // Send an Apple Event to this process specifying a process number
  916.             // address, so the event is delivered as a high-level event
  917.             error = AECreateDesc(typeProcessSerialNumber, &psn,
  918.                                 sizeof(ProcessSerialNumber), &targetAddress);
  919.             THROW_IF_ERROR(error);
  920.             TempAEDesc tmpTargetAddress(&targetAddress);
  921.     
  922.             error = AECreateAppleEvent(kODShellSignature, kODRequestLinkEventID, 
  923.                                 &targetAddress, kAutoGenerateReturnID, 
  924.                                 kAnyTransactionID, &theAppleEvent);
  925.             THROW_IF_ERROR(error);
  926.             TempAEDesc tmpAppleEvent(&theAppleEvent);
  927.         
  928.             // Add the link spec to the Apple event
  929.             linkSpec->WriteToAppleEvent(ev, &theAppleEvent);
  930.             
  931.             // Add the source link to the Apple event
  932.             error = AEPutParamPtr(&theAppleEvent, kODLinkSourceKey, typeLongInteger,
  933.                                 &linkSource, sizeof(linkSource));
  934.             THROW_IF_ERROR(error);
  935.         
  936.             error = AESend(&theAppleEvent, &replyAppleEvent, kAENoReply | kAENeverInteract,
  937.                                 kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  938.             THROW_IF_ERROR(error);
  939.         }
  940.  
  941.     SOM_CATCH_ALL
  942.     
  943.         ODSafeReleaseObject(linkSource);
  944.         linkSource = kODNULL;
  945.  
  946.     SOM_ENDTRY
  947.  
  948.     return linkSource;
  949. }
  950.  
  951. //------------------------------------------------------------------------------
  952. // GetLinkAEHandler
  953. //------------------------------------------------------------------------------
  954.  
  955. ODStatic OSErr ODPascal GetLinkAEHandler(
  956.         const AppleEvent* theAppleEvent,
  957.         AppleEvent* reply,
  958.         long refCon)
  959. {
  960.     ODLinkManager*        somSelf = (ODLinkManager*)refCon;
  961.     Environment*        ev = somGetGlobalEnvironment ();
  962.     ODLinkSpec*            linkSpec = (ODLinkSpec*) kODNULL; ODVolatile(linkSpec);
  963.     OSErr                error = noErr;
  964.  
  965. #if ODDebug
  966.     somPrintf("ODLinkManager: Get Link event received\n");
  967. #endif
  968.  
  969.     TRY
  970.         linkSpec = new ODLinkSpec;    // Can't use factory method; no draft object!
  971.         THROW_IF_NULL(linkSpec, kODErrOutOfMemory);
  972.         linkSpec->ReadFromAppleEvent(ev, (AppleEvent*) theAppleEvent);
  973.  
  974.         TempODByteArrayStruct aliasBA;
  975.         somSelf->GetLink(ev, linkSpec, (ODByteArray*) aliasBA);
  976.  
  977.         error = AEPutParamPtr(reply, keyEditionAlias, typeAlias,
  978.                             aliasBA->_buffer, aliasBA->_length);
  979.     CATCH_ALL
  980.         // Must catch any exceptions thrown!
  981.         error = ErrorCode();
  982.     ENDTRY
  983.  
  984.     delete linkSpec;
  985.     
  986.     return error;
  987. }
  988.  
  989. //------------------------------------------------------------------------------
  990. // GetLink
  991. //------------------------------------------------------------------------------
  992.  
  993. SOM_Scope void SOMLINK ODLinkManagerGetLink(ODLinkManager *somSelf, Environment *ev,
  994.         ODLinkSpec* linkSpec,
  995.         ODByteArray* aliasData)
  996. {
  997.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  998.     ODLinkManagerMethodDebug("ODLinkManager","GetLink");
  999.  
  1000.     SOM_TRY
  1001.  
  1002.         ODPart* part = linkSpec->GetPart(ev);
  1003.  
  1004.         // If document has never been saved, refuse to create a link
  1005.         DraftInfo* info = somSelf->GetDraftInfo(ev, part->GetStorageUnit(ev)->GetDraft(ev));
  1006.         THROW_IF_NULL(info, kODErrDocNotSaved);
  1007.  
  1008.         TempODLink link = kODNULL;
  1009.         TempODByteArrayStruct partData = linkSpec->GetPartData(ev);
  1010.         ODVolatile(partData);
  1011.  
  1012.         TempODLinkSource linkSource = kODNULL;
  1013.         ODVolatile(linkSource);
  1014.  
  1015.         linkSource = part->CreateLink(ev, (ODByteArray*) partData);
  1016.         THROW_IF_NULL(linkSource, kODErrCannotCreateLink);
  1017.         link = linkSource->GetLink(ev);
  1018.         THROW_IF_NULL(link, kODErrCannotCreateLink);
  1019.         link->Acquire(ev);
  1020.     
  1021.         ODLinkKey key;    ODVolatile(key);
  1022.         if ( link->Lock(ev,0,&key) ) 
  1023.         {
  1024.             TRY
  1025.                 if ( link->GetLinkEdition(ev, key, aliasData) )
  1026.                 {
  1027.                     // If a new cross-document destination is being created, and the edition
  1028.                     // file is waiting for a save to update, force the edition file to update
  1029.                     // now so the link content is the same as the content that would be pasted.
  1030.                     // [cc; #1190727]
  1031.                     DraftInfo* info = somSelf->GetDraftInfo(ev, link->GetStorageUnit(ev)->GetDraft(ev));
  1032.                     if ( info && info->linksToExport->Contains(link) ) 
  1033.                     {
  1034.                         TRY
  1035.                             link->UpdateLinkEdition(ev, key);
  1036.                             info->linksToExport->RemoveAndRelease(link);
  1037.                         CATCH_ALL
  1038.                         ENDTRY
  1039.                     }
  1040.                 }
  1041.                 else
  1042.                 {
  1043.                     ODDraft* draft = part->GetStorageUnit(ev)->GetDraft(ev);
  1044.                     ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);;
  1045.  
  1046.                     TempPlatformFile documentFile = GetPlatformFileFromContainer(ev, container);
  1047.                     ODFileSpec documentSpec = documentFile->GetFileSpec();
  1048.  
  1049.                     EditionContainerSpec editionContainer = NewEditionFile(ev, documentFile, draft);
  1050.  
  1051.                     link->CreateLinkEdition(ev,
  1052.                                             editionContainer,
  1053.                                             &documentSpec,
  1054.                                             somSelf->NewSectionID(ev, draft),
  1055.                                             key,
  1056.                                             aliasData);
  1057.  
  1058.                     info->newExportedLinks->AddLastAndAcquire(link);
  1059.                 }
  1060.             CATCH_ALL
  1061.                 link->Unlock(ev, key);
  1062.                 RERAISE;
  1063.             ENDTRY
  1064.             link->Unlock(ev, key);
  1065.         }
  1066.             
  1067.     SOM_CATCH_ALL
  1068.     
  1069.     SOM_ENDTRY
  1070. }
  1071.  
  1072. //------------------------------------------------------------------------------
  1073. // UseLinkEdition
  1074. //------------------------------------------------------------------------------
  1075.  
  1076. SOM_Scope void SOMLINK ODLinkManagerUseLinkEdition(ODLinkManager *somSelf, Environment *ev,
  1077.         ODLinkSource* linkSource,
  1078.         ODByteArray* aliasData)
  1079. {
  1080.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  1081.     ODLinkManagerMethodDebug("ODLinkManager","UseLinkEdition");
  1082.  
  1083.     AliasHandle                aliasHandle;
  1084.     EditionContainerSpec    editionContainer;
  1085.     ODBoolean                wasChanged;
  1086.     OSErr                    error;
  1087.  
  1088.     SOM_TRY
  1089.         error = PtrToHand(aliasData->_buffer, (Handle*) &aliasHandle, aliasData->_length);
  1090.         THROW_IF_ERROR(error);
  1091.         TempODHandle editionAlias((ODHandle) aliasHandle);
  1092.  
  1093.         error = ResolveAlias(nil, aliasHandle, &editionContainer.theFile, &wasChanged);
  1094.         THROW_IF_ERROR(error);
  1095.     
  1096.         editionContainer.theFileScript = smSystemScript;
  1097.         editionContainer.thePart = kPartsNotUsed;
  1098.     
  1099.         ODDraft* draft = linkSource->GetStorageUnit(ev)->GetDraft(ev);
  1100.     
  1101.         ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);;
  1102.         ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  1103.     
  1104.         ODLinkKey key;    ODVolatile(key);
  1105.         if ( linkSource->Lock(ev,0,&key) ) 
  1106.         {
  1107.             TRY
  1108.                 linkSource->UseLinkEdition(ev,
  1109.                                     editionContainer, 
  1110.                                     &documentSpec,
  1111.                                     somSelf->NewSectionID(ev, draft),
  1112.                                     key);
  1113.             CATCH_ALL
  1114.                 linkSource->Unlock(ev, key);
  1115.                 RERAISE;
  1116.             ENDTRY
  1117.             linkSource->Unlock(ev, key);
  1118.         }
  1119.  
  1120.     SOM_CATCH_ALL
  1121.     
  1122.     SOM_ENDTRY
  1123. }
  1124.  
  1125. //------------------------------------------------------------------------------
  1126. // RequestLinkAEHandler
  1127. //------------------------------------------------------------------------------
  1128.  
  1129. ODStatic OSErr ODPascal RequestLinkAEHandler(
  1130.         const AppleEvent* requestLinkAppleEvent,
  1131.         AppleEvent* reply,
  1132.         long refCon)
  1133. {
  1134.     ODLinkManager*            somSelf = (ODLinkManager*) refCon;
  1135.     Environment*            ev = somGetGlobalEnvironment();
  1136.     AppleEvent                getLinkAppleEvent;
  1137.     AppleEvent                replyAppleEvent;
  1138.     AEAddressDesc            targetAddress;
  1139.     ProcessSerialNumber     psn;
  1140.     DescType                returnedType;
  1141.     Size                    actualSize;
  1142.     OSErr                    error;
  1143.     const long                kGetLinkReplyTimeout = 600;    // Ten seconds
  1144.     
  1145.     ODLinkSource*    linkSource = kODNULL;    ODVolatile(linkSource);
  1146.     ODLinkSpec*        linkSpec = kODNULL;        ODVolatile(linkSpec);
  1147.  
  1148.     TRY
  1149.     
  1150.         linkSpec = new ODLinkSpec;    // Can't use factory method; no draft object!
  1151.         THROW_IF_NULL(linkSpec, kODErrOutOfMemory);
  1152.  
  1153.         linkSpec->ReadFromAppleEvent(ev, (AppleEvent*) requestLinkAppleEvent);
  1154.  
  1155.         error = AEGetParamPtr(requestLinkAppleEvent, kODLinkSourceKey,
  1156.                                 typeLongInteger, &returnedType,
  1157.                                 &linkSource, sizeof(linkSource), &actualSize);
  1158.         THROW_IF_ERROR(error);
  1159.  
  1160.         // Create the GetLink event
  1161.         
  1162.         linkSpec->GetOriginatingProcessID(ev, &psn);
  1163.     
  1164.         error = AECreateDesc(typeProcessSerialNumber, &psn,
  1165.                             sizeof(ProcessSerialNumber), &targetAddress);
  1166.         THROW_IF_ERROR(error);
  1167.         TempAEDesc tmpTargetAddress(&targetAddress);
  1168.  
  1169.         error = AECreateAppleEvent(kODShellSignature, kODGetLinkEventID, 
  1170.                             &targetAddress, kAutoGenerateReturnID, 
  1171.                             kAnyTransactionID, &getLinkAppleEvent);
  1172.         THROW_IF_ERROR(error);
  1173.         TempAEDesc tmpGetLinkAppleEvent(&getLinkAppleEvent);
  1174.     
  1175.         linkSpec->WriteToAppleEvent(ev, &getLinkAppleEvent);
  1176.         
  1177.         error = AESend(&getLinkAppleEvent, &replyAppleEvent, 
  1178.                             kAEWaitReply | kAENeverInteract, kAENormalPriority,
  1179.                             kGetLinkReplyTimeout, NULL, NULL);
  1180.         TempAEDesc tmpReplyAppleEvent(&replyAppleEvent);
  1181.         THROW_IF_ERROR(error);
  1182.  
  1183.         // Process the reply
  1184.  
  1185.         TempODByteArray aliasData = ODAEGetByteArray(&replyAppleEvent, keyEditionAlias, typeAlias);
  1186.         somSelf->UseLinkEdition(ev, linkSource, aliasData);
  1187.         
  1188.     CATCH_ALL
  1189.     
  1190.         if ( linkSource )
  1191.         {
  1192.             linkSource->SetStatus(ev, kODErrCannotEstablishLink);
  1193.  
  1194.             // Ignore errors returned by UpdateDependents
  1195.             TRY
  1196.                 linkSource->GetLink(ev)->UpdateDependents(ev);
  1197.             CATCH_ALL
  1198.             ENDTRY
  1199.         }
  1200.  
  1201.     ENDTRY
  1202.  
  1203.     ODDeleteObject(linkSpec);
  1204.  
  1205.     return noErr;
  1206. }
  1207.  
  1208. //------------------------------------------------------------------------------
  1209. // SectionReadAEHandler
  1210. //------------------------------------------------------------------------------
  1211.  
  1212. ODStatic OSErr ODPascal SectionReadAEHandler(
  1213.         const AppleEvent* theAppleEvent,
  1214.         const AppleEvent* reply,
  1215.         long refCon)
  1216. {
  1217.     ODUnused(reply);
  1218.  
  1219.     ODLinkManager*        somSelf = (ODLinkManager*)refCon;
  1220.     Environment*        ev = somGetGlobalEnvironment ();
  1221.     SectionHandle        section = kODNULL;
  1222.     OSErr                error;
  1223.  
  1224.     error = GetSectionFromEvent(theAppleEvent, §ion);
  1225.  
  1226. #if ODDebug
  1227.         somPrintf("ODLinkManager: Section Read event received; section = %x, linkSource = %x\n",
  1228.                     section, (**section).refCon);
  1229. #endif
  1230.  
  1231.     if ( error == noErr )
  1232.     {
  1233.         if ( IsRegisteredSection(section) == noErr ) 
  1234.         {
  1235.             ODLinkSource* linkSource = (ODLinkSource*) (*section)->refCon;
  1236.             ODLinkKey key;
  1237.  
  1238.             if ( linkSource->Lock(ev,0,&key) ) 
  1239.             {
  1240.                 TRY
  1241.                     linkSource->ReadLinkEdition(ev,key);
  1242.                     DraftInfo* info = somSelf->GetDraftInfo(ev, linkSource->GetStorageUnit(ev)->GetDraft(ev));
  1243.                     if ( info != (DraftInfo*) kODNULL ) 
  1244.                     {
  1245.                         info->linksImported = kODTrue;
  1246.                     }
  1247.                 CATCH_ALL
  1248.                     error = ErrorCode();
  1249.                 ENDTRY
  1250.                 linkSource->Unlock(ev, key);
  1251.             }
  1252.         }
  1253.     }
  1254.  
  1255.     return error;
  1256. }
  1257.  
  1258. //------------------------------------------------------------------------------
  1259. // SectionWriteAEHandler
  1260. //------------------------------------------------------------------------------
  1261.  
  1262. ODStatic OSErr ODPascal SectionWriteAEHandler(
  1263.         const AppleEvent* theAppleEvent,
  1264.         const AppleEvent* reply,
  1265.         long refCon)
  1266. {
  1267.     ODUnused(reply);
  1268.  
  1269.     ODLinkManager*        somSelf = (ODLinkManager*)refCon;
  1270.     Environment*        ev = somGetGlobalEnvironment ();
  1271.     ODLinkKey            key;
  1272.     SectionHandle        section = kODNULL;
  1273.     OSErr                error;
  1274.  
  1275.     error = GetSectionFromEvent(theAppleEvent, §ion);
  1276.  
  1277. #if ODDebug
  1278.         somPrintf("ODLinkManager: Section Write event received; section = %x, link = %x\n",
  1279.                     section, (**section).refCon);
  1280. #endif
  1281.  
  1282.     if ( error == noErr )
  1283.     {
  1284.         if ( IsRegisteredSection(section) == noErr ) 
  1285.         {
  1286.             ODLink* link = (ODLink*) (**section).refCon;
  1287.  
  1288.             // Force ExportLinkEdition to write the edition file
  1289.             (**section).mdDate = (TimeStamp) 0;
  1290.  
  1291.             if ( link->Lock(ev,0,&key) ) 
  1292.             {
  1293.                 TRY
  1294.                     link->UpdateLinkEdition(ev, key);
  1295.                 CATCH_ALL
  1296.                     error = ErrorCode();
  1297.                 ENDTRY
  1298.                 link->Unlock(ev, key);
  1299.             }
  1300.         }
  1301.     }
  1302.  
  1303.     return error;
  1304. }
  1305.  
  1306. //------------------------------------------------------------------------------
  1307. // BuildErrorString
  1308. //------------------------------------------------------------------------------
  1309.  
  1310. ODStatic StringPtr BuildErrorString(ODSShort strResourceID, ODError error)
  1311. {
  1312.     Str63 numberString;
  1313.     Str255 msgStr;
  1314.  
  1315.     StringPtr result = kODNULL;
  1316.     
  1317.     ODSLong savedRefNum;
  1318.     BeginUsingLibraryResources(savedRefNum);
  1319.  
  1320.     NumToString(error, numberString);
  1321.     ReplaceIntoString(strResourceID, numberString, kODNULL, msgStr);
  1322.  
  1323.     if ( msgStr[0] > 0 )
  1324.     {
  1325.         ODULong ptrSize = msgStr[0]+1;
  1326.         result = (StringPtr) ODNewPtr(ptrSize);
  1327.         if ( result )
  1328.             ODBlockMove((ODPtr) &msgStr, (ODPtr) result, ptrSize);
  1329.     }
  1330.     
  1331.     EndUsingLibraryResources(savedRefNum);
  1332.     
  1333.     return result;
  1334. }
  1335.  
  1336. //------------------------------------------------------------------------------
  1337. // SectionScrollAEHandler
  1338. //------------------------------------------------------------------------------
  1339.  
  1340. ODStatic OSErr ODPascal SectionScrollAEHandler(
  1341.         const AppleEvent* theAppleEvent,
  1342.         const AppleEvent* reply,
  1343.         long refCon)
  1344. {
  1345.     ODUnused(reply);
  1346.  
  1347.     ODLinkManager*        somSelf = (ODLinkManager*)refCon;
  1348.     ODLinkManagerData*    somThis = ODLinkManagerGetData(somSelf);
  1349.     Environment*        ev = somGetGlobalEnvironment ();
  1350.     SectionHandle        section = kODNULL;
  1351.     OSErr                error;
  1352.  
  1353.     error = GetSectionFromEvent(theAppleEvent, §ion);
  1354.  
  1355. #if ODDebug
  1356.     somPrintf("ODLinkManager: Section Scroll event received; section = %x, link = %x\n",
  1357.                     section, (section ? (**section).refCon : 0));
  1358. #endif
  1359.  
  1360.     if ( error == noErr )
  1361.     {
  1362.         if ( IsRegisteredSection(section) == noErr ) 
  1363.         {
  1364.             TRY
  1365.             ODLink* link = (ODLink*) (**section).refCon;
  1366.  
  1367.             if ( link != kODNULL )
  1368.             {
  1369.                 DraftInfo* info = somSelf->GetDraftInfo(ev, link->GetStorageUnit(ev)->GetDraft(ev));
  1370.                 if ( info && info->linksToDelete && info->linksToDelete->Contains(link) ) 
  1371.                     THROW(kODErrCannotRevealLink);
  1372.                 else
  1373.                     link->ShowSourceContent(ev);
  1374.             }
  1375.             CATCH_ALL
  1376.                 error = ErrorCode();
  1377.                                 
  1378.                 NMRemove(_fNMRecPtr);    // ensure not already queued
  1379.                 _fNMRecPtr->qType = nmType;
  1380.                 _fNMRecPtr->nmMark = 0;
  1381.                 _fNMRecPtr->nmIcon = nil;
  1382.                 _fNMRecPtr->nmSound = nil;
  1383.                 ODDisposePtr((ODPtr) _fNMRecPtr->nmStr);
  1384.                 _fNMRecPtr->nmStr = BuildErrorString(kODLinkMgrCannotShowSourceID, error);
  1385.                 _fNMRecPtr->nmResp = _fNMResponseUPP;
  1386.                 error = NMInstall(_fNMRecPtr);
  1387.             ENDTRY
  1388.         }
  1389.     }
  1390.  
  1391.     return error;
  1392. }
  1393.  
  1394. //------------------------------------------------------------------------------
  1395. // NewEditionFile
  1396. //------------------------------------------------------------------------------
  1397.  
  1398. ODStatic EditionContainerSpec NewEditionFile(Environment* ev,
  1399.             PlatformFile* documentFile,
  1400.             ODDraft* draft)
  1401. {
  1402.     EditionContainerSpec    editionContainer;
  1403.     OSErr                    error;
  1404.     Str255                    documentName;
  1405.     ODFileSpec                documentSpec = documentFile->GetFileSpec();
  1406.  
  1407.     do {
  1408.         documentFile->GetAsciiName((char *) documentName, 254);
  1409.         CToPascalString((char *) documentName);
  1410.         EditionFileName(documentName, (ODUShort) NewEditionID(ev, draft));
  1411.         error = FSMakeFSSpec(documentSpec.vRefNum,
  1412.                              documentSpec.parID,
  1413.                              documentName,
  1414.                              &(editionContainer.theFile));
  1415.         }
  1416.     while (error == noErr);
  1417.  
  1418.     // Expect a file not found error
  1419.     if ( error != fnfErr )
  1420.         THROW_IF_ERROR(error);
  1421.  
  1422.     editionContainer.theFileScript = smSystemScript;
  1423.     editionContainer.thePart = kPartsNotUsed;
  1424.     
  1425.     return editionContainer;
  1426. }
  1427.  
  1428. //------------------------------------------------------------------------------
  1429. // GetSectionFromEvent
  1430. //------------------------------------------------------------------------------
  1431.  
  1432. ODStatic OSErr GetSectionFromEvent(const AppleEvent* theAppleEvent,
  1433.                 SectionHandle* section)
  1434. {
  1435.     DescType        returnedType;
  1436.     Size            actualSize;
  1437.     OSErr            error;
  1438.  
  1439.     error = AEGetParamPtr(theAppleEvent, keyDirectObject, typeSectionH, &returnedType,
  1440.                             section, sizeof(*section), &actualSize);
  1441. #if ODDebug
  1442.     if ( error != noErr )
  1443.         somPrintf("ODLinkManager: Error %d getting section from event\n", error);
  1444. #endif
  1445.  
  1446.     return error;
  1447. }
  1448.  
  1449. //------------------------------------------------------------------------------
  1450. // EditionFileName
  1451. //------------------------------------------------------------------------------
  1452.  
  1453. ODStatic void EditionFileName(Str255 fileName, ODUShort numb)
  1454. {
  1455.     Str63 numberString;
  1456.  
  1457.     NumToString(numb, numberString);
  1458.  
  1459.     TruncateFileName(fileName, numberString);
  1460.  
  1461.     ODSLong savedRefNum;
  1462.     BeginUsingLibraryResources(savedRefNum);
  1463.  
  1464.     ReplaceIntoString(kODLinkMgrEditionTemplateID, fileName, numberString, fileName);
  1465.  
  1466.     EndUsingLibraryResources(savedRefNum);
  1467. }
  1468.  
  1469. //------------------------------------------------------------------------------
  1470. // TruncateFileName
  1471. //------------------------------------------------------------------------------
  1472.  
  1473. ODStatic void TruncateFileName(Str255 fileName, Str63 numberString)
  1474. {
  1475.     const maxFileNameLength = 31;
  1476.  
  1477.     Str255 emptyString;
  1478.     emptyString[0] = (unsigned char) 0;
  1479.  
  1480.     ODSLong savedRefNum;
  1481.     BeginUsingLibraryResources(savedRefNum);
  1482.  
  1483.     ReplaceIntoString(kODLinkMgrEditionTemplateID, emptyString, numberString, emptyString);
  1484.     
  1485.     EndUsingLibraryResources(savedRefNum);
  1486.  
  1487.     if ( (StrLength(fileName)+StrLength(emptyString)) > maxFileNameLength )
  1488.         ClipStringToBytes( fileName,
  1489.                 maxFileNameLength-StrLength(emptyString), smCurrentScript );
  1490. }
  1491.  
  1492. //------------------------------------------------------------------------------
  1493. // NewEditionID
  1494. //------------------------------------------------------------------------------
  1495.  
  1496. ODStatic ODULong NewEditionID(Environment *ev, ODDraft* draft)
  1497. {
  1498.     return ReserveGlobalID(ev, draft, kODPropEditionID);
  1499. }
  1500.  
  1501. //------------------------------------------------------------------------------
  1502. // PeekNextGlobalID
  1503. //------------------------------------------------------------------------------
  1504.  
  1505. ODStatic ODULong PeekNextGlobalID(Environment *ev,
  1506.         ODDraft* draft,
  1507.         ODPropertyName globalProp)
  1508. {
  1509.     TempODStorageUnit    draftPropertiesSU = draft->AcquireDraftProperties(ev);
  1510.     ODULong            id = 0;
  1511.     
  1512.     if ( ODSUExistsThenFocus(ev, draftPropertiesSU, globalProp, kODULong) )
  1513.         StorageUnitGetValue(draftPropertiesSU, ev, sizeof(ODULong), (ODValue) &id);
  1514.  
  1515.     return ++id;
  1516. }
  1517.  
  1518. //------------------------------------------------------------------------------
  1519. // ReserveGlobalID
  1520. //------------------------------------------------------------------------------
  1521.  
  1522. ODStatic ODULong ReserveGlobalID(Environment *ev,
  1523.         ODDraft* draft,
  1524.         ODPropertyName globalProp)
  1525. {
  1526.     TempODStorageUnit    draftPropertiesSU = draft->AcquireDraftProperties(ev);
  1527.     ODULong            id = 0;
  1528.     
  1529.     ODSUForceFocus(ev, draftPropertiesSU, globalProp, kODULong);
  1530.     if ( draftPropertiesSU->GetSize(ev) > 0 )
  1531.         id = ODGetULongProp(ev, draftPropertiesSU, globalProp, kODULong);
  1532.     ++id;
  1533.     ODSetULongProp(ev, draftPropertiesSU, globalProp, kODULong, id);
  1534.     
  1535.     return id;
  1536. }
  1537.  
  1538. //------------------------------------------------------------------------------
  1539. // ODLinkManager::NewDraftInfo
  1540. //------------------------------------------------------------------------------
  1541.  
  1542. SOM_Scope void  SOMLINK ODLinkManagerNewDraftInfo(ODLinkManager *somSelf, Environment *ev,
  1543.         ODDraft* draft)
  1544. {
  1545.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  1546.     ODLinkManagerMethodDebug("ODLinkManager","NewDraftInfo");
  1547.  
  1548.     SOM_CATCH return;
  1549.  
  1550.     // Create a new info structure for this draft
  1551.     DraftInfo* info = new DraftInfo;
  1552.  
  1553.     info->draft = draft;
  1554.     info->linksToExport = new ODRefCntCollection(ev);
  1555.     info->linksToDelete = new ODRefCntCollection(ev);
  1556.     info->newExportedLinks = new ODRefCntCollection(ev);
  1557.     info->linksImported = kODFalse;
  1558.     _fDraftInfos->AddLast(info);
  1559. }
  1560.  
  1561. //------------------------------------------------------------------------------
  1562. // ODLinkManager::GetDraftInfo
  1563. //------------------------------------------------------------------------------
  1564.  
  1565. SOM_Scope DraftInfo*  SOMLINK ODLinkManagerGetDraftInfo(ODLinkManager *somSelf, Environment *ev,
  1566.         ODDraft* draft)
  1567. {
  1568.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  1569.     ODLinkManagerMethodDebug("ODLinkManager","GetDraftInfo");
  1570.  
  1571.     OrderedCollectionIterator* iter = kODNULL; ODVolatile(iter);
  1572.     
  1573.     DraftInfo* result = (DraftInfo*) kODNULL;
  1574.     
  1575.     if ( draft && _fDraftInfos )
  1576.     {
  1577.         TRY
  1578.             iter = _fDraftInfos->CreateIterator();
  1579.  
  1580.             for (DraftInfo* info = (DraftInfo*) iter->First();
  1581.                     iter->IsNotComplete();
  1582.                     info = (DraftInfo*) iter->Next() )
  1583.             {
  1584.                 if ( info && draft->IsEqualTo(ev, info->draft) ) 
  1585.                 {
  1586.                     result = info;
  1587.                     break;
  1588.                 }
  1589.             }
  1590.         CATCH_ALL
  1591.         ENDTRY
  1592.  
  1593.         ODDeleteObject(iter);
  1594.     }
  1595.  
  1596.     return result;
  1597. }
  1598.  
  1599. //------------------------------------------------------------------------------
  1600. // ODLinkManager::DeleteDraftInfos
  1601. //------------------------------------------------------------------------------
  1602.  
  1603. // SOM_Scope void  SOMLINK ODLinkManagerDeleteDraftInfos(ODLinkManager *somSelf, Environment *ev)
  1604. // {
  1605. //     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  1606. //     ODLinkManagerMethodDebug("ODLinkManager","DeleteDraftInfos");
  1607. // 
  1608. //     SOM_CATCH return;
  1609. //     
  1610. //     if (_fDraftInfos != (OrderedCollection*) kODNULL)
  1611. //     {
  1612. //         DraftInfo* info;
  1613. //         while ((info = (DraftInfo*) _fDraftInfos->First()) != (DraftInfo*) kODNULL)
  1614. //         {
  1615. //             ODDeleteObject(info->linksToExport);
  1616. //             ODDeleteObject(info->linksToDelete);
  1617. //             ODDeleteObject(info->newExportedLinks);
  1618. //             _fDraftInfos->RemoveFirst();
  1619. //             delete info;
  1620. //         }
  1621. //         ODDeleteObject(_fDraftInfos);
  1622. //     }
  1623. // }
  1624.  
  1625. //------------------------------------------------------------------------------
  1626. // ODLinkManager::somUninit
  1627. //------------------------------------------------------------------------------
  1628.  
  1629. SOM_Scope void  SOMLINK ODLinkManagersomUninit(ODLinkManager *somSelf)
  1630. {
  1631.     ODLinkManagerData *somThis = ODLinkManagerGetData(somSelf);
  1632.     ODLinkManagerMethodDebug("ODLinkManager","somUninit");
  1633.  
  1634.     AEEventHandlerUPP    toBeDisposedUPP;
  1635.     long                toBeIgnoredRefCon;
  1636.     OSErr                error;
  1637.  
  1638.     // somSelf->DeleteDraftInfos(ev);
  1639.     // It is incorrect to call methods on somSelf inside somUninit, 
  1640.     // a subclass may have already been somUninited.  See OpenDoc Building Code for details.
  1641.     // Instead the implementation of DeleteDraftInfos has been copied here.
  1642.     
  1643.     // BEGIN copy of DeleteDraftInfos implementation
  1644.     if (_fDraftInfos != (OrderedCollection*) kODNULL )
  1645.     {
  1646.         Environment* ev = somGetGlobalEnvironment();
  1647.         DraftInfo* info;
  1648.         while ((info = (DraftInfo*) _fDraftInfos->First()) != (DraftInfo*) kODNULL)
  1649.         {
  1650.             ODDeleteObject(info->linksToExport);
  1651.             ODDeleteObject(info->linksToDelete);
  1652.             ODDeleteObject(info->newExportedLinks);
  1653.             _fDraftInfos->RemoveFirst();
  1654.             delete info;
  1655.         }
  1656.         ODDeleteObject(_fDraftInfos);
  1657.     }
  1658.     // END copy of DeleteDraftInfos implementation
  1659.  
  1660.     if ( _fSuspendedUpdateLinks != (ODRefCntCollection*) kODNULL ) 
  1661.     {
  1662.         // _fSuspendedUpdateLinks->RemoveAndReleaseAll();
  1663.         ODDeleteObject(_fSuspendedUpdateLinks);
  1664.     }
  1665.  
  1666.     error = AEGetEventHandler(kODShellSignature, kODGetLinkEventID,
  1667.             &toBeDisposedUPP, &toBeIgnoredRefCon, kNotSysHandler);
  1668.     if ( error == noErr )
  1669.     {
  1670.         DisposeRoutineDescriptor(toBeDisposedUPP);
  1671.         error = AERemoveEventHandler(kODShellSignature, kODGetLinkEventID,
  1672.                     kODNULL,        // a UPP wouldn't work: it might not be ==
  1673.                     kNotSysHandler);
  1674.     }
  1675.  
  1676.     error = AEGetEventHandler(kODShellSignature, kODRequestLinkEventID,
  1677.             &toBeDisposedUPP, &toBeIgnoredRefCon, kNotSysHandler);
  1678.     if ( error == noErr )
  1679.     {
  1680.         DisposeRoutineDescriptor(toBeDisposedUPP);
  1681.         error = AERemoveEventHandler(kODShellSignature, kODRequestLinkEventID,
  1682.                     kODNULL,        // a UPP wouldn't work: it might not be ==
  1683.                     kNotSysHandler);
  1684.     }
  1685.  
  1686.     error = AEGetEventHandler(sectionEventMsgClass, sectionReadMsgID,
  1687.             &toBeDisposedUPP, &toBeIgnoredRefCon, kNotSysHandler);
  1688.     if ( error == noErr )
  1689.     {
  1690.         DisposeRoutineDescriptor(toBeDisposedUPP);
  1691.         error = AERemoveEventHandler(sectionEventMsgClass, sectionReadMsgID,
  1692.                     kODNULL,
  1693.                     kNotSysHandler);
  1694.     }
  1695.  
  1696.     error = AEGetEventHandler(sectionEventMsgClass, sectionWriteMsgID,
  1697.             &toBeDisposedUPP, &toBeIgnoredRefCon, kNotSysHandler);
  1698.     if ( error == noErr )
  1699.     {
  1700.         DisposeRoutineDescriptor(toBeDisposedUPP) ;
  1701.         error = AERemoveEventHandler(sectionEventMsgClass, sectionWriteMsgID,
  1702.                     kODNULL,
  1703.                     kNotSysHandler);
  1704.     }
  1705.  
  1706.     error = AEGetEventHandler(sectionEventMsgClass, sectionScrollMsgID,
  1707.             &toBeDisposedUPP, &toBeIgnoredRefCon, kNotSysHandler);
  1708.     if ( error == noErr )
  1709.     {
  1710.         DisposeRoutineDescriptor(toBeDisposedUPP) ;
  1711.         error = AERemoveEventHandler(sectionEventMsgClass, sectionScrollMsgID,
  1712.                     kODNULL,
  1713.                     kNotSysHandler);
  1714.     }
  1715.  
  1716.     if ( _fNMResponseUPP != kODNULL )
  1717.         DisposeRoutineDescriptor(_fNMResponseUPP);
  1718.  
  1719.     if ( _fNMRecPtr )
  1720.         ODDisposePtr((ODPtr) _fNMRecPtr->nmStr);
  1721.     ODDisposePtr(_fNMRecPtr);
  1722.  
  1723.     parent_somUninit(somSelf);
  1724. }
  1725.  
  1726. //------------------------------------------------------------------------------
  1727. // RegisterSubscribingLinks
  1728. //------------------------------------------------------------------------------
  1729.  
  1730. ODStatic void RegisterSubscribingLinks(Environment *ev, ODDraft* draft)
  1731. {
  1732.     // Internalize all link source objects; each link subscribing to an edition
  1733.     // file will register with the edition manager.
  1734.  
  1735.     ODLinkSourceIterator* iter = kODNULL;
  1736.  
  1737.     FN_CATCH
  1738.     {
  1739.         ODDeleteObject(iter);
  1740.         return;
  1741.     }
  1742.  
  1743.     iter = draft->CreateLinkSourceIterator(ev);
  1744.  
  1745.     for (ODLinkSource* linkSource = iter->First(ev);
  1746.             iter->IsNotComplete(ev);
  1747.             linkSource = iter->Next(ev) )
  1748.     {
  1749.         linkSource->Release(ev);
  1750.     }
  1751.  
  1752.     delete iter;
  1753. }
  1754.  
  1755. //------------------------------------------------------------------------------
  1756. // RegisterPublishingLinks
  1757. //------------------------------------------------------------------------------
  1758. ODStatic void RegisterPublishingLinks(Environment *ev, ODDraft* draft)
  1759. {
  1760.     // Internalize all link objects; each link publishing an edition file will 
  1761.     // register with the edition manager.
  1762.  
  1763.     ODLinkIterator* iter = kODNULL;
  1764.     
  1765.     FN_CATCH
  1766.     {
  1767.         ODDeleteObject(iter);
  1768.         return;
  1769.     }
  1770.  
  1771.     iter = draft->CreateLinkIterator(ev);
  1772.  
  1773.     for (ODLink* link = iter->First(ev);
  1774.             iter->IsNotComplete(ev);
  1775.             link = iter->Next(ev) )
  1776.     {
  1777.         link->Release(ev);
  1778.     }
  1779.  
  1780.     delete iter;
  1781. }
  1782.  
  1783. //------------------------------------------------------------------------------
  1784. // UpdateEditionFiles
  1785. //------------------------------------------------------------------------------
  1786.  
  1787. ODStatic void UpdateEditionFiles(Environment *ev, ODRefCntCollection* collection)
  1788. {
  1789.     if ( collection != kODNULL )
  1790.     {
  1791.         ODRefCntCollectionIterator iter(collection);
  1792.         ODLinkKey key;
  1793.     
  1794.         for (ODLink* link = (ODLink*) iter.First();
  1795.                 iter.IsNotComplete();
  1796.                 link = (ODLink*) iter.Next() )
  1797.         {
  1798.             if ( link->Lock(ev,0,&key) ) 
  1799.             {
  1800.                 TRY
  1801.                     link->UpdateLinkEdition(ev, key);
  1802.                 CATCH_ALL
  1803.                 ENDTRY
  1804.                 link->Unlock(ev, key);
  1805.             }
  1806.         }
  1807.     }
  1808. }
  1809.  
  1810. //------------------------------------------------------------------------------
  1811. // DeleteEditionFiles
  1812. //------------------------------------------------------------------------------
  1813.  
  1814. ODStatic void DeleteEditionFiles(Environment *ev, ODRefCntCollection* collection)
  1815. {
  1816.     if ( collection != kODNULL )
  1817.     {
  1818.         ODRefCntCollectionIterator iter(collection);
  1819.         ODLinkKey key;
  1820.     
  1821.         for (ODLink* link = (ODLink*) iter.First();
  1822.                 iter.IsNotComplete();
  1823.                 link = (ODLink*) iter.Next() )
  1824.         {
  1825.             if ( link->Lock(ev,0,&key) ) 
  1826.             {
  1827.                 TRY
  1828.                     link->DeleteLinkEdition(ev, key);
  1829.                 CATCH_ALL
  1830.                 ENDTRY
  1831.                 link->Unlock(ev, key);
  1832.             }
  1833.         }
  1834.     }
  1835. }
  1836.  
  1837. //------------------------------------------------------------------------------
  1838. // RemoveAllLinksInCollection
  1839. //------------------------------------------------------------------------------
  1840.  
  1841. // ODStatic void RemoveAllLinksInCollection(Environment *ev, ODRefCntCollection* collection)
  1842. //     // collection must contain only ODLink subclass instances
  1843. // {
  1844. //     if ( collection != kODNULL )
  1845. //     {
  1846. //         ODRefCntCollectionIterator iter(collection);
  1847. //         
  1848. //         TRY
  1849. //             for (ODLink* link = (ODLink*) iter->First();
  1850. //                     iter->IsNotComplete();
  1851. //                     link = (ODLink*) iter->Next() )
  1852. //             {
  1853. //                 ODReleaseObject(ev, link);
  1854. //             }
  1855. //         CATCH_ALL
  1856. //         ENDTRY
  1857. //     
  1858. //         collection->RemoveAll();
  1859. //     }
  1860. // }
  1861.  
  1862. //------------------------------------------------------------------------------
  1863. // AppendULongToDraftProperty
  1864. //------------------------------------------------------------------------------
  1865.  
  1866. ODStatic void AppendULongToDraftProperty(Environment *ev,
  1867.     ODDraft* draft, ODPropertyName prop, ODULong value)
  1868. {
  1869.     TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  1870.     ODSUForceFocus(ev, draftProperties, prop, kODULongSequence);
  1871.     draftProperties->SetOffset(ev, draftProperties->GetSize(ev));
  1872.     ODSetULongProp(ev, draftProperties, kODNULL, kODNULL, value);
  1873.     
  1874.     draft->SetChangedFromPrev(ev);
  1875. }
  1876.  
  1877. //------------------------------------------------------------------------------
  1878. // SectionIDReserved
  1879. //------------------------------------------------------------------------------
  1880.  
  1881. ODStatic ODBoolean SectionIDReserved(Environment *ev,
  1882.     ODDraft* draft, ODULong requestedID)
  1883. {
  1884.     ODBoolean result = kODFalse;
  1885.  
  1886.     TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  1887.  
  1888.     if ( ODSUExistsThenFocus(ev, draftProperties, kODPropReservedSectionIDs, kODULongSequence) )
  1889.     {
  1890.         ODULong size = draftProperties->GetSize(ev);
  1891.         while ( draftProperties->GetOffset(ev) < size )
  1892.         {
  1893.             if ( ODGetULongProp(ev, draftProperties, kODNULL, kODNULL) == requestedID )
  1894.             {
  1895.                 result = kODTrue;
  1896.                 break;
  1897.             }
  1898.         }
  1899.     }
  1900.  
  1901.     return result;
  1902. }
  1903.