localisation/apparchitecture/apgrfx/APGDOOR.CPP
branchSymbian2
changeset 1 8758140453c0
child 6 c108117318cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/localisation/apparchitecture/apgrfx/APGDOOR.CPP	Thu Jan 21 12:53:44 2010 +0000
@@ -0,0 +1,870 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <s32stor.h>
+#include <fbs.h>
+
+#include "APGDOOR.H"
+#include "APGICNFL.H"
+#include "APGCLI.H"
+#include "APACLN.H"
+#include "APGSTD.H"
+#include "APGPRIV.H"
+#include "APFDEF.H"
+
+#include "../apparc/TRACE.H"
+
+const TUid KUidApaDoorStateStream={0x1000012a}; // build invariant
+const TInt KHugeGranularity=4096; // 4k granularity for the door's host buffer
+// default icon size only used if door was created by a model door, set to glass, but does not support glass
+#define KDefaultIconSizeInTwips TSize(500,500)
+
+///////////////////////////////////////////
+// CApaDoor
+///////////////////////////////////////////
+
+EXPORT_C CApaDoor* CApaDoor::NewLC(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)
+/** Creates a new wrapper for the specified embedded document and places a
+pointer to it onto the cleanup stack.
+
+The door is of the specified size. The wrapper takes ownership of the document; 
+if creation of the wrapper fails, the document object is destroyed.
+
+@param aFs A file server session.
+@param aDoc The document for which the door is to be created.
+@param aDefaultIconSizeInTwips The size of the door in twips.
+@return  The new embedded document wrapper object. */
+	{
+	CApaDoor* self=new CApaDoor(aFs, aDoc,aDefaultIconSizeInTwips);
+	if (!self)
+		{
+		__ASSERT_DEBUG(aDoc.Process(), Panic(EDPanicNoProcess));
+		aDoc.Process()->DestroyDocument(&aDoc);
+		User::LeaveNoMemory();
+		}
+	CleanupStack::PushL(self);
+	self->ConstructL(); //lint !e613 Possible use of null pointer - Lint is wrong, see User::LeaveNoMemory() above
+	return self;
+	}
+
+
+EXPORT_C CApaDoor* CApaDoor::NewL(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)
+/** Creates a new wrapper for the specified embedded document.
+
+The door is of the specified size. The wrapper takes ownership of the document; 
+if creation of the wrapper fails, the document object is destroyed.
+
+@param aFs A file server session.
+@param aDoc The document for which the door is to be created.
+@param aDefaultIconSizeInTwips The size of the door in twips.
+@return  The new embedded document wrapper object. */
+	{
+	CApaDoor* self = CApaDoor::NewLC(aFs, aDoc,aDefaultIconSizeInTwips);
+	CleanupStack::Pop();
+	return self;
+	}
+
+
+EXPORT_C CApaDoor* CApaDoor::NewL(RFs& aFs, const CStreamStore& aStore,TStreamId aStreamId,CApaProcess& aProcess)
+// Creates a door and restores it
+// Should only be called by the TApaPictureFactory
+//
+	{
+	CApaDoor* self=new(ELeave) CApaDoor(aFs, aProcess);
+	CleanupStack::PushL(self);
+	self->RestoreL(aStore,aStreamId);
+	CleanupStack::Pop();
+	return self;
+	}
+
+
+CApaDoor::CApaDoor(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)
+	:iFs(aFs),
+	iApaProcess(aDoc.Process()),
+	iApaDoc(&aDoc),
+	iIconSizeInTwips(aDefaultIconSizeInTwips)
+	{__DECLARE_NAME(_S("CApaDoor"));}
+
+
+CApaDoor::CApaDoor(RFs& aFs, CApaProcess& aProcess)
+	:iFs(aFs),
+	iApaProcess(&aProcess)
+	{__DECLARE_NAME(_S("CApaDoor"));}
+
+
+EXPORT_C CApaDoor::~CApaDoor()
+/** Destructor.
+
+Frees all resources owned by the object, prior to its destruction. In particular, 
+it destroys the document, removing all references to it from the application 
+process. */
+	{
+	delete iPicture;
+	if (iApaDoc)
+		iApaProcess->DestroyDocument(iApaDoc); // removes it from the process and deletes it
+	delete iAppCaption;
+	delete iStore;
+	delete iStoreHost;
+	iApaProcess = NULL;
+	iApaDoc = NULL;
+	}
+
+
+void CApaDoor::ConstructL()
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::ConstructL"));
+	__APA_PROFILE_START(3);
+	__ASSERT_ALWAYS(iApaDoc,Panic(EPanicNoDocumentOnConstruction));
+	//
+	// check that the doc supports embedding
+	TApaAppCapabilityBuf buf;
+	__ASSERT_DEBUG(iApaDoc->Application(), Panic(EDPanicNoApplication));
+	iApaDoc->Application()->Capability(buf);
+	if (buf().iEmbeddability==TApaAppCapability::ENotEmbeddable)
+		User::Leave(KErrNotSupported);
+	//
+	__SHOW_TRACE(_L("...doc is embeddable"));
+	//
+	// set up the icon
+	SetFormatToIconL();
+	//
+	__PROFILE_END(3);
+	}
+
+TStreamId CApaDoor::StoreL(CStreamStore& aTargetStore)const
+/** Stores the embedded document in the specified store as an embedded store.
+
+This function saves the format of the door. It also stores the document, if 
+the document exists in memory, otherwise, it simply copies the stream containing 
+the embedded document into the specified store.
+
+@param aStore The store into which the embedded document is to be stored.
+@return The stream ID of the head stream for the embedded document. This stream 
+contains the stream dictionary through which the embedded document and its 
+door can be restored. */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::StoreL"));
+	__APA_PROFILE_START(4);
+	// create stream dictionary
+	CStreamDictionary* streamDic = CStreamDictionary::NewLC();
+	//
+	// stream out door's state
+	ExternalizeBaseStreamL(aTargetStore,*streamDic);
+	ExternalizeStateStreamL(aTargetStore,*streamDic);
+	//
+	// store the doc if it exists, otherwise copy the persistent data directly
+	TStreamId id;
+	RStoreWriteStream stream;
+	if (iApaDoc)
+		{
+		// create an embedded store in a new write stream
+		id = stream.CreateL(aTargetStore);
+		CEmbeddedStore* target=CEmbeddedStore::NewLC(stream); // takes ownership of stream
+		streamDic->AssignL(KUidApaDoorDocStream,id);
+		StoreDocL(*target);
+		// close the new embedded store
+		target->CommitL();
+		CleanupStack::PopAndDestroy(); // target
+		}
+	else if (iStore)
+		{
+		RStoreWriteStream trg;
+		id = trg.CreateLC(aTargetStore);
+		CopyStoreL(*iStore,trg);
+		CleanupStack::PopAndDestroy(); // trg
+		streamDic->AssignL(KUidApaDoorDocStream,id);
+		}
+	else 
+		Panic(EPanicNoDocOrStoreWhenStoring); // impossible situation
+	//
+	// store the stream dictionary and return its stream id
+	id = stream.CreateLC(aTargetStore);
+	stream<< *streamDic;
+	stream.CommitL();
+	CleanupStack::PopAndDestroy(); // stream
+	//
+	// tidy up
+	CleanupStack::PopAndDestroy(); // streamDic
+	__PROFILE_END(4);
+	return id;
+	}
+
+
+void CApaDoor::CopyStoreL(const CEmbeddedStore& aSourceStore,RWriteStream& aTargetStream)
+// static method
+// copies an embedded store containing a doc to aTargetStream
+//
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::CopyStoreL"));
+	// read the contents of aSourceStore's rootstream (so I can write it out in a mo')
+	CStreamDictionary* root=ReadStreamDictionaryLC(aSourceStore,aSourceStore.Root());
+	//
+	// copy the source store directly
+	MStreamBuf* host=aSourceStore.Host();
+	__ASSERT_DEBUG(host, Panic(EDPanicNoHostForStore));
+	TStreamPos pos=aSourceStore.Position(aSourceStore.Root());
+	host->SeekL(host->ERead,EStreamBeginning);
+	RReadStream stream(host);
+	aTargetStream.WriteL(stream,pos.Offset());
+	//
+	// write the root stream
+	aTargetStream<< *root;
+	aTargetStream.CommitL();
+	CleanupStack::PopAndDestroy(); // root
+	}
+
+EXPORT_C void CApaDoor::RestoreL(const CStreamStore& aSourceStore,TStreamId aStreamId)
+/** Restores the embedded document from the specified store.
+
+The format of the door is set to iconic if the embedded document is password 
+protected.
+
+@param aStore The store from which the embedded document is to be restored. 
+@param aHeadStreamId The stream ID of the head stream for the embedded document. 
+This stream contains the stream dictionary through which the embedded document 
+and its door can be restored. */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::RestoreL"));
+	__APA_PROFILE_START(5);
+	__ASSERT_DEBUG(iApaProcess,Panic(EDPanicNoProcess));
+	//
+	if (iApaDoc)
+		{
+		iApaProcess->DestroyDocument(iApaDoc);
+		iApaDoc = NULL;
+		}
+	delete iStore;
+	delete iStoreHost;
+	iStore=NULL;
+	iStoreHost = NULL;
+	//
+	// internalize the streamDic from the headstream
+	CStreamDictionary* streamDic=ReadStreamDictionaryLC(aSourceStore,aStreamId);
+	//
+	// internalize the door's state
+	__APA_PROFILE_START(13);
+	TSize currentSize=InternalizeBaseStreamL(aSourceStore,*streamDic);
+	InternalizeStateStreamL(aSourceStore,*streamDic,currentSize);
+	__APA_PROFILE_END(13);
+	//
+	// internalize the embedded store
+	__APA_PROFILE_START(14);
+	RStoreReadStream src;
+	src.OpenL(aSourceStore,streamDic->At(KUidApaDoorDocStream));
+	iStore = CEmbeddedStore::FromL(src);
+	CleanupStack::PopAndDestroy(); // streamDic
+	streamDic = NULL;
+	__APA_PROFILE_END(14);
+	//
+	// internalize the doc's stream dict
+	streamDic = ReadStreamDictionaryLC(*iStore,iStore->Root());
+	//
+	// set the door's format 
+	if (iFormat==EIconic || (streamDic->At(KUidSecurityStream)!=KNullStreamId))
+		// iconify automatically if a password is required for access
+		SetFormatToIconL();
+	else
+		{
+		TRAPD(ret, SetFormatToGlassL() );
+		if (ret==KErrNone)
+			{
+			__ASSERT_DEBUG(iPicture, Panic(EDPanicNoPictureOnDrawing));
+			iPicture->SetSizeInTwips(currentSize);
+			}
+		else if (ret!=KErrNoMemory)
+			// problem loading app/doc - just iconify it for now...
+			SetFormatToIconL();
+		else
+			User::Leave(ret);
+		}	
+	CleanupStack::PopAndDestroy(); // streamDic
+	__PROFILE_END(5);
+	}
+
+
+void CApaDoor::StoreDocL(CPersistentStore& aTargetStore)const
+// stores the doc if it's in memory, otherwise panics!
+// aStore should be protected before calling this method
+//
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::StoreDocL"));
+	__ASSERT_ALWAYS(iApaDoc,Panic(EPanicNoDocumentOnStore)); // the doc must be in memory to be stored
+	//
+	// create a stream dic
+	CStreamDictionary* streamDic=CStreamDictionary::NewLC();
+	// store the doc
+	iApaDoc->StoreL(aTargetStore,*streamDic);
+	// write store's root stream
+	CApaProcess::WriteRootStreamL(aTargetStore,*streamDic,*iApaDoc->Application());
+	// tidy up
+	CleanupStack::PopAndDestroy(); // streamDic
+	}
+
+
+void CApaDoor::RestoreDocL(const CPersistentStore& aSourceStore)
+// restores the document from the embedded store
+// leaves with KErrNotFound if the app dll cant be located
+//
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::RestoreDocL"));
+	__ASSERT_ALWAYS(!iApaDoc,Panic(EPanicDocAlreadyExists));
+	//
+	// read the stream dic from the doc's root stream
+	CStreamDictionary* streamDic=ReadStreamDictionaryLC(aSourceStore,aSourceStore.Root());
+	//
+	// read the app id from the store
+	TApaAppIdentifier appId = CApaProcess::ReadAppIdentifierL(aSourceStore,*streamDic);
+	//
+	__ASSERT_DEBUG(iApaProcess,Panic(EDPanicNoProcess));
+	// if the app exists find it, load it and create a doc, else leave if the correct app cannot be found
+	CApaDocument* doc = // create an unrestored doc and adds it to the process list
+	iApaProcess->AddNewDocumentL(appId.iAppUid);
+	TApaDocCleanupItem cleanup(iApaProcess,doc);
+	CleanupStack::PushL(cleanup);
+	doc->RestoreL(aSourceStore,*streamDic); // restores the doc
+	iApaDoc = doc;
+	CleanupStack::Pop(); // doc
+	CleanupStack::PopAndDestroy(); // streamDic
+	}
+
+
+CStreamDictionary* CApaDoor::ReadStreamDictionaryLC(const CStreamStore& aSourceStore,TStreamId aStreamId)
+// static method
+//
+	{
+	__APA_PROFILE_START(12);
+	// read the stream dic from the doc's root stream
+	CStreamDictionary* streamDic=CStreamDictionary::NewLC();
+	RStoreReadStream stream;
+	stream.OpenLC(aSourceStore,aStreamId);
+	stream>> *streamDic;
+	CleanupStack::PopAndDestroy(); // root
+	__APA_PROFILE_END(12);
+	return streamDic;
+	}
+
+
+void CApaDoor::ExternalizeL(RWriteStream& /*aStream*/)const
+	{
+	Panic(EPanicMethodNotSupported);
+	}
+
+
+void CApaDoor::ExternalizeStateStreamL(CStreamStore& aStore,CStreamDictionary& aStreamDict)const
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::ExternalizeStateStreamL"));
+	__ASSERT_ALWAYS(iAppCaption,Panic(EPanicNoCaption));
+	__ASSERT_ALWAYS(iPicture,Panic(EPanicNoPictureInDoor));
+	RStoreWriteStream stream;
+	TStreamId id=stream.CreateLC(aStore);
+	//
+	stream<< *iAppCaption;
+	TSize size;
+	if (iFormat==EIconic || iFormat==ETemporarilyIconic)
+		GetSizeInTwips(size);
+	else 
+		size = iIconSizeInTwips;
+	stream<< size;
+	//
+	stream.CommitL();
+	CleanupStack::PopAndDestroy(); // stream
+	aStreamDict.AssignL(KUidApaDoorStateStream,id);
+	}
+
+
+void CApaDoor::InternalizeStateStreamL(const CStreamStore& aStore,const CStreamDictionary& aStreamDict,TSize aDefaultIconSize)
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::InternalizeStateStreamL"));
+	TStreamId id=aStreamDict.At(KUidApaDoorStateStream);
+	if (id!=KNullStreamId)
+		{
+		RStoreReadStream stream;
+		stream.OpenLC(aStore,id);
+		TApaAppCaption caption;
+		stream>> caption;
+		delete iAppCaption;
+		iAppCaption = NULL;
+		iAppCaption = caption.AllocL();
+		stream>> iIconSizeInTwips;
+		CleanupStack::PopAndDestroy(); // stream
+		}
+	else
+		{// use default settings
+		delete iAppCaption;
+		iAppCaption = NULL;
+		iAppCaption = HBufC::NewL(0);
+		if (iFormat==EIconic)
+			iIconSizeInTwips = aDefaultIconSize;
+		else
+			iIconSizeInTwips = KDefaultIconSizeInTwips;
+		}
+	}
+
+
+void CApaDoor::DetachFromStoreL(TDetach aDegree)
+/** Detaches the door from its store, restoring any unrestored elements of the picture, 
+if necessary.
+
+@param aDegree Degree to which picture is detached.
+@see CApaDocument::DetachFromStoreL() */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::DetachFromStoreL"));
+	if (iApaDoc)
+		{
+		iApaDoc->DetachFromStoreL(aDegree);
+		if (!iStoreHost)
+			{
+			delete iStore;
+			iStore = NULL;
+			}
+		}
+	else if (!iStoreHost)
+		{
+		if (aDegree==EDetachDraw)
+			{
+			delete iStore;
+			iStore = NULL;
+			// now all I can do is draw as I am, any attempt to change me will result in a panic
+			}
+		else
+			{
+			__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnDetach));
+			// instantiate the mem buffer, and a stream to write to it
+			CBufSeg* bufSeg = CBufSeg::NewL(KHugeGranularity);
+			CleanupStack::PushL(bufSeg);
+			HBufBuf* buf=HBufBuf::NewL(*bufSeg,0);
+			RWriteStream writeStream(buf);
+			writeStream.PushL();
+			// write the store to the mem buffer
+			CopyStoreL(*iStore,writeStream);
+			CleanupStack::Pop(2); // bufSeg,writeStream
+			//
+			// set iStoreHost as host for the embedded store
+			MStreamBuf* host=iStore->Host();
+			__ASSERT_ALWAYS(host!=NULL,Panic(EDPanicNoHostForStore));
+			iStore->Detach();
+			host->Release(); //lint !e613 Suppress possible use of null pointer
+			iStore->Reattach(buf);
+			iStoreHost = bufSeg;
+			}
+		}
+	}
+
+
+EXPORT_C CApaDocument* CApaDoor::DocumentL(TBool aCheckPassword)
+// leaves with KErrNotFound if the doc needs to be restored but the app dll cannot be found
+//
+/** Returns a pointer to the embedded document represented by this wrapper.
+
+If necessary, the document is restored from its embedded store.
+
+Note that if the wrapper does not have a reference to the embedded document 
+store, then the function raises a APGRFX 13 panic. Constructing this wrapper 
+through a TApaPictureFactory or storing the embedded document through CApaDoor::StoreL() 
+ensures that this wrapper has a reference to the embedded document store.
+
+@param aCheckPassword If ETrue, any password is checked before returning a 
+pointer to the document. If EFalse, the password is not checked.
+@return A pointer to the embedded document.
+@see TApaPictureFactory
+@see CApaDoor::StoreL()
+@see CApaDocument::ValidatePasswordL() */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::DocumentL"));
+	//
+	if (!iApaDoc)
+		{
+		__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnRestore));
+		RestoreDocL(*iStore);
+		}
+	else if (aCheckPassword)
+		iApaDoc->ValidatePasswordL();
+	//
+	return iApaDoc;
+	}
+
+EXPORT_C void CApaDoor::SetFormatToTemporaryIconL(TBool aEnabled)
+// if the door is currently iconic do nothing
+// if the door is glass switch it's format to iconic, but ensure that when externalized the format will be persisted as glass
+//
+/** Switches the format of the door between temporarily iconic and glass.
+
+If the door is iconic, then the function does nothing.
+
+@param aEnabled If ETrue and the format is currently glass, then the format 
+switches to temporarily iconic; this is the default. If EFalse and the format 
+is currently temporarily iconic, then the format switches to glass. */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::SetFormatToTemporaryIconL"));
+	if (aEnabled && iFormat==EGlassDoor) 
+		{
+		TSize glassSize;
+		GetSizeInTwips(glassSize);
+		SetFormatToIconL();
+		iFormat = ETemporarilyIconic;
+		iIconSizeInTwips = glassSize; //abuse it!
+		}
+	else if (!aEnabled && iFormat==ETemporarilyIconic)
+		SetFormatToGlassL();
+	}
+
+#ifdef __VC32__
+#pragma optimize("g", off) // Disable due to problem with MSVC
+#endif
+EXPORT_C void CApaDoor::SetFormatToIconL()
+/** Sets the format of the door to iconic.
+
+The application's icon is used, or, if this cannot be found, the default icon 
+is used instead. The function leaves only if construction of the default icon 
+object fails. */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::SetFormatToIconL"));
+	__APA_PROFILE_START(6);
+	if (iFormat==ETemporarilyIconic && iPicture)
+		{
+		GetSizeInTwips(iIconSizeInTwips);
+		iFormat = EIconic;
+		}
+	else if (iFormat!=EIconic || !iPicture)
+		{
+		TUid appUid;
+		if (iApaDoc)
+			{
+			__ASSERT_DEBUG(iApaDoc->Application(), Panic(EDPanicNoApplication));
+			appUid = iApaDoc->Application()->AppDllUid();
+			}
+		else
+			{
+			appUid = AppUidFromStreamL();
+			}
+
+		TInt ret=KErrNone;
+		if (!iAppCaption)
+			{
+			RApaLsSession ls;
+			CleanupClosePushL(ls);
+			ret=ls.Connect();
+			if (ret==KErrNone)
+				{
+				TApaAppInfo info;
+				ret=ls.GetAppInfo(info,appUid);
+				if (ret==KErrNone)
+					{
+					iAppCaption = info.iCaption.AllocL();
+					}
+				}
+			CleanupStack::PopAndDestroy(&ls);
+			}
+
+		if (!iAppCaption)	// no caption found
+			iAppCaption = HBufC::NewL(0);
+
+		CPicture* icon=CApaIconPicture::NewL(iIconSizeInTwips, appUid);
+		delete iPicture;
+		iPicture = icon;
+		iFormat = EIconic;
+		}
+	__PROFILE_END(6);
+	}
+#ifdef __VC32__
+#pragma optimize("g", on)
+#endif
+
+
+TUid CApaDoor::AppUidFromStreamL() const
+	{
+	__ASSERT_DEBUG(iStore,Panic(EDPanicNoStoreOnIconify));
+	__APA_PROFILE_START(15);
+	CStreamDictionary* streamDic=ReadStreamDictionaryLC(*iStore,iStore->Root());
+	TApaAppIdentifier appId=CApaProcess::ReadAppIdentifierL(*iStore,*streamDic);
+	CleanupStack::PopAndDestroy(streamDic);
+	__APA_PROFILE_END(15);
+	return appId.iAppUid;
+	}
+	
+
+EXPORT_C void CApaDoor::SetFormatToGlassL()
+/** Sets the format of the door to glass.
+
+The function asks the document to create a fresh copy of the door and destroys 
+any existing copy. If the process of creating the door completes without leaving, 
+but returns a zero pointer, then the function raises an APGRFX 17 panic.
+
+The function leaves with:
+
+KErrNotSupported, if the document does not support being represented by a 
+glass door.
+
+KErrNotFound, if the application DLL cannot be found.
+
+If the function leaves, the format remains unchanged.
+
+@see CApaDocument::GlassPictureL() */
+	{
+	__SHOW_TRACE(_L("Starting CApaDoor::SetFormatToGlassL"));
+	__APA_PROFILE_START(7);
+	if (iFormat!=EGlassDoor || !iPicture)
+		{
+		if (!iApaDoc)
+			{
+			__ASSERT_DEBUG(iStore,Panic(EDPanicNoStoreOnGlassing));
+			RestoreDocL(*iStore);
+			}
+		if (iApaDoc->Capability().CanDrawGlass())
+			{
+			CPicture* glass = iApaDoc->GlassPictureL();
+			__ASSERT_ALWAYS(glass,Panic(EPanicNoGlassPicture));
+			if (iPicture)
+				iPicture->GetSizeInTwips(iIconSizeInTwips); // store the current icon size
+			delete iPicture;
+			iPicture = glass;
+			iFormat = EGlassDoor;
+			}
+		else
+			User::Leave(KErrNotSupported); // glass pic's not supported
+		}
+	__PROFILE_END(7);
+	}
+
+
+EXPORT_C TUid CApaDoor::AppUidL()const
+/** Gets the application specific UID associated with the embedded document.
+
+@return The application specific UID. */
+	{
+	if (iApaDoc)
+		{
+		__ASSERT_DEBUG(iApaDoc->Application(), Panic(EDPanicNoApplication));
+		return iApaDoc->Application()->AppDllUid();
+		}
+	//
+	__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnAppUid));
+	//
+	// read uid from store's headstream
+	CStreamDictionary* streamDic = ReadStreamDictionaryLC(*iStore,iStore->Root());
+	TApaAppIdentifier appId = CApaProcess::ReadAppIdentifierL(*iStore,*streamDic);
+	CleanupStack::PopAndDestroy(); // streamDic
+	return appId.iAppUid;
+	}
+	
+
+void CApaDoor::Draw(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aClipRect,
+						MGraphicsDeviceMap* aMap)const
+/** Draws the door either as glass or as an icon depending on the format.
+
+@param aGc The graphics context.
+@param aTopLeft The co-ordinates where the top left corner pixel of the picture 
+should be placed. Note that whether this is actually drawn depends on the 
+clipping area defined.
+@param aClipRect A clipping rectangle.
+@param aMap The device map for the graphics device. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPictureOnDrawing));
+	//
+	iPicture->Draw(aGc,aTopLeft,aClipRect,aMap);
+	}
+
+void CApaDoor::GetOriginalSizeInTwips(TSize& aSize)const
+/** Get the door's original size, in twips.
+
+@param aSize The size, in twips. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	iPicture->GetOriginalSizeInTwips(aSize);
+	}
+
+void CApaDoor::SetScaleFactor(TInt aScaleFactorWidth,TInt aScaleFactorHeight)
+/** Sets the door's scale factors.
+
+@param aScaleFactorWidth The width scale factor, in percent.
+@param aScaleFactorHeight The height scale factor, in percent. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	iPicture->SetScaleFactor(aScaleFactorWidth,aScaleFactorHeight);
+	}
+
+TInt CApaDoor::ScaleFactorWidth()const
+/** Gets the door's width scale factor.
+
+@return The width scale factor, in percent. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	return iPicture->ScaleFactorWidth();
+	}
+
+TInt CApaDoor::ScaleFactorHeight()const
+/** Gets the door's height scale factor.
+
+@return The height scale factor, in percent. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	return iPicture->ScaleFactorHeight();
+	}
+
+void CApaDoor::SetCropInTwips(const TMargins& aMargins)
+/** Sets the cropping margins of a picture in twips.
+
+These are relative to the original unscaled size of the picture.
+
+@param aMargins The cropping margins, in twips. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	iPicture->SetCropInTwips(aMargins);
+	}
+
+void CApaDoor::GetCropInTwips(TMargins& aMargins)const
+/** Gets the cropping margins of the door in twips.
+
+These margins are relative to the original unscaled size of the picture.
+
+@param aMargins The cropping margins, in twips. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	iPicture->GetCropInTwips(aMargins);
+	}
+
+TPictureCapability CApaDoor::Capability()const
+/** Gets the picture's capabilities.
+
+These include whether it is scalable and croppable.
+
+@return The capabilities of the picture. */
+	{
+	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
+	return iPicture->Capability();
+	}
+
+TSize CApaDoor::GlassDoorSize()const
+	{
+	TSize size;
+	if (iFormat==EGlassDoor)
+		GetSizeInTwips(size);
+	else if (iFormat==ETemporarilyIconic)
+		{
+		if (!iApaDoc)
+			size = iIconSizeInTwips;
+		else
+			{
+			// there's a doc, so get a glass door from it just in case it's size has changed since I changed format
+			CPicture* glass = NULL;
+			TRAP_IGNORE(glass = iApaDoc->GlassPictureL()); 
+			__ASSERT_ALWAYS(glass,Panic(EPanicNoGlassPicture));
+			glass->GetSizeInTwips(size); //lint !e613 Possible use of null pointer - Asserted above
+			delete glass;
+			}
+		}
+	else
+		Panic(EIllegalCallToGlassDoorSize);
+	return size;
+	}
+
+
+void CApaDoor::SetIconSizeInTwips(TSize aSize)
+// for use of factory
+	{
+	if (iFormat==EGlassDoor)
+		iIconSizeInTwips = aSize;
+	else
+		SetSizeInTwips(aSize);
+	}
+
+
+///////////////////////////////////
+// TApaPictureFactory
+///////////////////////////////////
+
+#define KDoNotApplyIconSize TSize(-1,-1)
+
+/** Constructor for TApaPictureFactory */
+EXPORT_C TApaPictureFactory::TApaPictureFactory()
+	:iApaProcess(NULL),
+	iIconSize(TSize(0,0))
+	{
+	}
+
+EXPORT_C TApaPictureFactory::TApaPictureFactory(CApaProcess* aAppProcess)
+	:iApaProcess(aAppProcess),
+	iIconSize(KDoNotApplyIconSize)
+/** Constructs a door factory object for the specified application process.
+
+@param aAppProcess The application process. */
+	{}
+
+EXPORT_C void TApaPictureFactory::NewPictureL(TPictureHeader& aPictureHeader,const CStreamStore& aPictureStore)const
+// called (by the containing doc) to restore an app door from its header
+//
+/** Constructs and restores an application's door (picture) from a stream in the 
+specified store.
+
+The restored door is a CApaDoor type object.
+
+Note that the function can leave with KErrNoMemory if creation of the CApaDoor 
+object fails.
+
+@param aPictureHeader The header identifying the door to be restored. The 
+UID identifying the door must be KUidPictureTypeDoor, otherwise the function 
+leaves with KErrNotSupported. On entry, the door picture must be represented 
+by a stream ID, otherwise the function leaves with KErrBadHandle; on return, 
+the door picture is represented by a pointer to an internalized CApaDoor object.
+@param aPictureStore The store from which the door will be restored.
+@see TPictureHeader
+@see TPictureHeader::iPicture */
+	{
+	__SHOW_TRACE(_L("Starting TApaPictureFactory::NewPictureL"));
+	if (aPictureHeader.iPictureType!=KUidPictureTypeDoor)
+		User::Leave(KErrNotSupported); // wrong type
+	if (!aPictureHeader.iPicture.IsId())
+		User::Leave(KErrBadHandle); // not an id - can't restore
+	//
+	// create and restore the door
+	TStreamId id = aPictureHeader.iPicture.AsId();
+//	RFs fs;
+//	User::LeaveIfError(fs.Connect());
+//	CleanupClosePushL(fs);
+	__ASSERT_DEBUG(iApaProcess, Panic(EDPanicNoProcess));
+	if(iApaProcess)
+		{
+		CApaDoor* door = CApaDoor::NewL(iApaProcess->FsSession()/*fs*/,aPictureStore,id,*CONST_CAST(CApaProcess*,iApaProcess));
+		aPictureHeader.iPicture = door;
+		//
+		// set the icon size if requested
+		if (iIconSize!=KDoNotApplyIconSize)
+			door->SetIconSizeInTwips(iIconSize);
+		}
+//	CleanupStack::PopAndDestroy(); // fs - it's not needed any more as the base class doesn't use it
+	}
+
+
+////////////////////////////////////
+// HBufBuf
+////////////////////////////////////
+
+HBufBuf* HBufBuf::NewL(CBufBase& aBuf,TInt aPos,TInt aMode)
+//
+// Create a pre-set buffer stream buffer.
+//
+	{
+	HBufBuf* buf=new(ELeave) HBufBuf;
+	buf->Set(aBuf,aPos,aMode);
+	return buf;
+	}
+
+void HBufBuf::DoRelease()
+//
+// Finished with this stream buffer.
+//
+	{
+	delete this;
+	}