home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 21.8 KB | 780 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Content.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "ODFDraw.hpp"
-
- #ifndef CONTENT_H
- #include "Content.h"
- #endif
-
- #ifndef DRAWPART_H
- #include "DrawPart.h"
- #endif
-
- #ifndef DRAWCLIP_H
- #include "DrawClip.h"
- #endif
-
- #ifndef BASESHP_H
- #include "BaseShp.h"
- #endif
-
- #ifndef GROUPSHP_H
- #include "GroupShp.h"
- #endif
-
- #ifndef DRAWPRXY_H
- #include "DrawPrxy.h"
- #endif
-
- #ifndef UTILS_H
- #include "Utils.h"
- #endif
-
- #ifndef DRAWLINK_H
- #include "DrawLink.h"
- #endif
-
- #ifndef DRWPRMSE_H
- #include "DrwPrmse.h"
- #endif
-
- #ifndef DRAWSEL_H
- #include "DrawSel.h"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWKIND_H
- #include "FWKind.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWSUUTIL_H
- #include "FWSUUtil.h"
- #endif
-
- #ifndef FWRECT_H
- #include "FWRect.h"
- #endif
-
- #ifndef FWODGEOM_H
- #include "FWODGeom.h"
- #endif
-
- #ifndef FWSUSINK_H
- #include "FWSUSink.h"
- #endif
-
- #ifndef FWBARRAY_H
- #include "FWBArray.h"
- #endif
-
- #ifndef FWFILEAC_H
- #include "FWFileAc.h"
- #endif
-
- #ifndef SLMixOS_H
- #include "SLMixOS.h"
- #endif
-
- #ifndef FWPICTUR_H
- #include "FWPictur.h"
- #endif
-
- // ----- Foundation Layer -----
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- #ifndef FWSUSINK_H
- #include "FWSUSink.h"
- #endif
-
- #ifndef FWMEMORY_H
- #include "FWMemory.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfdraw2
- #endif
-
- FW_DEFINE_AUTO(CDrawContent)
- FW_DEFINE_AUTO(CDrawContentShapeIterator)
- FW_DEFINE_AUTO(CSemanticShapeElementIterator)
-
- //========================================================================================
- // class CDrawContent
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::CDrawContent
- //----------------------------------------------------------------------------------------
- // CDrawContent constructor
-
- CDrawContent::CDrawContent(Environment* ev, CDrawPart* part, const FW_CRect& contentRect) :
- FW_CEmbeddingContent(ev, part),
- fShapeList(NULL),
- fDrawPart(part),
- fProxyShapeCount(0),
- fContentRect(contentRect)
- {
- fShapeList = FW_NEW(CShapeCollection, ());
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::CDrawContent
- //----------------------------------------------------------------------------------------
-
- CDrawContent::CDrawContent(Environment* ev, CDrawPart* part, CDrawContent* other) :
- FW_CEmbeddingContent(ev, part),
- fShapeList(NULL),
- fDrawPart(part),
- fProxyShapeCount(0),
- fContentRect(FW_kZeroRect)
- {
- fShapeList = FW_NEW(CShapeCollection, ());
-
- if (other != NULL)
- {
- fContentRect = other->fContentRect;
-
- CDrawContentShapeIterator ite(other);
- for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
- {
- this->AddShape(ev, shape);
- }
- }
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::~CDrawContent
- //----------------------------------------------------------------------------------------
- // CDrawContent destructor
-
- CDrawContent::~CDrawContent()
- {
- FW_START_DESTRUCTOR
- delete fShapeList;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::AddShape
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::AddShape(Environment* ev, CBaseShape* shape, CBaseShape* nextShape)
- {
- if (fShapeList->Contains(shape)) return; // don't add shape twice
-
- if (nextShape == NULL)
- fShapeList->AddLast(shape);
- else
- fShapeList->AddBefore(nextShape, shape);
-
- if (shape->GetShapeType() == kProxyShape)
- {
- fProxyShapeCount++;
- }
- else if (shape->GetShapeType() == kGroupShape) // thanks, Troy!
- {
- fProxyShapeCount += ((CGroupShape*) shape)->CountProxyShapes(ev);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::RemoveShape
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::RemoveShape(Environment* ev, CBaseShape* shape)
- {
- fShapeList->Remove(shape);
-
- if (shape->GetShapeType() == kProxyShape)
- {
- fProxyShapeCount--;
- }
- else if (shape->GetShapeType() == kGroupShape)
- {
- fProxyShapeCount -= ((CGroupShape*) shape)->CountProxyShapes(ev);
- // ••• Ultimately, this might not be quite right.
- // If a proxy is removed from the group before the group is
- // removed from the content, the count here could be wrong.
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::RemoveShapeFromContent
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::RemoveShapeFromContent(Environment* ev, CBaseShape* shape)
- {
- RemoveShape(ev, shape);
- shape->Removed(ev); // notify shape
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::Count
- //----------------------------------------------------------------------------------------
-
- unsigned long CDrawContent::CountShapes() const
- {
- return fShapeList->Count();
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::Count
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::EmptyShapes(Environment* ev)
- {
- FW_UNUSED(ev);
- if (fShapeList)
- {
- fShapeList->RemoveAll();
- fProxyShapeCount = 0;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::GetFirstShape
- //----------------------------------------------------------------------------------------
-
- CBaseShape* CDrawContent::GetFirstShape() const
- {
- return fShapeList->First();
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::GetShapeAfter
- //----------------------------------------------------------------------------------------
- CBaseShape* CDrawContent::GetShapeAfter(CBaseShape* shape) const
- {
- return fShapeList->After(shape);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::IsEmpty
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CDrawContent::IsEmpty() const
- {
- return (fShapeList->Count() == 0);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::CalcUpdateShape
- //----------------------------------------------------------------------------------------
-
- ODShape* CDrawContent::CalcUpdateShape(Environment* ev)
- {
- if (this->IsEmpty())
- return NULL;
-
- ODShape* updateShape = ::FW_NewODShape(ev);
-
- FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
- FW_Boolean first = TRUE;
-
- CDrawContentShapeIterator ite(this);
- for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
- {
- shape->GetUpdateBox(ev, aqTempShape);
- if (first)
- updateShape->CopyFrom(ev, aqTempShape);
- else
- updateShape->Union(ev, aqTempShape);
-
- first = FALSE;
- }
-
- return updateShape;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::RedrawShapes
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::RedrawShapes(Environment* ev)
- {
- // Calculate the update shape and invalidate it
- FW_CAcquiredODShape updateShape = CalcUpdateShape(ev);
- if (updateShape != NULL)
- this->RedrawShape(ev, updateShape);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::RedrawShape
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::RedrawShape(Environment* ev, CBaseShape* shape)
- {
- FW_CAcquiredODShape updateShape = ::FW_NewODShape(ev);
-
- shape->GetUpdateBox(ev, updateShape);
- this->RedrawShape(ev, updateShape);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::RedrawShape
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::RedrawShape(Environment* ev, ODShape* odShape)
- {
- FW_CPresentation* presentation = fDrawPart->GetMainPresentation();
- CDrawFacetClipper facetClipper(fDrawPart);
- facetClipper.Clip(ev, presentation, odShape);
- presentation->Invalidate(ev, odShape);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::OffsetShapes
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::OffsetShapes(Environment* ev, const FW_CPoint& offset)
- {
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->OffsetShape(ev, offset.x, offset.y);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::IsOKtoWrite
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CDrawContent::IsOKtoWrite(Environment* ev, CBaseShape* shape)
- {
- FW_UNUSED(ev);
- FW_UNUSED(shape);
- return TRUE; // the default
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::PostInternalizeShape
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::PostInternalizeShape(Environment* ev,
- const FW_CPoint& offset,
- CBaseShape* shape,
- short i)
- {
- FW_UNUSED(ev);
- FW_UNUSED(offset);
- FW_UNUSED(shape);
- FW_UNUSED(i);
- // Default is to do nothing
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::ExternalizeShapeList
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::ExternalizeShapeList(Environment* ev,
- ODStorageUnit* storageUnit,
- FW_CCloneInfo* cloneInfo,
- FW_Fixed offsetX,
- FW_Fixed offsetY)
- {
- // ----- Create an archive for our shapes -----
- FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, fDrawPart->GetPartKind(ev)->GetType(ev));
- CDrawWritableStream archive(ev, suSink, suSink, cloneInfo);
-
- // ----- Write number of shapes -----
- unsigned long count = fShapeList->Count();
- archive << count;
-
- // ----- Write top, left offsets -----
- archive << offsetX;
- archive << offsetY;
-
- // ----- Write shapes -----
- short extIndex = 1; // externalization index, used by links to identify shapes
- CShapeCollectionIterator ite(fShapeList);
- for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
- {
- if (this->IsOKtoWrite(ev, theShape))
- {
- FW_WRITE_DYNAMIC_OBJECT(archive, theShape, CBaseShape);
- theShape->SetExternalizationIndex(extIndex++); // so links can write their shapes' indices
- }
- }
-
- FW_SUDeleteEndOfFocusedValue(ev, storageUnit);
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::InternalizeShapeList
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::InternalizeShapeList(Environment* ev,
- ODStorageUnit* storageUnit,
- FW_CCloneInfo* cloneInfo)
- {
- // ----- Create an Archive for our shapes -----
- FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, fDrawPart->GetPartKind(ev)->GetType(ev));
- FW_PBufferedSink sink(ev, suSink);
- CDrawReadableStream archive(ev, fDrawPart, sink, suSink, cloneInfo);
-
- // ----- Read number of shapes -----
- unsigned long count;
- archive >> count;
-
- // ----- Read top left offset -----
- FW_CPoint offset;
- archive >> offset.x;
- archive >> offset.y;
-
- for (short i = 1; i<=count; i++)
- {
- CBaseShape* theShape = NULL;
- FW_READ_DYNAMIC_OBJECT(archive, &theShape, CBaseShape);
- FW_ASSERT(theShape);
-
- // ----- Add the shape to the shape list -----
- this->AddShape(ev, theShape);
-
- // ----- Do whatever else needs to be done to the shape -----
- this->PostInternalizeShape(ev, offset, theShape, i);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawPartContent::ExternalizeKind
- //----------------------------------------------------------------------------------------
-
- void CDrawContent::ExternalizeKind(Environment* ev,
- ODStorageUnit* storageUnit,
- FW_CKind* kind,
- FW_StorageKinds storageKind,
- FW_CPromise* promise,
- FW_CCloneInfo* cloneInfo)
- {
- FW_UNUSED(kind);
-
- if (promise)
- {
- promise->Promise(ev, storageUnit, kODPropContents, kind->GetType(ev)); // just promise
- }
- else if (kind->IsPartKind(ev))
- {
- ExternalizeShapeList(ev, storageUnit, cloneInfo, fContentRect.left, fContentRect.top);
-
- if (storageKind == FW_kPartStorage)
- {
- // ----- Write links -----
- CDrawLinkManager* linkMgr = (CDrawLinkManager*) fDrawPart->GetLinkManager(ev);
- linkMgr->ExternalizeLinks(ev, storageUnit, cloneInfo);
- }
- }
- else if (kind->IsEqual(ev, 'PICT', kODPlatformDataType))
- {
- FW_CPicture picture;
-
- {
- FW_CPictureContext pc(ev, picture, fContentRect.Width(), fContentRect.Height());
-
- // ----- Draw all the shapes -----
- CDrawContentShapeIterator ite(this);
- for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
- {
- if (shape->GetShapeType() != kProxyShape)
- {
- shape->OffsetShape(ev, -fContentRect.left, -fContentRect.top);
- shape->RenderShape(ev, NULL, pc);
- shape->OffsetShape(ev, fContentRect.left, fContentRect.top);
- }
- }
- }
-
- FW_PlatformPict platformPict = picture.GetPlatformPict();
-
- unsigned long pictSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)platformPict);
-
- FW_CAcquireLockedSystemHandle lockedHandle((FW_PlatformHandle)platformPict);
-
- FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, kind->GetType(ev));
- FW_CWritableStream stream(suSink);
- stream.Write(lockedHandle.GetPointer(), pictSize);
- }
- #ifdef FW_DEBUG
- else
- FW_DEBUG_MESSAGE("CDrawPromiseContent::ExternalizeKind - unkown kind");
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::InternalizeKind
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CDrawContent::InternalizeKind(Environment* ev,
- ODStorageUnit* storageUnit,
- FW_CKind* kind,
- FW_StorageKinds storageKind,
- FW_CCloneInfo* cloneInfo)
- {
- if (kind->IsPartKind(ev))
- {
- // ----- [HLX] force promises to be fulfilled, otherwise bug in locks - OpenDoc Bug???
- if (storageKind != FW_kPartStorage)
- {
- storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kind->GetType(ev), 0, kODPosUndefined);
- storageUnit->GetSize(ev);
- }
-
- InternalizeShapeList(ev, storageUnit, cloneInfo);
-
- // ----- Read links -----
- if (storageKind == FW_kPartStorage)
- {
- CDrawLinkManager* linkMgr = (CDrawLinkManager*)fDrawPart->GetLinkManager(ev);
- linkMgr->InternalizeLinks(ev, storageUnit);
- }
- }
- #ifdef FW_DEBUG
- else
- FW_DEBUG_MESSAGE("CDrawPromiseContent::ExternalizeKind - unkown kind");
- #endif
-
- return true;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::IsDataOnlyOneProxy
- //----------------------------------------------------------------------------------------
-
- FW_MProxy* CDrawContent::IsDataOnlyOneProxy(Environment* ev) const
- {
- FW_UNUSED(ev);
- if (fProxyShapeCount == 1 && CountShapes() == 1)
- {
- CBaseShape* shape = GetFirstShape();
- FW_ASSERT(shape != NULL);
-
- if( shape->GetShapeType() == kGroupShape)
- {
- FW_ASSERT(FW_DYNAMIC_CAST(CGroupShape, shape));
- shape = ((CGroupShape*)shape)->GetFirstShape();
- }
-
- FW_ASSERT(FW_DYNAMIC_CAST(CProxyShape, shape));
- return (CProxyShape*)shape;
- }
-
- return NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContent::AddSingleEmbeddedFrame
- //----------------------------------------------------------------------------------------
-
- CProxyShape* CDrawContent::AddSingleEmbeddedFrame(Environment* ev,
- FW_CEmbeddingFrame* scopeFrame,
- ODPart* embeddedPart,
- ODFrame* embeddedFrame,
- ODShape* suggestedShape,
- ODTypeToken viewType)
- {
- // ----- Step 2: Calculate the default shape rect
- FW_CRect shapeRect;
- if (suggestedShape)
- {
- shapeRect = FW_GetShapeBoundingBox(ev, suggestedShape);
- shapeRect.Offset(-shapeRect.left, -shapeRect.top);
- }
- else
- {
- shapeRect.SetInt(0, 0, 80, 80);
- }
-
- // ----- Step 3: Calculate the shape of the embedded frame -----
- FW_CAcquiredODShape aqFrameShape = ::FW_NewODShape(ev, shapeRect);
-
- // ----- Step 4: Calculate its position -----
- // ----- We are placing it in the middle of the content view -----
- FW_CRect frameBounds = scopeFrame->GetContentView(ev)->GetBoundsInContent(ev);
- shapeRect.PlaceInCenterOf(frameBounds);
-
- // ----- Step 5: Create the proxy shape -----
- CProxyShape* proxyShape = FW_NEW(CProxyShape, (ev, shapeRect, fDrawPart));
- // Make sure that if an exception occurs before we complete this method that
- // we dispose of the shape
-
- FW_TRY
- {
- proxyShape->Embed(ev,
- scopeFrame->GetPresentation(ev),
- embeddedPart,
- embeddedFrame,
- kODFrameObject, // I want persistent frames
- aqFrameShape,
- viewType,
- NULL, // no presentation
- 0, // group id
- FALSE, // IsOverlaid
- FALSE); // sub frame
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING () {
- // cleanup for Step 5
- delete proxyShape;
- FW_THROW_SAME ();
- }
- FW_CATCH_END
-
- // Step 6: ----- Add the shape to our list -----
- this->AddShape(ev, proxyShape);
-
- return proxyShape;
- }
-
- //========================================================================================
- // class CDrawContentShapeIterator
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CDrawContentShapeIterator::CDrawContentShapeIterator
- //----------------------------------------------------------------------------------------
-
- CDrawContentShapeIterator::CDrawContentShapeIterator(CDrawContent* content) :
- CShapeCollectionIterator(content->fShapeList)
- {
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CDrawContentShapeIterator::~CDrawContentShapeIterator
- //----------------------------------------------------------------------------------------
-
- CDrawContentShapeIterator::~CDrawContentShapeIterator()
- {
- FW_START_DESTRUCTOR
- }
-
- //========================================================================================
- // class CSemanticShapeElementIterator
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CSemanticShapeElementIterator::CSemanticShapeElementIterator
- //----------------------------------------------------------------------------------------
-
- CSemanticShapeElementIterator::CSemanticShapeElementIterator(CDrawContent* content,
- ODDescType desiredClass) :
- fImplementation(content->fShapeList),
- fDesiredClass(desiredClass)
- {
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CSemanticShapeElementIterator::~CSemanticShapeElementIterator
- //----------------------------------------------------------------------------------------
-
- CSemanticShapeElementIterator::~CSemanticShapeElementIterator()
- {
- FW_START_DESTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CSemanticShapeElementIterator::First
- //----------------------------------------------------------------------------------------
-
- FW_MScriptable* CSemanticShapeElementIterator::First()
- {
- FW_MScriptable* element = fImplementation.First();
- while (element && !IsDesiredClass(element))
- element = Next();
-
- return element;
- }
-
- //----------------------------------------------------------------------------------------
- // CSemanticShapeElementIterator::Next
- //----------------------------------------------------------------------------------------
-
- FW_MScriptable* CSemanticShapeElementIterator::Next()
- {
- FW_MScriptable* element = fImplementation.Next();
- while (element && !IsDesiredClass(element))
- element = fImplementation.Next();
-
- return element;
- }
-
- //----------------------------------------------------------------------------------------
- // CSemanticShapeElementIterator::IsDesiredClass
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CSemanticShapeElementIterator::IsDesiredClass(FW_MScriptable* element) const
- {
- FW_Boolean result;
-
- switch (fDesiredClass)
- {
- case typeWildCard:
- case kShapeClass:
- result = TRUE;
- break;
-
- case cOval:
- case cLine:
- case cRectangle:
- case cRoundedRectangle:
- result = (fDesiredClass == element->GetObjectClass());
- break;
-
- default:
- result = FALSE;
- break;
- }
-
- return result;
- }
-