appfw/apparchitecture/apgrfx/APGDOOR.CPP
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // apgdoor.cpp
       
    15 //
       
    16 
       
    17 #include <s32stor.h>
       
    18 #include <fbs.h>
       
    19 #include <e32def_private.h> // MattR addition for __PROFILE_END error
       
    20 
       
    21 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    22 #if !defined(__APA_INTERNAL_H__)
       
    23 #include "apainternal.h"
       
    24 #endif
       
    25 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
       
    26 
       
    27 #include "APGDOOR.H"
       
    28 #include "APGICNFL.H"
       
    29 #include "APGCLI.H"
       
    30 #include "APACLN.H"
       
    31 #include "APGSTD.H"
       
    32 #include "APGPRIV.H"
       
    33 #include "APFDEF.H"
       
    34 
       
    35 #include "../apparc/TRACE.H"
       
    36 
       
    37 const TUid KUidApaDoorStateStream={0x1000012a}; // build invariant
       
    38 const TInt KHugeGranularity=4096; // 4k granularity for the door's host buffer
       
    39 // default icon size only used if door was created by a model door, set to glass, but does not support glass
       
    40 #define KDefaultIconSizeInTwips TSize(500,500)
       
    41 
       
    42 //
       
    43 // CApaDoor
       
    44 //
       
    45 
       
    46 EXPORT_C CApaDoor* CApaDoor::NewLC(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)
       
    47 /** Creates a new wrapper for the specified embedded document and places a
       
    48 pointer to it onto the cleanup stack.
       
    49 
       
    50 The door is of the specified size. The wrapper takes ownership of the document; 
       
    51 if creation of the wrapper fails, the document object is destroyed.
       
    52 
       
    53 @param aFs A file server session.
       
    54 @param aDoc The document for which the door is to be created.
       
    55 @param aDefaultIconSizeInTwips The size of the door in twips.
       
    56 @return  The new embedded document wrapper object. */
       
    57 	{
       
    58 	CApaDoor* self=new CApaDoor(aFs, aDoc,aDefaultIconSizeInTwips);
       
    59 	if (!self)
       
    60 		{
       
    61 		__ASSERT_DEBUG(aDoc.Process(), Panic(EDPanicNoProcess));
       
    62 		aDoc.Process()->DestroyDocument(&aDoc);
       
    63 		User::LeaveNoMemory();
       
    64 		}
       
    65 	CleanupStack::PushL(self);
       
    66 	self->ConstructL(); //lint !e613 Possible use of null pointer - Lint is wrong, see User::LeaveNoMemory() above
       
    67 	return self;
       
    68 	}
       
    69 
       
    70 
       
    71 EXPORT_C CApaDoor* CApaDoor::NewL(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)
       
    72 /** Creates a new wrapper for the specified embedded document.
       
    73 
       
    74 The door is of the specified size. The wrapper takes ownership of the document; 
       
    75 if creation of the wrapper fails, the document object is destroyed.
       
    76 
       
    77 @param aFs A file server session.
       
    78 @param aDoc The document for which the door is to be created.
       
    79 @param aDefaultIconSizeInTwips The size of the door in twips.
       
    80 @return  The new embedded document wrapper object. */
       
    81 	{
       
    82 	CApaDoor* self = CApaDoor::NewLC(aFs, aDoc,aDefaultIconSizeInTwips);
       
    83 	CleanupStack::Pop();
       
    84 	return self;
       
    85 	}
       
    86 
       
    87 
       
    88 EXPORT_C CApaDoor* CApaDoor::NewL(RFs& aFs, const CStreamStore& aStore,TStreamId aStreamId,CApaProcess& aProcess)
       
    89 // Creates a door and restores it
       
    90 // Should only be called by the TApaPictureFactory
       
    91 //
       
    92 	{
       
    93 	CApaDoor* self=new(ELeave) CApaDoor(aFs, aProcess);
       
    94 	CleanupStack::PushL(self);
       
    95 	self->RestoreL(aStore,aStreamId);
       
    96 	CleanupStack::Pop();
       
    97 	return self;
       
    98 	}
       
    99 
       
   100 
       
   101 CApaDoor::CApaDoor(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)
       
   102 	:iFs(aFs),
       
   103 	iApaProcess(aDoc.Process()),
       
   104 	iApaDoc(&aDoc),
       
   105 	iIconSizeInTwips(aDefaultIconSizeInTwips)
       
   106 	{}
       
   107 
       
   108 
       
   109 CApaDoor::CApaDoor(RFs& aFs, CApaProcess& aProcess)
       
   110 	:iFs(aFs),
       
   111 	iApaProcess(&aProcess)
       
   112 	{}
       
   113 
       
   114 
       
   115 EXPORT_C CApaDoor::~CApaDoor()
       
   116 /** Destructor.
       
   117 
       
   118 Frees all resources owned by the object, prior to its destruction. In particular, 
       
   119 it destroys the document, removing all references to it from the application 
       
   120 process. */
       
   121 	{
       
   122 	delete iPicture;
       
   123 	if (iApaDoc)
       
   124 		iApaProcess->DestroyDocument(iApaDoc); // removes it from the process and deletes it
       
   125 	delete iAppCaption;
       
   126 	delete iStore;
       
   127 	delete iStoreHost;
       
   128 	iApaProcess = NULL;
       
   129 	iApaDoc = NULL;
       
   130 	}
       
   131 
       
   132 
       
   133 void CApaDoor::ConstructL()
       
   134 	{
       
   135 	__SHOW_TRACE(_L("Starting CApaDoor::ConstructL"));
       
   136 	__APA_PROFILE_START(3);
       
   137 	__ASSERT_ALWAYS(iApaDoc,Panic(EPanicNoDocumentOnConstruction));
       
   138 	//
       
   139 	// check that the doc supports embedding
       
   140 	TApaAppCapabilityBuf buf;
       
   141 	__ASSERT_DEBUG(iApaDoc->Application(), Panic(EDPanicNoApplication));
       
   142 	iApaDoc->Application()->Capability(buf);
       
   143 	if (buf().iEmbeddability==TApaAppCapability::ENotEmbeddable)
       
   144 		User::Leave(KErrNotSupported);
       
   145 	//
       
   146 	__SHOW_TRACE(_L("...doc is embeddable"));
       
   147 	//
       
   148 	// set up the icon
       
   149 	SetFormatToIconL();
       
   150 	//
       
   151 	__PROFILE_END(3);
       
   152 	}
       
   153 
       
   154 TStreamId CApaDoor::StoreL(CStreamStore& aTargetStore)const
       
   155 /** Stores the embedded document in the specified store as an embedded store.
       
   156 
       
   157 This function saves the format of the door. It also stores the document, if 
       
   158 the document exists in memory, otherwise, it simply copies the stream containing 
       
   159 the embedded document into the specified store.
       
   160 
       
   161 @param aStore The store into which the embedded document is to be stored.
       
   162 @return The stream ID of the head stream for the embedded document. This stream 
       
   163 contains the stream dictionary through which the embedded document and its 
       
   164 door can be restored. */
       
   165 	{
       
   166 	__SHOW_TRACE(_L("Starting CApaDoor::StoreL"));
       
   167 	__APA_PROFILE_START(4);
       
   168 	// create stream dictionary
       
   169 	CStreamDictionary* streamDic = CStreamDictionary::NewLC();
       
   170 	//
       
   171 	// stream out door's state
       
   172 	ExternalizeBaseStreamL(aTargetStore,*streamDic);
       
   173 	ExternalizeStateStreamL(aTargetStore,*streamDic);
       
   174 	//
       
   175 	// store the doc if it exists, otherwise copy the persistent data directly
       
   176 	TStreamId id;
       
   177 	RStoreWriteStream stream;
       
   178 	if (iApaDoc)
       
   179 		{
       
   180 		// create an embedded store in a new write stream
       
   181 		id = stream.CreateL(aTargetStore);
       
   182 		CEmbeddedStore* target=CEmbeddedStore::NewLC(stream); // takes ownership of stream
       
   183 		streamDic->AssignL(KUidApaDoorDocStream,id);
       
   184 		StoreDocL(*target);
       
   185 		// close the new embedded store
       
   186 		target->CommitL();
       
   187 		CleanupStack::PopAndDestroy(); // target
       
   188 		}
       
   189 	else if (iStore)
       
   190 		{
       
   191 		RStoreWriteStream trg;
       
   192 		id = trg.CreateLC(aTargetStore);
       
   193 		CopyStoreL(*iStore,trg);
       
   194 		CleanupStack::PopAndDestroy(); // trg
       
   195 		streamDic->AssignL(KUidApaDoorDocStream,id);
       
   196 		}
       
   197 	else 
       
   198 		Panic(EPanicNoDocOrStoreWhenStoring); // impossible situation
       
   199 	//
       
   200 	// store the stream dictionary and return its stream id
       
   201 	id = stream.CreateLC(aTargetStore);
       
   202 	stream<< *streamDic;
       
   203 	stream.CommitL();
       
   204 	CleanupStack::PopAndDestroy(); // stream
       
   205 	//
       
   206 	// tidy up
       
   207 	CleanupStack::PopAndDestroy(); // streamDic
       
   208 	__PROFILE_END(4);
       
   209 	return id;
       
   210 	}
       
   211 
       
   212 
       
   213 void CApaDoor::CopyStoreL(const CEmbeddedStore& aSourceStore,RWriteStream& aTargetStream)
       
   214 // static method
       
   215 // copies an embedded store containing a doc to aTargetStream
       
   216 //
       
   217 	{
       
   218 	__SHOW_TRACE(_L("Starting CApaDoor::CopyStoreL"));
       
   219 	// read the contents of aSourceStore's rootstream (so I can write it out in a mo')
       
   220 	CStreamDictionary* root=ReadStreamDictionaryLC(aSourceStore,aSourceStore.Root());
       
   221 	//
       
   222 	// copy the source store directly
       
   223 	MStreamBuf* host=aSourceStore.Host();
       
   224 	__ASSERT_DEBUG(host, Panic(EDPanicNoHostForStore));
       
   225 	TStreamPos pos=aSourceStore.Position(aSourceStore.Root());
       
   226 	host->SeekL(host->ERead,EStreamBeginning);
       
   227 	RReadStream stream(host);
       
   228 	aTargetStream.WriteL(stream,pos.Offset());
       
   229 	//
       
   230 	// write the root stream
       
   231 	aTargetStream<< *root;
       
   232 	aTargetStream.CommitL();
       
   233 	CleanupStack::PopAndDestroy(); // root
       
   234 	}
       
   235 
       
   236 EXPORT_C void CApaDoor::RestoreL(const CStreamStore& aSourceStore,TStreamId aStreamId)
       
   237 /** Restores the embedded document from the specified store.
       
   238 
       
   239 The format of the door is set to iconic if the embedded document is password 
       
   240 protected.
       
   241 
       
   242 @param aStore The store from which the embedded document is to be restored. 
       
   243 @param aHeadStreamId The stream ID of the head stream for the embedded document. 
       
   244 This stream contains the stream dictionary through which the embedded document 
       
   245 and its door can be restored. */
       
   246 	{
       
   247 	__SHOW_TRACE(_L("Starting CApaDoor::RestoreL"));
       
   248 	__APA_PROFILE_START(5);
       
   249 	__ASSERT_DEBUG(iApaProcess,Panic(EDPanicNoProcess));
       
   250 	//
       
   251 	if (iApaDoc)
       
   252 		{
       
   253 		iApaProcess->DestroyDocument(iApaDoc);
       
   254 		iApaDoc = NULL;
       
   255 		}
       
   256 	delete iStore;
       
   257 	delete iStoreHost;
       
   258 	iStore=NULL;
       
   259 	iStoreHost = NULL;
       
   260 	//
       
   261 	// internalize the streamDic from the headstream
       
   262 	CStreamDictionary* streamDic=ReadStreamDictionaryLC(aSourceStore,aStreamId);
       
   263 	//
       
   264 	// internalize the door's state
       
   265 	__APA_PROFILE_START(13);
       
   266 	TSize currentSize=InternalizeBaseStreamL(aSourceStore,*streamDic);
       
   267 	InternalizeStateStreamL(aSourceStore,*streamDic,currentSize);
       
   268 	__APA_PROFILE_END(13);
       
   269 	//
       
   270 	// internalize the embedded store
       
   271 	__APA_PROFILE_START(14);
       
   272 	RStoreReadStream src;
       
   273 	src.OpenL(aSourceStore,streamDic->At(KUidApaDoorDocStream));
       
   274 	iStore = CEmbeddedStore::FromL(src);
       
   275 	CleanupStack::PopAndDestroy(); // streamDic
       
   276 	streamDic = NULL;
       
   277 	__APA_PROFILE_END(14);
       
   278 	//
       
   279 	// internalize the doc's stream dict
       
   280 	streamDic = ReadStreamDictionaryLC(*iStore,iStore->Root());
       
   281 	//
       
   282 	// set the door's format 
       
   283 	if (iFormat==EIconic || (streamDic->At(KUidSecurityStream)!=KNullStreamId))
       
   284 		// iconify automatically if a password is required for access
       
   285 		SetFormatToIconL();
       
   286 	else
       
   287 		{
       
   288 		TRAPD(ret, SetFormatToGlassL() );
       
   289 		if (ret==KErrNone)
       
   290 			{
       
   291 			__ASSERT_DEBUG(iPicture, Panic(EDPanicNoPictureOnDrawing));
       
   292 			iPicture->SetSizeInTwips(currentSize);
       
   293 			}
       
   294 		else if (ret!=KErrNoMemory)
       
   295 			// problem loading app/doc - just iconify it for now...
       
   296 			SetFormatToIconL();
       
   297 		else
       
   298 			User::Leave(ret);
       
   299 		}	
       
   300 	CleanupStack::PopAndDestroy(); // streamDic
       
   301 	__PROFILE_END(5);
       
   302 	}
       
   303 
       
   304 
       
   305 void CApaDoor::StoreDocL(CPersistentStore& aTargetStore)const
       
   306 // stores the doc if it's in memory, otherwise panics!
       
   307 // aStore should be protected before calling this method
       
   308 //
       
   309 	{
       
   310 	__SHOW_TRACE(_L("Starting CApaDoor::StoreDocL"));
       
   311 	__ASSERT_ALWAYS(iApaDoc,Panic(EPanicNoDocumentOnStore)); // the doc must be in memory to be stored
       
   312 	//
       
   313 	// create a stream dic
       
   314 	CStreamDictionary* streamDic=CStreamDictionary::NewLC();
       
   315 	// store the doc
       
   316 	iApaDoc->StoreL(aTargetStore,*streamDic);
       
   317 	// write store's root stream
       
   318 	CApaProcess::WriteRootStreamL(aTargetStore,*streamDic,*iApaDoc->Application());
       
   319 	// tidy up
       
   320 	CleanupStack::PopAndDestroy(); // streamDic
       
   321 	}
       
   322 
       
   323 
       
   324 void CApaDoor::RestoreDocL(const CPersistentStore& aSourceStore)
       
   325 // restores the document from the embedded store
       
   326 // leaves with KErrNotFound if the app dll cant be located
       
   327 //
       
   328 	{
       
   329 	__SHOW_TRACE(_L("Starting CApaDoor::RestoreDocL"));
       
   330 	__ASSERT_ALWAYS(!iApaDoc,Panic(EPanicDocAlreadyExists));
       
   331 	//
       
   332 	// read the stream dic from the doc's root stream
       
   333 	CStreamDictionary* streamDic=ReadStreamDictionaryLC(aSourceStore,aSourceStore.Root());
       
   334 	//
       
   335 	// read the app id from the store
       
   336 	TApaAppIdentifier appId = CApaProcess::ReadAppIdentifierL(aSourceStore,*streamDic);
       
   337 	//
       
   338 	__ASSERT_DEBUG(iApaProcess,Panic(EDPanicNoProcess));
       
   339 	// if the app exists find it, load it and create a doc, else leave if the correct app cannot be found
       
   340 	CApaDocument* doc = // create an unrestored doc and adds it to the process list
       
   341 	iApaProcess->AddNewDocumentL(appId.iAppUid);
       
   342 	TApaDocCleanupItem cleanup(iApaProcess,doc);
       
   343 	CleanupStack::PushL(cleanup);
       
   344 	doc->RestoreL(aSourceStore,*streamDic); // restores the doc
       
   345 	iApaDoc = doc;
       
   346 	CleanupStack::Pop(); // doc
       
   347 	CleanupStack::PopAndDestroy(); // streamDic
       
   348 	}
       
   349 
       
   350 
       
   351 CStreamDictionary* CApaDoor::ReadStreamDictionaryLC(const CStreamStore& aSourceStore,TStreamId aStreamId)
       
   352 // static method
       
   353 //
       
   354 	{
       
   355 	__APA_PROFILE_START(12);
       
   356 	// read the stream dic from the doc's root stream
       
   357 	CStreamDictionary* streamDic=CStreamDictionary::NewLC();
       
   358 	RStoreReadStream stream;
       
   359 	stream.OpenLC(aSourceStore,aStreamId);
       
   360 	stream>> *streamDic;
       
   361 	CleanupStack::PopAndDestroy(); // root
       
   362 	__APA_PROFILE_END(12);
       
   363 	return streamDic;
       
   364 	}
       
   365 
       
   366 
       
   367 void CApaDoor::ExternalizeL(RWriteStream& /*aStream*/)const
       
   368 	{
       
   369 	Panic(EPanicMethodNotSupported);
       
   370 	}
       
   371 
       
   372 
       
   373 void CApaDoor::ExternalizeStateStreamL(CStreamStore& aStore,CStreamDictionary& aStreamDict)const
       
   374 	{
       
   375 	__SHOW_TRACE(_L("Starting CApaDoor::ExternalizeStateStreamL"));
       
   376 	__ASSERT_ALWAYS(iAppCaption,Panic(EPanicNoCaption));
       
   377 	__ASSERT_ALWAYS(iPicture,Panic(EPanicNoPictureInDoor));
       
   378 	RStoreWriteStream stream;
       
   379 	TStreamId id=stream.CreateLC(aStore);
       
   380 	//
       
   381 	stream<< *iAppCaption;
       
   382 	TSize size;
       
   383 	if (iFormat==EIconic || iFormat==ETemporarilyIconic)
       
   384 		GetSizeInTwips(size);
       
   385 	else 
       
   386 		size = iIconSizeInTwips;
       
   387 	stream<< size;
       
   388 	//
       
   389 	stream.CommitL();
       
   390 	CleanupStack::PopAndDestroy(); // stream
       
   391 	aStreamDict.AssignL(KUidApaDoorStateStream,id);
       
   392 	}
       
   393 
       
   394 
       
   395 void CApaDoor::InternalizeStateStreamL(const CStreamStore& aStore,const CStreamDictionary& aStreamDict,TSize aDefaultIconSize)
       
   396 	{
       
   397 	__SHOW_TRACE(_L("Starting CApaDoor::InternalizeStateStreamL"));
       
   398 	TStreamId id=aStreamDict.At(KUidApaDoorStateStream);
       
   399 	if (id!=KNullStreamId)
       
   400 		{
       
   401 		RStoreReadStream stream;
       
   402 		stream.OpenLC(aStore,id);
       
   403 		TApaAppCaption caption;
       
   404 		stream>> caption;
       
   405 		delete iAppCaption;
       
   406 		iAppCaption = NULL;
       
   407 		iAppCaption = caption.AllocL();
       
   408 		stream>> iIconSizeInTwips;
       
   409 		CleanupStack::PopAndDestroy(); // stream
       
   410 		}
       
   411 	else
       
   412 		{// use default settings
       
   413 		delete iAppCaption;
       
   414 		iAppCaption = NULL;
       
   415 		iAppCaption = HBufC::NewL(0);
       
   416 		if (iFormat==EIconic)
       
   417 			iIconSizeInTwips = aDefaultIconSize;
       
   418 		else
       
   419 			iIconSizeInTwips = KDefaultIconSizeInTwips;
       
   420 		}
       
   421 	}
       
   422 
       
   423 
       
   424 void CApaDoor::DetachFromStoreL(TDetach aDegree)
       
   425 /** Detaches the door from its store, restoring any unrestored elements of the picture, 
       
   426 if necessary.
       
   427 
       
   428 @param aDegree Degree to which picture is detached.
       
   429 @see CApaDocument::DetachFromStoreL() */
       
   430 	{
       
   431 	__SHOW_TRACE(_L("Starting CApaDoor::DetachFromStoreL"));
       
   432 	if (iApaDoc)
       
   433 		{
       
   434 		iApaDoc->DetachFromStoreL(aDegree);
       
   435 		if (!iStoreHost)
       
   436 			{
       
   437 			delete iStore;
       
   438 			iStore = NULL;
       
   439 			}
       
   440 		}
       
   441 	else if (!iStoreHost)
       
   442 		{
       
   443 		if (aDegree==EDetachDraw)
       
   444 			{
       
   445 			delete iStore;
       
   446 			iStore = NULL;
       
   447 			// now all I can do is draw as I am, any attempt to change me will result in a panic
       
   448 			}
       
   449 		else
       
   450 			{
       
   451 			__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnDetach));
       
   452 			// instantiate the mem buffer, and a stream to write to it
       
   453 			CBufSeg* bufSeg = CBufSeg::NewL(KHugeGranularity);
       
   454 			CleanupStack::PushL(bufSeg);
       
   455 			HBufBuf* buf=HBufBuf::NewL(*bufSeg,0);
       
   456 			RWriteStream writeStream(buf);
       
   457 			writeStream.PushL();
       
   458 			// write the store to the mem buffer
       
   459 			CopyStoreL(*iStore,writeStream);
       
   460 			CleanupStack::Pop(2); // bufSeg,writeStream
       
   461 			//
       
   462 			// set iStoreHost as host for the embedded store
       
   463 			MStreamBuf* host=iStore->Host();
       
   464 			__ASSERT_ALWAYS(host!=NULL,Panic(EDPanicNoHostForStore));
       
   465 			iStore->Detach();
       
   466 			host->Release(); //lint !e613 Suppress possible use of null pointer
       
   467 			iStore->Reattach(buf);
       
   468 			iStoreHost = bufSeg;
       
   469 			}
       
   470 		}
       
   471 	}
       
   472 
       
   473 
       
   474 EXPORT_C CApaDocument* CApaDoor::DocumentL(TBool aCheckPassword)
       
   475 // leaves with KErrNotFound if the doc needs to be restored but the app dll cannot be found
       
   476 //
       
   477 /** Returns a pointer to the embedded document represented by this wrapper.
       
   478 
       
   479 If necessary, the document is restored from its embedded store.
       
   480 
       
   481 Note that if the wrapper does not have a reference to the embedded document 
       
   482 store, then the function raises a APGRFX 13 panic. Constructing this wrapper 
       
   483 through a TApaPictureFactory or storing the embedded document through CApaDoor::StoreL() 
       
   484 ensures that this wrapper has a reference to the embedded document store.
       
   485 
       
   486 @param aCheckPassword If ETrue, any password is checked before returning a 
       
   487 pointer to the document. If EFalse, the password is not checked.
       
   488 @return A pointer to the embedded document.
       
   489 @see TApaPictureFactory
       
   490 @see CApaDoor::StoreL()
       
   491 @see CApaDocument::ValidatePasswordL() */
       
   492 	{
       
   493 	__SHOW_TRACE(_L("Starting CApaDoor::DocumentL"));
       
   494 	//
       
   495 	if (!iApaDoc)
       
   496 		{
       
   497 		__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnRestore));
       
   498 		RestoreDocL(*iStore);
       
   499 		}
       
   500 	else if (aCheckPassword)
       
   501 		iApaDoc->ValidatePasswordL();
       
   502 	//
       
   503 	return iApaDoc;
       
   504 	}
       
   505 
       
   506 EXPORT_C void CApaDoor::SetFormatToTemporaryIconL(TBool aEnabled)
       
   507 // if the door is currently iconic do nothing
       
   508 // if the door is glass switch it's format to iconic, but ensure that when externalized the format will be persisted as glass
       
   509 //
       
   510 /** Switches the format of the door between temporarily iconic and glass.
       
   511 
       
   512 If the door is iconic, then the function does nothing.
       
   513 
       
   514 @param aEnabled If ETrue and the format is currently glass, then the format 
       
   515 switches to temporarily iconic; this is the default. If EFalse and the format 
       
   516 is currently temporarily iconic, then the format switches to glass. */
       
   517 	{
       
   518 	__SHOW_TRACE(_L("Starting CApaDoor::SetFormatToTemporaryIconL"));
       
   519 	if (aEnabled && iFormat==EGlassDoor) 
       
   520 		{
       
   521 		TSize glassSize;
       
   522 		GetSizeInTwips(glassSize);
       
   523 		SetFormatToIconL();
       
   524 		iFormat = ETemporarilyIconic;
       
   525 		iIconSizeInTwips = glassSize; //abuse it!
       
   526 		}
       
   527 	else if (!aEnabled && iFormat==ETemporarilyIconic)
       
   528 		SetFormatToGlassL();
       
   529 	}
       
   530 
       
   531 #ifdef __VC32__
       
   532 #pragma optimize("g", off) // Disable due to problem with MSVC
       
   533 #endif
       
   534 EXPORT_C void CApaDoor::SetFormatToIconL()
       
   535 /** Sets the format of the door to iconic.
       
   536 
       
   537 The application's icon is used, or, if this cannot be found, the default icon 
       
   538 is used instead. The function leaves only if construction of the default icon 
       
   539 object fails. */
       
   540 	{
       
   541 	__SHOW_TRACE(_L("Starting CApaDoor::SetFormatToIconL"));
       
   542 	__APA_PROFILE_START(6);
       
   543 	if (iFormat==ETemporarilyIconic && iPicture)
       
   544 		{
       
   545 		GetSizeInTwips(iIconSizeInTwips);
       
   546 		iFormat = EIconic;
       
   547 		}
       
   548 	else if (iFormat!=EIconic || !iPicture)
       
   549 		{
       
   550 		TUid appUid;
       
   551 		if (iApaDoc)
       
   552 			{
       
   553 			__ASSERT_DEBUG(iApaDoc->Application(), Panic(EDPanicNoApplication));
       
   554 			appUid = iApaDoc->Application()->AppDllUid();
       
   555 			}
       
   556 		else
       
   557 			{
       
   558 			appUid = AppUidFromStreamL();
       
   559 			}
       
   560 
       
   561 		TInt ret=KErrNone;
       
   562 		if (!iAppCaption)
       
   563 			{
       
   564 			RApaLsSession ls;
       
   565 			CleanupClosePushL(ls);
       
   566 			ret=ls.Connect();
       
   567 			if (ret==KErrNone)
       
   568 				{
       
   569 				TApaAppInfo info;
       
   570 				ret=ls.GetAppInfo(info,appUid);
       
   571 				if (ret==KErrNone)
       
   572 					{
       
   573 					iAppCaption = info.iCaption.AllocL();
       
   574 					}
       
   575 				}
       
   576 			CleanupStack::PopAndDestroy(&ls);
       
   577 			}
       
   578 
       
   579 		if (!iAppCaption)	// no caption found
       
   580 			iAppCaption = HBufC::NewL(0);
       
   581 
       
   582 		CPicture* icon=CApaIconPicture::NewL(iIconSizeInTwips, appUid);
       
   583 		delete iPicture;
       
   584 		iPicture = icon;
       
   585 		iFormat = EIconic;
       
   586 		}
       
   587 	__PROFILE_END(6);
       
   588 	}
       
   589 #ifdef __VC32__
       
   590 #pragma optimize("g", on)
       
   591 #endif
       
   592 
       
   593 
       
   594 TUid CApaDoor::AppUidFromStreamL() const
       
   595 	{
       
   596 	__ASSERT_DEBUG(iStore,Panic(EDPanicNoStoreOnIconify));
       
   597 	__APA_PROFILE_START(15);
       
   598 	CStreamDictionary* streamDic=ReadStreamDictionaryLC(*iStore,iStore->Root());
       
   599 	TApaAppIdentifier appId=CApaProcess::ReadAppIdentifierL(*iStore,*streamDic);
       
   600 	CleanupStack::PopAndDestroy(streamDic);
       
   601 	__APA_PROFILE_END(15);
       
   602 	return appId.iAppUid;
       
   603 	}
       
   604 	
       
   605 
       
   606 EXPORT_C void CApaDoor::SetFormatToGlassL()
       
   607 /** Sets the format of the door to glass.
       
   608 
       
   609 The function asks the document to create a fresh copy of the door and destroys 
       
   610 any existing copy. If the process of creating the door completes without leaving, 
       
   611 but returns a zero pointer, then the function raises an APGRFX 17 panic.
       
   612 
       
   613 The function leaves with:
       
   614 
       
   615 KErrNotSupported, if the document does not support being represented by a 
       
   616 glass door.
       
   617 
       
   618 KErrNotFound, if the application DLL cannot be found.
       
   619 
       
   620 If the function leaves, the format remains unchanged.
       
   621 
       
   622 @see CApaDocument::GlassPictureL() */
       
   623 	{
       
   624 	__SHOW_TRACE(_L("Starting CApaDoor::SetFormatToGlassL"));
       
   625 	__APA_PROFILE_START(7);
       
   626 	if (iFormat!=EGlassDoor || !iPicture)
       
   627 		{
       
   628 		if (!iApaDoc)
       
   629 			{
       
   630 			__ASSERT_DEBUG(iStore,Panic(EDPanicNoStoreOnGlassing));
       
   631 			RestoreDocL(*iStore);
       
   632 			}
       
   633 		if (iApaDoc->Capability().CanDrawGlass())
       
   634 			{
       
   635 			CPicture* glass = iApaDoc->GlassPictureL();
       
   636 			__ASSERT_ALWAYS(glass,Panic(EPanicNoGlassPicture));
       
   637 			if (iPicture)
       
   638 				iPicture->GetSizeInTwips(iIconSizeInTwips); // store the current icon size
       
   639 			delete iPicture;
       
   640 			iPicture = glass;
       
   641 			iFormat = EGlassDoor;
       
   642 			}
       
   643 		else
       
   644 			User::Leave(KErrNotSupported); // glass pic's not supported
       
   645 		}
       
   646 	__PROFILE_END(7);
       
   647 	}
       
   648 
       
   649 
       
   650 EXPORT_C TUid CApaDoor::AppUidL()const
       
   651 /** Gets the application specific UID associated with the embedded document.
       
   652 
       
   653 @return The application specific UID. */
       
   654 	{
       
   655 	if (iApaDoc)
       
   656 		{
       
   657 		__ASSERT_DEBUG(iApaDoc->Application(), Panic(EDPanicNoApplication));
       
   658 		return iApaDoc->Application()->AppDllUid();
       
   659 		}
       
   660 	//
       
   661 	__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnAppUid));
       
   662 	//
       
   663 	// read uid from store's headstream
       
   664 	CStreamDictionary* streamDic = ReadStreamDictionaryLC(*iStore,iStore->Root());
       
   665 	TApaAppIdentifier appId = CApaProcess::ReadAppIdentifierL(*iStore,*streamDic);
       
   666 	CleanupStack::PopAndDestroy(); // streamDic
       
   667 	return appId.iAppUid;
       
   668 	}
       
   669 	
       
   670 
       
   671 void CApaDoor::Draw(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aClipRect,
       
   672 						MGraphicsDeviceMap* aMap)const
       
   673 /** Draws the door either as glass or as an icon depending on the format.
       
   674 
       
   675 @param aGc The graphics context.
       
   676 @param aTopLeft The co-ordinates where the top left corner pixel of the picture 
       
   677 should be placed. Note that whether this is actually drawn depends on the 
       
   678 clipping area defined.
       
   679 @param aClipRect A clipping rectangle.
       
   680 @param aMap The device map for the graphics device. */
       
   681 	{
       
   682 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPictureOnDrawing));
       
   683 	//
       
   684 	iPicture->Draw(aGc,aTopLeft,aClipRect,aMap);
       
   685 	}
       
   686 
       
   687 void CApaDoor::GetOriginalSizeInTwips(TSize& aSize)const
       
   688 /** Get the door's original size, in twips.
       
   689 
       
   690 @param aSize The size, in twips. */
       
   691 	{
       
   692 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   693 	iPicture->GetOriginalSizeInTwips(aSize);
       
   694 	}
       
   695 
       
   696 void CApaDoor::SetScaleFactor(TInt aScaleFactorWidth,TInt aScaleFactorHeight)
       
   697 /** Sets the door's scale factors.
       
   698 
       
   699 @param aScaleFactorWidth The width scale factor, in percent.
       
   700 @param aScaleFactorHeight The height scale factor, in percent. */
       
   701 	{
       
   702 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   703 	iPicture->SetScaleFactor(aScaleFactorWidth,aScaleFactorHeight);
       
   704 	}
       
   705 
       
   706 TInt CApaDoor::ScaleFactorWidth()const
       
   707 /** Gets the door's width scale factor.
       
   708 
       
   709 @return The width scale factor, in percent. */
       
   710 	{
       
   711 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   712 	return iPicture->ScaleFactorWidth();
       
   713 	}
       
   714 
       
   715 TInt CApaDoor::ScaleFactorHeight()const
       
   716 /** Gets the door's height scale factor.
       
   717 
       
   718 @return The height scale factor, in percent. */
       
   719 	{
       
   720 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   721 	return iPicture->ScaleFactorHeight();
       
   722 	}
       
   723 
       
   724 void CApaDoor::SetCropInTwips(const TMargins& aMargins)
       
   725 /** Sets the cropping margins of a picture in twips.
       
   726 
       
   727 These are relative to the original unscaled size of the picture.
       
   728 
       
   729 @param aMargins The cropping margins, in twips. */
       
   730 	{
       
   731 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   732 	iPicture->SetCropInTwips(aMargins);
       
   733 	}
       
   734 
       
   735 void CApaDoor::GetCropInTwips(TMargins& aMargins)const
       
   736 /** Gets the cropping margins of the door in twips.
       
   737 
       
   738 These margins are relative to the original unscaled size of the picture.
       
   739 
       
   740 @param aMargins The cropping margins, in twips. */
       
   741 	{
       
   742 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   743 	iPicture->GetCropInTwips(aMargins);
       
   744 	}
       
   745 
       
   746 TPictureCapability CApaDoor::Capability()const
       
   747 /** Gets the picture's capabilities.
       
   748 
       
   749 These include whether it is scalable and croppable.
       
   750 
       
   751 @return The capabilities of the picture. */
       
   752 	{
       
   753 	__ASSERT_DEBUG(iPicture,Panic(EDPanicNoPicture));
       
   754 	return iPicture->Capability();
       
   755 	}
       
   756 
       
   757 TSize CApaDoor::GlassDoorSize()const
       
   758 	{
       
   759 	TSize size;
       
   760 	if (iFormat==EGlassDoor)
       
   761 		GetSizeInTwips(size);
       
   762 	else if (iFormat==ETemporarilyIconic)
       
   763 		{
       
   764 		if (!iApaDoc)
       
   765 			size = iIconSizeInTwips;
       
   766 		else
       
   767 			{
       
   768 			// there's a doc, so get a glass door from it just in case it's size has changed since I changed format
       
   769 			CPicture* glass = NULL;
       
   770 			TRAP_IGNORE(glass = iApaDoc->GlassPictureL()); 
       
   771 			__ASSERT_ALWAYS(glass,Panic(EPanicNoGlassPicture));
       
   772 			glass->GetSizeInTwips(size); //lint !e613 Possible use of null pointer - Asserted above
       
   773 			delete glass;
       
   774 			}
       
   775 		}
       
   776 	else
       
   777 		Panic(EIllegalCallToGlassDoorSize);
       
   778 	return size;
       
   779 	}
       
   780 
       
   781 
       
   782 void CApaDoor::SetIconSizeInTwips(TSize aSize)
       
   783 // for use of factory
       
   784 	{
       
   785 	if (iFormat==EGlassDoor)
       
   786 		iIconSizeInTwips = aSize;
       
   787 	else
       
   788 		SetSizeInTwips(aSize);
       
   789 	}
       
   790 
       
   791 
       
   792 //
       
   793 // TApaPictureFactory
       
   794 //
       
   795 
       
   796 #define KDoNotApplyIconSize TSize(-1,-1)
       
   797 
       
   798 /** Constructor for TApaPictureFactory */
       
   799 EXPORT_C TApaPictureFactory::TApaPictureFactory()
       
   800 	:iApaProcess(NULL),
       
   801 	iIconSize(TSize(0,0))
       
   802 	{
       
   803 	}
       
   804 
       
   805 EXPORT_C TApaPictureFactory::TApaPictureFactory(CApaProcess* aAppProcess)
       
   806 	:iApaProcess(aAppProcess),
       
   807 	iIconSize(KDoNotApplyIconSize)
       
   808 /** Constructs a door factory object for the specified application process.
       
   809 
       
   810 @param aAppProcess The application process. */
       
   811 	{}
       
   812 
       
   813 EXPORT_C void TApaPictureFactory::NewPictureL(TPictureHeader& aPictureHeader,const CStreamStore& aPictureStore)const
       
   814 // called (by the containing doc) to restore an app door from its header
       
   815 //
       
   816 /** Constructs and restores an application's door (picture) from a stream in the 
       
   817 specified store.
       
   818 
       
   819 The restored door is a CApaDoor type object.
       
   820 
       
   821 Note that the function can leave with KErrNoMemory if creation of the CApaDoor 
       
   822 object fails.
       
   823 
       
   824 @param aPictureHeader The header identifying the door to be restored. The 
       
   825 UID identifying the door must be KUidPictureTypeDoor, otherwise the function 
       
   826 leaves with KErrNotSupported. On entry, the door picture must be represented 
       
   827 by a stream ID, otherwise the function leaves with KErrBadHandle; on return, 
       
   828 the door picture is represented by a pointer to an internalized CApaDoor object.
       
   829 @param aPictureStore The store from which the door will be restored.
       
   830 @see TPictureHeader
       
   831 @see TPictureHeader::iPicture */
       
   832 	{
       
   833 	__SHOW_TRACE(_L("Starting TApaPictureFactory::NewPictureL"));
       
   834 	if (aPictureHeader.iPictureType!=KUidPictureTypeDoor)
       
   835 		User::Leave(KErrNotSupported); // wrong type
       
   836 	if (!aPictureHeader.iPicture.IsId())
       
   837 		User::Leave(KErrBadHandle); // not an id - can't restore
       
   838 	//
       
   839 	// create and restore the door
       
   840 	TStreamId id = aPictureHeader.iPicture.AsId();
       
   841 //	RFs fs;
       
   842 //	User::LeaveIfError(fs.Connect());
       
   843 //	CleanupClosePushL(fs);
       
   844 	__ASSERT_DEBUG(iApaProcess, Panic(EDPanicNoProcess));
       
   845 	if(iApaProcess)
       
   846 		{
       
   847 		CApaDoor* door = CApaDoor::NewL(iApaProcess->FsSession()/*fs*/,aPictureStore,id,*CONST_CAST(CApaProcess*,iApaProcess));
       
   848 		aPictureHeader.iPicture = door;
       
   849 		//
       
   850 		// set the icon size if requested
       
   851 		if (iIconSize!=KDoNotApplyIconSize)
       
   852 			door->SetIconSizeInTwips(iIconSize);
       
   853 		}
       
   854 //	CleanupStack::PopAndDestroy(); // fs - it's not needed any more as the base class doesn't use it
       
   855 	}
       
   856 
       
   857 
       
   858 //
       
   859 // HBufBuf
       
   860 //
       
   861 
       
   862 HBufBuf* HBufBuf::NewL(CBufBase& aBuf,TInt aPos,TInt aMode)
       
   863 //
       
   864 // Create a pre-set buffer stream buffer.
       
   865 //
       
   866 	{
       
   867 	HBufBuf* buf=new(ELeave) HBufBuf;
       
   868 	buf->Set(aBuf,aPos,aMode);
       
   869 	return buf;
       
   870 	}
       
   871 
       
   872 void HBufBuf::DoRelease()
       
   873 //
       
   874 // Finished with this stream buffer.
       
   875 //
       
   876 	{
       
   877 	delete this;
       
   878 	}
       
   879