--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/appfw/apparchitecture/apgrfx/APGDOOR.CPP Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,879 @@
+// 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 "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// apgdoor.cpp
+//
+
+#include <s32stor.h>
+#include <fbs.h>
+#include <e32def_private.h> // MattR addition for __PROFILE_END error
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#if !defined(__APA_INTERNAL_H__)
+#include "apainternal.h"
+#endif
+#endif //SYMBIAN_ENABLE_SPLIT_HEADERS
+
+#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)
+ {}
+
+
+CApaDoor::CApaDoor(RFs& aFs, CApaProcess& aProcess)
+ :iFs(aFs),
+ iApaProcess(&aProcess)
+ {}
+
+
+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;
+ }
+