home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-08 | 36.1 KB | 1,048 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: DrawLink.cpp
- // Release Version: $ 1.0d11 $
- //
- // Author: Henri Lamiraux
- // Linking added by: M.Boetcher
- //
- // Copyright: © 1993, 1995 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "ODFDraw.hpp"
-
- #ifndef DRAWLINK_H
- #include "DrawLink.h"
- #endif
-
- #ifndef DRAWDEF_H
- #include "DrawDef.h"
- #endif
-
- #ifndef DRAWPART_H
- #include "DrawPart.h"
- #endif
-
- #ifndef DRAWSEL_H
- #include "DrawSel.h"
- #endif
-
- #ifndef BASESHP_H
- #include "BaseShp.h"
- #endif
-
- #ifndef BOUNDSHP_H
- #include "BoundShp.h"
- #endif
-
- #ifndef LINESHP_H
- #include "LineShp.h"
- #endif
-
- #ifndef OVALSHP_H
- #include "OvalShp.h"
- #endif
-
- #ifndef RECTSHP_H
- #include "RectShp.h"
- #endif
-
- #ifndef RRECTSHP_H
- #include "RRectShp.h"
- #endif
-
- #ifndef TEXTSHP_H
- #include "TextShp.h"
- #endif
-
- #ifndef DRAWPRXY_H
- #include "DrawPrxy.h"
- #endif
-
- // ----- Framework Includes -----
-
- #ifndef FWFRAME_H
- #include "FWFrame.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWPRTITE_H
- #include "FWPrtIte.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWPXYFRM_H
- #include "FWPxyFrm.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWCLNINF_H
- #include "FWClnInf.h"
- #endif
-
- #ifndef FWBARRAY_H
- #include "FWBArray.h"
- #endif
-
- // ----- Foundation Includes -----
-
- #ifndef FWORDCOL_H
- #include "FWOrdCol.h"
- #endif
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODUndo_xh
- #include <Undo.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODLink_xh
- #include <Link.xh>
- #endif
-
- #ifndef SOM_ODLinkSpec_xh
- #include <LinkSpec.xh>
- #endif
-
- #ifndef SOM_ODLinkSource_xh
- #include <LinkSrc.xh>
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- FW_DEFINE_CLASS_M1(CDrawPublishLink, FW_CPublishLink)
- FW_DEFINE_CLASS_M1(CDrawSubscribeLink, FW_CSubscribeLink)
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfdraw
- #endif
-
- //========================================================================================
- // Constants
- //========================================================================================
-
- const ODPropertyName kDrawPropSourceLink = "ODFDraw:Property:SourceLink";
- const ODPropertyName kDrawPropDestLink = "ODFDraw:Property:DestLink";
-
- const ODValueType kDrawLinkValue = "ODFDraw:Value";
-
- //========================================================================================
- // class CDrawPublishLink
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::CDrawPublishLink
- //----------------------------------------------------------------------------------------
-
- CDrawPublishLink::CDrawPublishLink(Environment *ev, ODUpdateID updateID,
- FW_CPresentation* presentation,
- CDrawSelection* drawSelection,
- FW_Boolean saveSelection) :
- FW_CPublishLink(ev, updateID, presentation),
- fDrawSelection(drawSelection),
- fCollection(NULL),
- fSavedSelection(NULL)
- {
- //---- Create a new collection to hold the shapes in this link source ----
- fCollection = new FW_CPrivOrderedCollection;
-
- //---- Save the selected shapes ----
- if (saveSelection)
- {
- FW_COrderedCollectionIterator ite(fDrawSelection->GetSelectionCollection());
- for (CBaseShape* shape = (CBaseShape*)ite.First(); ite.IsNotComplete(); shape = (CBaseShape*)ite.Next())
- {
- fCollection->AddLast(shape);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::~CDrawPublishLink
- //----------------------------------------------------------------------------------------
-
- CDrawPublishLink::~CDrawPublishLink()
- {
- delete fCollection;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::Publish - Override
- //----------------------------------------------------------------------------------------
-
- void CDrawPublishLink::Publish(Environment* ev)
- {
- //---- Mark the collected shapes as published
- FW_COrderedCollectionIterator ite(fCollection);
- for (CBaseShape* shape = (CBaseShape*)ite.First(); ite.IsNotComplete(); shape = (CBaseShape*)ite.Next())
- {
- shape->SetPublishLink(ev, this);
- }
-
- //--- Force the first update using a new change ID
- ODUpdateID change = fPresentation->GetPart(ev)->GetSession(ev)->UniqueUpdateID(ev);
- this->ContentUpdated(ev, change, TRUE);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::GetPublishFormat - Override
- //----------------------------------------------------------------------------------------
-
- ODValueType CDrawPublishLink::GetPublishFormat(Environment* ev)
- {
- return kPublishFormat;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::ExternalizeLinkContent - Override
- //----------------------------------------------------------------------------------------
-
- void CDrawPublishLink::ExternalizeLinkContent(Environment* ev, ODStorageUnit* linkSU)
- {
- // Remove extra properties (ODLinkSource::Clear removed only the content property)
- FW_SURemoveProperty(ev, linkSU, kODPropContentFrame);
-
- // -- Pick a frame, any frame --
- FW_CPresentationFrameIterator piter(fPresentation);
- FW_CFrame* frame = piter.First();
- FW_ASSERT(frame);
-
- // Since ExternalizeData writes the current selection,
- // we need to temporarily select the shapes to be published
- this->SelectShapes(ev);
-
- fDrawSelection->ExternalizeData(ev, frame, FW_kLinkStorage, linkSU, kODCloneToLink);
-
- // Now restore the saved selection
- this->RestoreDrawSelection(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::SelectShapes
- //----------------------------------------------------------------------------------------
- void CDrawPublishLink::SelectShapes(Environment* ev)
- {
- // Save the list of selected shapes
- fSavedSelection = fDrawSelection->GetSelectionCollection();
- fDrawSelection->CloseSelection(ev); // empty the selection
-
- // Add all our published shapes to the selection
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawSelection->AddToSelection(ev, shape, FALSE);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::RestoreDrawSelection
- //----------------------------------------------------------------------------------------
- void CDrawPublishLink::RestoreDrawSelection(Environment* ev)
- {
- fDrawSelection->CloseSelection(ev); // empty the selection
-
- // Add the saved shapes to the selection
- FW_COrderedCollectionIterator iter(fSavedSelection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawSelection->AddToSelection(ev, shape, FALSE);
- }
- fSavedSelection = NULL;
-
- // Redraw???
- fPresentation->Invalidate(ev); // force all frames to be redrawn
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::HasEmbeddedFrame
- //----------------------------------------------------------------------------------------
- FW_Boolean CDrawPublishLink::HasEmbeddedFrame(Environment *ev, ODFrame* odFrame)
- {
- // Is odFrame involved in this link source? (called by DoUpdateLinks)
-
- // --- Find out whether odFrame is involved in any link source ---
- if (odFrame->GetLinkStatus(ev) == kODInLinkSource)
- {
- // -- Find out whether odFrame is one of my frames --
- FW_CFrame* fwFrame = FW_CFrame::ODtoFWFrame(ev, odFrame);
- if (fwFrame)
- {
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- if ((shape->GetShapeType() == kProxyShape) && (((CProxyShape*)shape)->IsEmbeddedFrame(ev, odFrame)))
- return TRUE;
- }
- }
- }
-
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::GetFrameToRevealLink
- //----------------------------------------------------------------------------------------
- FW_CFrame* CDrawPublishLink::GetFrameToRevealLink(Environment* ev)
- {
- // Just return the presentation's first display frame
- FW_CPresentationFrameIterator piter(fPresentation);
- return piter.First();
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::DoSelect
- //----------------------------------------------------------------------------------------
- void CDrawPublishLink::DoSelect(Environment* ev, FW_CFrame* /*frame*/)
- {
- fDrawSelection->CloseSelection(ev); // empty the selection
-
- // Add all our published shapes to the selection
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawSelection->AddToSelection(ev, shape, TRUE); // draw selection handles
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::AddShape
- //----------------------------------------------------------------------------------------
- void CDrawPublishLink::AddShape(Environment* ev, CBaseShape* shape)
- {
- shape->SetPublishLink(ev, this);
- fCollection->AddLast(shape);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPublishLink::Externalize
- //----------------------------------------------------------------------------------------
-
- void CDrawPublishLink::Externalize(Environment* ev, ODStorageUnit* storageUnit,
- FW_CCloneInfo* cloneInfo)
- {
- //-- Storage unit must be focussed to property kDrawPropDestLink, value drawPartValueType
- fODLinkSource->Externalize(ev);
-
- ODID linkID = fODLinkSource->GetID(ev);
- if (cloneInfo != NULL)
- {
- linkID = cloneInfo->Clone(ev, linkID, 0, 0);
- }
- FW_ASSERT(linkID != kODNULL);
-
- //--- Write a reference to the link ---
- ODStorageUnitRef suRef;
- storageUnit->GetStrongStorageUnitRef(ev, linkID, suRef);
- FW_CByteArray byteArray(&suRef, sizeof(ODStorageUnitRef));
- storageUnit->SetValue(ev, byteArray);
-
- //--- Write update ID ---
- byteArray.Set(&fUpdateID, sizeof(ODUpdateID));
- storageUnit->SetValue(ev, byteArray);
-
- //--- Write the number of shapes in the link ---
- unsigned long shapeCount = fCollection->Count();
- FW_ASSERT(shapeCount != 0);
- byteArray.Set(&shapeCount, sizeof(unsigned long));
- storageUnit->SetValue(ev, byteArray);
-
- //--- Write the externalization index for each shape in the link ---
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- short extIndex = shape->GetExternalizationIndex();
- byteArray.Set(&extIndex, sizeof(short));
- storageUnit->SetValue(ev, byteArray);
- }
- }
-
- //========================================================================================
- // class CDrawSubscribeLink
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::CDrawSubscribeLink
- //----------------------------------------------------------------------------------------
-
- CDrawSubscribeLink::CDrawSubscribeLink(Environment* ev, ODLink* odLink,
- FW_CPresentation* presentation,
- CDrawSelection* drawSelection,
- ODLinkInfo* linkInfo) :
- FW_CSubscribeLink(ev, odLink, linkInfo, presentation),
- fDrawSelection(drawSelection),
- fCollection(NULL),
- fSavedSelection(NULL)
- {
- fUpdateOffset.Clear();
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::~CDrawSubscribeLink
- //----------------------------------------------------------------------------------------
-
- CDrawSubscribeLink::~CDrawSubscribeLink()
- {
- delete fCollection;
- }
-
- //---------------------------------------------------------------------------------------
- // CDrawSubscribeLink::Subscribe - Override
- //---------------------------------------------------------------------------------------
-
- void CDrawSubscribeLink::Subscribe(Environment* ev)
- {
- // SetCollection already initialized fCollection (called from DoUpdateLink)
- }
-
- //---------------------------------------------------------------------------------------
- // CDrawSubscribeLink::DoUpdateLink - Override
- //---------------------------------------------------------------------------------------
-
- void CDrawSubscribeLink::DoUpdateLink(Environment* ev, ODStorageUnit* linkContentSU)
- {
- // Read data from the linkContentSU
- FW_CPresentationFrameIterator piter(fPresentation);
- FW_CFrame* frame = piter.First();
- FW_ASSERT(frame);
-
- // Since InternalizeData reads into the current selection,
- // we need to save the selection and clear the linked shapes before reading new ones
- this->SaveAndSelectShapes(ev);
-
- fDrawSelection->InternalizeData(ev, frame, linkContentSU, kODCloneFromLink);
- this->SetCollection(ev);
-
- // Now restore the saved selection
- this->RestoreDrawSelection(ev);
-
- fPresentation->Invalidate(ev); // force all frames to be redrawn
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::SetCollection
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::SetCollection(Environment *ev)
- {
- FW_Boolean updating = (fCollection != NULL);
- if (fCollection)
- this->EmptyCollection(ev);
- else
- fCollection = new FW_CPrivOrderedCollection;
-
- FW_COrderedCollectionIterator ite(fDrawSelection->GetSelectionCollection());
- for (CBaseShape *shape = (CBaseShape*)ite.First(); ite.IsNotComplete(); shape = (CBaseShape*)ite.Next())
- {
- shape->SetSubscribeLink(ev, this);
- fCollection->AddLast(shape);
- }
-
- if (updating && fUpdateOffset != FW_kZeroPoint) // updating an existing link
- {
- // move the updated shapes to their proper position
- FW_CRect selRect;
- fDrawSelection->GetDragRect(selRect);
- fDrawSelection->OffsetSelection(ev, fUpdateOffset.x - selRect.left, fUpdateOffset.y - selRect.top);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::SelectShapes
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::SelectShapes(Environment* ev)
- {
- fDrawSelection->CloseSelection(ev); // empty the selection
-
- // Add all our subscribed shapes to the selection
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawSelection->AddToSelection(ev, shape, FALSE);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::SaveAndSelectShapes
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::SaveAndSelectShapes(Environment* ev)
- {
- // Save the list of selected shapes
- fSavedSelection = fDrawSelection->GetSelectionCollection();
- fDrawSelection->CloseSelection(ev); // empty the selection
-
- if (!fCollection) return; // fCollection is NULL when it's the first update
-
- // Add all our subscribed shapes to the selection so we can delete them
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawSelection->AddToSelection(ev, shape, FALSE);
- }
-
- // Save the selection's position
- FW_CRect tempRect;
- fDrawSelection->GetDragRect(tempRect);
- fUpdateOffset = tempRect.TopLeft();
-
- // Before deleting the link destination shapes, clear the Undo stacks to get rid of
- // any references to these doomed shapes.
- ODUndo* undo = fPresentation->GetPart(ev)->GetSession(ev)->GetUndo(ev);
- undo->ClearActionHistory(ev, kODDontRespectMarks); // dis 'em
-
- // Delete the link destination shapes; they'll be recreated when the link is updated
- fDrawSelection->DeleteSelection(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::RestoreDrawSelection
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::RestoreDrawSelection(Environment* ev)
- {
- fDrawSelection->CloseSelection(ev); // empty the selection
-
- // Add the saved shapes to the selection
- FW_COrderedCollectionIterator iter(fSavedSelection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawSelection->AddToSelection(ev, shape, FALSE);
- }
- fSavedSelection = NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::EmptyCollection
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::EmptyCollection(Environment* ev)
- {
- if (fCollection)
- {
- fCollection->RemoveAll();
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::BreakLink - Override
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::BreakLink(Environment* ev)
- {
- FW_CSubscribeLink::BreakLink(ev);
-
- //--- Erase Link Borders ---
- fPresentation->Invalidate(ev); // force all frames to be redrawn
-
- //--- Change status of embedded frames ---
- FW_COrderedCollectionIterator ite(fCollection);
- for (CBaseShape* shape = (CBaseShape*)ite.First(); ite.IsNotComplete(); shape = (CBaseShape*)ite.Next())
- {
- if (shape->GetShapeType() == kProxyShape)
- ((CProxyShape*)shape)->ChangeLinkStatus(ev, kODNotInLink);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::AddShape
- //----------------------------------------------------------------------------------------
- void CDrawSubscribeLink::AddShape(Environment* ev, CBaseShape* shape)
- {
- shape->SetSubscribeLink(ev, this);
- if (fCollection == NULL)
- fCollection = new FW_CPrivOrderedCollection;
- fCollection->AddLast(shape);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawSubscribeLink::Externalize
- //----------------------------------------------------------------------------------------
-
- void CDrawSubscribeLink::Externalize(Environment* ev, ODStorageUnit* storageUnit,
- FW_CCloneInfo* cloneInfo)
- {
- //-- Storage unit must be focused to property kDrawPropDestLink, value drawPartValueType
- fODLink->Externalize(ev);
-
- ODID linkID = fODLink->GetID(ev);
- if (cloneInfo != NULL)
- {
- linkID = cloneInfo->Clone(ev, linkID, 0, 0);
- }
- FW_ASSERT(linkID != kODNULL);
-
- //--- Write a reference to the link ---
- ODStorageUnitRef suRef;
- storageUnit->GetStrongStorageUnitRef(ev, linkID, suRef);
- FW_CByteArray byteArray(&suRef, sizeof(ODStorageUnitRef));
- storageUnit->SetValue(ev, byteArray);
-
- //--- Write link info ---
- ODType kind = fLinkInfo.kind; // save kind string
- fLinkInfo.kind = (ODType) strlen(kind) + 1; // stash its length in linkInfo
- byteArray.Set(&fLinkInfo, sizeof(ODLinkInfo));
- storageUnit->SetValue(ev, byteArray); // write out linkInfo
- byteArray.Set((void*)kind, (ODULong)fLinkInfo.kind);
- storageUnit->SetValue(ev, byteArray); // write out kind string
- fLinkInfo.kind = kind; // restore kind string
-
- //--- Write the number of shapes in the link ---
- unsigned long shapeCount = fCollection->Count();
- FW_ASSERT(shapeCount != 0);
- byteArray.Set(&shapeCount, sizeof(unsigned long));
- storageUnit->SetValue(ev, byteArray);
-
- //--- Write the export index for each shape in the link ---
- FW_COrderedCollectionIterator iter(fCollection);
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- short extIndex = shape->GetExternalizationIndex();
- byteArray.Set(&extIndex, sizeof(short));
- storageUnit->SetValue(ev, byteArray);
- }
- }
-
- //========================================================================================
- // class CDrawLinkManager
- //========================================================================================
-
- FW_DEFINE_CLASS_M1(CDrawLinkManager, FW_CLinkManager)
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager constructor
- //----------------------------------------------------------------------------------------
-
- CDrawLinkManager::CDrawLinkManager(Environment* ev, CDrawPart* thePart) :
- FW_CLinkManager(ev, (FW_CPart*)thePart),
- fDrawPart(thePart)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager destructor
- //----------------------------------------------------------------------------------------
-
- CDrawLinkManager::~CDrawLinkManager()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::NewPublishLink - Override
- //----------------------------------------------------------------------------------------
-
- FW_CPublishLink* CDrawLinkManager::NewPublishLink(Environment* ev, ODUpdateID changeID,
- FW_CPresentation* presentation)
- {
- return new CDrawPublishLink(ev, changeID,
- presentation, fDrawPart->fDrawSelection,
- TRUE); // saveSelection = TRUE
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::NewSubscribeLink - Override
- //----------------------------------------------------------------------------------------
-
- FW_CSubscribeLink* CDrawLinkManager::NewSubscribeLink(Environment* ev, ODLink *odLink,
- ODLinkInfo* linkInfo,
- FW_CPresentation* presentation)
- {
- return new CDrawSubscribeLink(ev, odLink, presentation, fDrawPart->fDrawSelection, linkInfo);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::DoChangeLinkStatus - Override
- //----------------------------------------------------------------------------------------
-
- void CDrawLinkManager::DoChangeLinkStatus(Environment* ev, ODFrame* odFrame)
- {
- // call ODFrame::ChangeLinkStatus on any embedded frames that are involved in a link
- // when a link is created, broken, moved, etc.
- // odFrame is the frame of this part whose link status has changed.
-
- FW_CEmbeddingFrame* frame = FW_CEmbeddingFrame::ODtoFWEmbeddingFrame(ev, odFrame);
- if (frame)
- {
- ODLinkStatus linkStatus = odFrame->GetLinkStatus(ev);
-
- // Only need to propagate linkStatus to embedded frames that don't participate in
- // any of this part's links; otherwise their local link status takes precedence.
-
- FW_COrderedCollectionIterator iter(fDrawPart->GetShapeList());
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- if (shape->GetShapeType() == kProxyShape)
- {
- CProxyShape* proxyShape = (CProxyShape*)shape;
- if (!proxyShape->IsPublished() && !proxyShape->IsSubscribed())
- {
- FW_CProxyEmbeddedFrameIterator efiter(ev, proxyShape);
- for (ODFrame* embFrame = efiter.First(ev); efiter.IsNotComplete(ev); embFrame = efiter.Next(ev))
- embFrame->ChangeLinkStatus(ev, linkStatus);
- }
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::DoUpdateLinks - Override
- //----------------------------------------------------------------------------------------
-
- void CDrawLinkManager::DoUpdateLinks(Environment* ev, ODFrame* odEmbeddedFrame, ODUpdateID change)
- {
- // Content displayed in the embedded frame has changed
-
- /* 1) If odEmbeddedFrame is involved in one of my link sources, update the link with new data.
- "If the part maintains the source of a link that includes the embedded frame, the
- part should update the link." (Recipe p.12) */
- if (this->CountPublishers(ev) > 0)
- {
- FW_CPartPublishIterator iter(fPart);
- for (CDrawPublishLink* publisher = (CDrawPublishLink*)iter.First(); iter.IsNotComplete();
- publisher = (CDrawPublishLink*)iter.Next())
- {
- if (publisher->HasEmbeddedFrame(ev, odEmbeddedFrame))
- {
- publisher->ContentUpdated(ev, change, FALSE);
- break;
- }
- }
- }
-
- /* 2) Call ContentUpdated on my display frames as appropriate */
- FW_CPartFrameIterator ite(fPart);
- for (FW_CFrame* frame = ite.First(); ite.IsNotComplete(); frame = ite.Next())
- {
- frame->GetODFrame(ev)->ContentUpdated(ev, change);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::CreateLink - Override
- //----------------------------------------------------------------------------------------
- ODLinkSource* CDrawLinkManager::CreateLink(Environment *ev, ODByteArray* data)
- {
- // CreateLink is overridden so that we can delete the pending publish link.
- // This prevents the link spec from being re-used to create more than one link.
-
- ODLinkSource* odLinkSource = FW_CLinkManager::CreateLink(ev, data);
- this->DeletePendingPublish(ev);
- return odLinkSource;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::UndoPasteAs
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::UndoPasteAs(Environment* ev, CDrawSubscribeLink* link)
- {
- //--- Break the link ---
- this->BreakSubscribeLink(ev, link);
-
- //--- Remove subscribed shapes from the document ---
- this->DeleteSubscribedShapes(ev, link);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::RedoPasteAs
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::RedoPasteAs(Environment* ev, CDrawSubscribeLink* link)
- {
- //-- Restore the broken link --
- this->RestoreSubscribeLink(ev, link);
-
- // When the restored link is updated, new subscriber shapes will be created
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::CommitUndone
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::CommitUndone(Environment* ev, CDrawSubscribeLink* link)
- {
- this->DeleteSubscribedShapes(ev, link);
- delete link;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::DeleteSubscribedShapes
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::DeleteSubscribedShapes(Environment* ev, CDrawSubscribeLink* link)
- {
- this->SelectSubscribedShapes(ev, link);
- fDrawPart->fDrawSelection->DeleteSelection(ev);
- link->EmptyCollection(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::SelectSubscribedShapes
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::SelectSubscribedShapes(Environment* ev, CDrawSubscribeLink* link)
- {
- fDrawPart->fDrawSelection->CloseSelection(ev); // empty the selection
-
- // Saved link contains a list of the subscribed shapes
- FW_COrderedCollectionIterator iter(link->fCollection); /* PRIVATE */
- for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
- {
- fDrawPart->fDrawSelection->AddToSelection(ev, shape, FALSE);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::GetLatestSubscriber
- //----------------------------------------------------------------------------------------
- CDrawSubscribeLink* CDrawLinkManager::GetLatestSubscriber(Environment* ev)
- {
- // Return the most recent subscriber
- FW_CPartSubscribeIterator iter(fPart);
- return (CDrawSubscribeLink*) iter.Last();
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::RevealLink - Override
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::RevealLink(Environment *ev, ODLinkSource* linkSource)
- {
- CDrawPublishLink* sourceLink = (CDrawPublishLink*) ODtoPublishLink(ev, linkSource);
- if (sourceLink == NULL) return; // not our link!?
-
- // Choose a display frame for the source content
- FW_CFrame* frame = sourceLink->GetFrameToRevealLink(ev);
- if (frame)
- {
- // Ensure the display frame is revealed
- if (!frame->GetWindow(ev)->IsActive(ev))
- frame->GetWindow(ev)->Select(ev);
-
- // ----- Activate the frame -----
- if (!frame->IsActive(ev))
- {
- FW_CFrameFacetIterator iter(ev, frame); // find a facet
- frame->ActivateFrame(ev, iter.First(ev));
- }
-
- // Select the shape(s) that make up this link source
- sourceLink->DoSelect(ev, frame);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::ExternalizeLinks
- //----------------------------------------------------------------------------------------
-
- void CDrawLinkManager::ExternalizeLinks(Environment* ev, ODStorageUnit* su,
- FW_CCloneInfo* cloneInfo)
- {
- ODValueType drawPartValueType = fDrawPart->GetPartKind(ev);
-
- //--- Write out the source links ---
- if (this->CountPublishers(ev) > 0)
- {
- //-- Make sure the correct property and value is present in the SU --
- FW_SUForceFocus(ev, su, kDrawPropSourceLink, drawPartValueType);
-
- FW_CPartPublishIterator iter(fPart);
- for (CDrawPublishLink* slink = (CDrawPublishLink*)iter.First(); iter.IsNotComplete();
- slink = (CDrawPublishLink*)iter.Next())
- {
- slink->Externalize(ev, su, cloneInfo);
- }
- }
- else
- FW_SURemoveProperty(ev, su, kDrawPropSourceLink);
-
- //--- Write out the destination links ---
- if (this->CountSubscribers(ev) > 0)
- {
- //-- Make sure the correct property and value is present in the SU --
- FW_SUForceFocus(ev, su, kDrawPropDestLink, drawPartValueType);
-
- FW_CPartSubscribeIterator iter(fPart);
- for (CDrawSubscribeLink* link = (CDrawSubscribeLink*)iter.First(); iter.IsNotComplete();
- link = (CDrawSubscribeLink*)iter.Next())
- {
- link->Externalize(ev, su, cloneInfo);
- }
- }
- else
- FW_SURemoveProperty(ev, su, kDrawPropDestLink);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::InternalizeLinks
- //----------------------------------------------------------------------------------------
-
- void CDrawLinkManager::InternalizeLinks(Environment* ev, ODStorageUnit* storageUnit)
- {
- ODValueType drawPartValueType = fDrawPart->GetPartKind(ev);
- unsigned long valueSize;
-
- if (storageUnit->Exists(ev, kDrawPropSourceLink, kODNULL, kODNULL))
- {
- storageUnit->Focus(ev, kDrawPropSourceLink, kODPosUndefined, drawPartValueType, 0, kODPosUndefined);
- valueSize = storageUnit->GetSize(ev);
- while (storageUnit->GetOffset(ev) < valueSize)
- {
- this->InternalizeOneSourceLink(ev, storageUnit);
- }
- }
-
- if (storageUnit->Exists(ev, kDrawPropDestLink, kODNULL, kODNULL))
- {
- storageUnit->Focus(ev, kDrawPropDestLink, kODPosUndefined, drawPartValueType, 0, kODPosUndefined);
- valueSize = storageUnit->GetSize(ev);
- while (storageUnit->GetOffset(ev) < valueSize)
- {
- this->InternalizeOneDestLink(ev, storageUnit);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::GetSUValue
- //----------------------------------------------------------------------------------------
-
- ODULong CDrawLinkManager::GetSUValue(Environment* ev, ODStorageUnit* su,
- unsigned long size, void *buffer)
- {
- // Convenience function; also makes code easier to read
- FW_CByteArray ba;
- ODULong bytesRead = su->GetValue(ev, size, ba);
- ba.CopyBuffer(buffer, bytesRead);
-
- return bytesRead;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::InternalizeOneDestLink
- //----------------------------------------------------------------------------------------
-
- void CDrawLinkManager::InternalizeOneDestLink(Environment* ev, ODStorageUnit* storageUnit)
- {
- //-- Storage unit must be focused to property kDrawPropDestLink, value drawPart kind
- ODStorageUnitRef suRef;
- ODLinkInfo linkInfo;
- ODDraft* suDraft = storageUnit->GetDraft(ev);
-
- GetSUValue(ev, storageUnit, kODStorageUnitRefSize, &suRef);
- if (storageUnit->IsValidStorageUnitRef(ev, suRef))
- {
- // We have a validated SU ref for the link, so read the link data
- ODLink* odLink = suDraft->AcquireLink(ev, storageUnit->GetIDFromStorageUnitRef(ev, suRef), NULL);
-
- //--- Read the link info and kind ---
- GetSUValue(ev, storageUnit, sizeof(ODLinkInfo), &linkInfo);
- // the length of the kind string was saved in the kind field
- ODType kind = (ODType) FW_CMemoryManager::AllocateBlock((ODULong)linkInfo.kind);
- GetSUValue(ev, storageUnit, (ODULong)linkInfo.kind, (void*)kind); // read the kind string
- linkInfo.kind = kind;
-
- //--- Create a subscriber object for this link ---
- CDrawSubscribeLink* destLink = new CDrawSubscribeLink(ev, odLink, fDrawPart->GetMainPresentation(), fDrawPart->fDrawSelection, &linkInfo);
-
- //--- Read the number of shapes in the link ---
- unsigned long shapeCount;
- GetSUValue(ev, storageUnit, sizeof(unsigned long), &shapeCount);
-
- //--- Read each shape index and add the shape to the source link ---
- short extIndex;
- while (shapeCount > 0)
- {
- GetSUValue(ev, storageUnit, sizeof(short), &extIndex);
- CBaseShape* shape = fDrawPart->FindShapeWithIndex(extIndex);
- if (shape)
- destLink->AddShape(ev, shape);
- shapeCount--;
- }
-
- //--- Finish subscribing ---
- this->AddToSubscribeLinkList(ev, destLink);
- destLink->HandleSubscribe(ev);
- odLink->Release(ev); // to balance AcquireLink above
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::InternalizeOneSourceLink
- //----------------------------------------------------------------------------------------
-
- void CDrawLinkManager::InternalizeOneSourceLink(Environment* ev, ODStorageUnit* storageUnit)
- {
- //-- Storage unit must be focused to property kDrawPropSourceLink, value drawPart kind
- ODStorageUnitRef suRef;
- ODUpdateID updateID;
- ODDraft* suDraft = storageUnit->GetDraft(ev);
-
- GetSUValue(ev, storageUnit, kODStorageUnitRefSize, &suRef);
- if (storageUnit->IsValidStorageUnitRef(ev, suRef))
- {
- // We have a validated SU ref for the link, so read the link source data
- ODLinkSource* odLinkSource = suDraft->AcquireLinkSource(ev, storageUnit->GetIDFromStorageUnitRef(ev, suRef));
- GetSUValue(ev, storageUnit, sizeof(ODUpdateID), &updateID);
-
- //--- Create a publish object for this source link ---
- CDrawPublishLink* sourceLink = new CDrawPublishLink(ev, updateID, fDrawPart->GetMainPresentation(), fDrawPart->fDrawSelection, FALSE);
-
- //--- Read the number of shapes in the link ---
- unsigned long shapeCount;
- GetSUValue(ev, storageUnit, sizeof(unsigned long), &shapeCount);
-
- //--- Read each shape index and add the shape to the source link ---
- short extIndex;
- while (shapeCount > 0)
- {
- GetSUValue(ev, storageUnit, sizeof(short), &extIndex);
- CBaseShape* shape = fDrawPart->FindShapeWithIndex(extIndex);
- if (shape)
- sourceLink->AddShape(ev, shape);
- shapeCount--;
- }
-
- //--- Make this publisher official ---
- sourceLink->SetODLinkSource(ev, odLinkSource);
- this->AddToPublishLinkList(ev, sourceLink);
- odLinkSource->Release(ev); // to balance AcquireLinkSource above
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawLinkManager::RegisterSubscribers
- //----------------------------------------------------------------------------------------
- void CDrawLinkManager::RegisterSubscribers(Environment* ev)
- {
- if (this->CountSubscribers(ev) > 0)
- {
- FW_CPartSubscribeIterator iter(fPart);
- for (CDrawSubscribeLink* link = (CDrawSubscribeLink*)iter.First(); iter.IsNotComplete(); link = (CDrawSubscribeLink*)iter.Next())
- {
- link->Register(ev, fPart); // auto-update link will have its LinkUpdated method called
- }
- }
- }
-