emailservices/emailstore/message_store/client/src/MsgStoreMessagePart.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Message store multipart message client support implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //<cmail>
       
    21 #include "MsgStoreMessagePart.h"
       
    22 #include "MsgStorePropertyKeys.h"
       
    23 //</cmail>
       
    24 #include "MsgStoreSessionContext.h"
       
    25 #include "RMessageStoreSession.h"
       
    26 #include "MessageStoreClientServer.h"
       
    27 #include "MsgStoreMessage.h"
       
    28 
       
    29 //_LIT( KTextPlain, "text/plain" );
       
    30 //_LIT( KTextHTML, "text/html" );
       
    31 _LIT(KFSMailContentTypeMultipartAlternative, "multipart/alternative");
       
    32 
       
    33 
       
    34 // ========================
       
    35 // CLASS: TPartsArray
       
    36 // ========================
       
    37 class TPartsArray : public MPropertiesArray
       
    38     {
       
    39     public:
       
    40     
       
    41 	    // ==============
       
    42 	    // PUBLIC METHODS
       
    43 	    // ==============
       
    44 	    
       
    45         TPartsArray( CMsgStoreSessionContext& aContext, TMsgStoreId aMailBoxId, RPointerArray<CMsgStoreMessagePart>& aParts );
       
    46         
       
    47         // inherited from MPropertiesArray              
       
    48         virtual void AddElementL( TMsgStoreId aId, TMsgStoreId aParentId, const TDesC8& aProperties );
       
    49         virtual void Reset();        
       
    50         
       
    51     private:
       
    52     
       
    53  	    // ==================
       
    54 	    // PRIVATE ATTRIBUTES
       
    55 	    // ==================
       
    56 	
       
    57         CMsgStoreSessionContext&             iContext;
       
    58         TMsgStoreId                          iMailBoxId;
       
    59         RPointerArray<CMsgStoreMessagePart>& iParts;
       
    60         
       
    61     }; // end class TPartsArray
       
    62 
       
    63     
       
    64 // ==========================================================================
       
    65 // FUNCTION: Constructor
       
    66 // ==========================================================================
       
    67 TPartsArray::TPartsArray( CMsgStoreSessionContext& aContext, TMsgStoreId aMailBoxId, RPointerArray<CMsgStoreMessagePart>& aParts ) : 
       
    68     iContext( aContext ), iMailBoxId( aMailBoxId ), iParts( aParts ) 
       
    69     {
       
    70     } // end constructor
       
    71        
       
    72 // ==========================================================================
       
    73 // FUNCTION: AddElementL
       
    74 // ==========================================================================
       
    75 void TPartsArray::AddElementL( TMsgStoreId aId, TMsgStoreId aParentId, const TDesC8& aProperties )
       
    76     {
       
    77     CMsgStoreMessagePart *newPart = CMsgStoreMessagePart::NewL( iContext, aId, aParentId, iMailBoxId, aProperties );
       
    78     CleanupStack::PushL( newPart );
       
    79     
       
    80     iParts.AppendL( newPart );    
       
    81     
       
    82     CleanupStack::Pop( newPart );
       
    83     } // end AddElementL
       
    84     
       
    85 // ==========================================================================
       
    86 // FUNCTION: Reset
       
    87 // ==========================================================================
       
    88 void TPartsArray::Reset()
       
    89     {
       
    90     iParts.ResetAndDestroy();
       
    91     } // end Reset
       
    92     
       
    93 
       
    94 /** Adds a child part to this part 
       
    95 
       
    96     /param aProperties the headers of the newly added part
       
    97     /note This method leaves with KErrNotSupported if it is NOT multi-part, i.e. this part
       
    98     already has content.
       
    99  */
       
   100 EXPORT_C CMsgStoreMessagePart* CMsgStoreMessagePart::AddChildPartL( const CMsgStorePropertyContainer& aProperties,
       
   101                                                                     const TDesC& aContentFilename                 )
       
   102 	{
       
   103 	RBuf8 serializedProperties;
       
   104 	CleanupClosePushL( serializedProperties );
       
   105 	aProperties.SerializeL( serializedProperties );
       
   106 	
       
   107 	TInt partId = iContext.iSession.CreateContainerL( Id(), 
       
   108 													  KMsgStoreInvalidId,   //do not check grand parent id
       
   109 													  iMailBoxId,
       
   110 													  EMsgStorePartBits,
       
   111 													  serializedProperties,
       
   112 													  ETrue,
       
   113                                                       aContentFilename );
       
   114 	
       
   115 	CMsgStoreMessagePart* part = CMsgStoreMessagePart::NewL( iContext, partId, Id(), iMailBoxId, serializedProperties );
       
   116 	
       
   117 	CleanupStack::PopAndDestroy( &serializedProperties );
       
   118 	
       
   119 	return part;
       
   120 	}
       
   121 		
       
   122 
       
   123 /** Adds a child part to this part and set the content to the same content stored in the input file handle 
       
   124 
       
   125     /param aProperties the headers of the newly added part
       
   126             /param aFile file handle that contains the content.
       
   127     /note This method leaves with KErrNotSupported if it is NOT multi-part, i.e. this part
       
   128     already has content.
       
   129  */
       
   130 EXPORT_C CMsgStoreMessagePart* CMsgStoreMessagePart::AddChildPartL( const CMsgStorePropertyContainer& aProperties,
       
   131                                                                     RFile& aFile )
       
   132 	{
       
   133 	RBuf8 serializedProperties;
       
   134 	serializedProperties.CleanupClosePushL();
       
   135 	aProperties.SerializeL( serializedProperties );
       
   136 	
       
   137 	TInt partId = iContext.iSession.CreateContainerL( Id(), 
       
   138 													  KMsgStoreInvalidId,   //do not check grand parent id
       
   139 													  iMailBoxId,
       
   140 													  EMsgStorePartBits,
       
   141 													  serializedProperties,
       
   142 													  ETrue,
       
   143 													  aFile );
       
   144 	
       
   145 	CMsgStoreMessagePart* part = CMsgStoreMessagePart::NewL( iContext, partId, Id(), iMailBoxId, serializedProperties );
       
   146 	
       
   147 	CleanupStack::PopAndDestroy( &serializedProperties );
       
   148 	
       
   149 	return part;
       
   150 	}
       
   151 
       
   152 
       
   153 /** Adds an existing part to the child 
       
   154 
       
   155     /param aPart already created child part
       
   156     /note This method leaves with KErrNotSupported if it is NOT multi-part, i.e. this part
       
   157     already has content.
       
   158  */
       
   159 
       
   160 EXPORT_C CMsgStoreMessage* CMsgStoreMessagePart::AddChildMessageL( CMsgStorePropertyContainer& aProperties )
       
   161 	{
       
   162 	aProperties.AddOrUpdatePropertyL( KMsgStorePropertyIsEmbeddedMsg, ETrue );
       
   163 
       
   164 	return static_cast<CMsgStoreMessage*>( AddChildPartL( aProperties ) );
       
   165 	}
       
   166 
       
   167 
       
   168 /** Copies an attachment from one message to another message.
       
   169 	
       
   170 	This function copies an an attachment, including the properties and content, from one
       
   171 	message to another message.  This function will leave with KErrNotFound if the specified
       
   172 	message is not found in the source folder or if the destination message is not found in
       
   173 	the destination folder.
       
   174 
       
   175     KMsgStoreInvalidId may be passed for the destination folder ID if there is no desire to 
       
   176     check the source folder.
       
   177     
       
   178 	ECapabilityWriteUserData is required to use this function.			
       
   179 	
       
   180 	\retval Returns the ID of the new message.
       
   181 
       
   182     \note Only works if the store is in an authenticated state, otherwise this function leaves
       
   183           with KErrNotReady.
       
   184 */		
       
   185 EXPORT_C TMsgStoreId CMsgStoreMessagePart::CopyChildPartL( TMsgStoreId aPartId, TMsgStoreId aNewParentId )
       
   186 	{
       
   187 	iContext.VerifyTypeL( aPartId, EMsgStorePartBits );
       
   188 	//new parent can be a message or a part
       
   189 	iContext.VerifyTypeL( aNewParentId, EMsgStoreMessageBits, EMsgStorePartBits );
       
   190 	
       
   191 	return iContext.iSession.CopyContainerL( aPartId, 
       
   192 	                                         Id(), 
       
   193 	                                         KMsgStoreInvalidId,     //don't care
       
   194 	                                         aNewParentId,
       
   195 	                                         KMsgStoreInvalidId,     //don't care
       
   196 	                                         iMailBoxId);	
       
   197 	} // end CopyMessageL
       
   198 
       
   199 
       
   200 /** Removes a child part from this part 
       
   201 
       
   202     /note This method leaves with KErrNotSupported if it is NOT multi-part.
       
   203  */
       
   204 EXPORT_C void CMsgStoreMessagePart::RemoveChildPartL( TMsgStoreId aPartId, TBool aRecursive )
       
   205 	{
       
   206 	iContext.VerifyTypeL( aPartId, EMsgStorePartBits );
       
   207     
       
   208     TMsgStoreId parentId = ( aRecursive ? KMsgStoreInvalidId : Id() );
       
   209 	
       
   210 	iContext.iSession.DeleteContainerL( aPartId, parentId, KMsgStoreInvalidId, iMailBoxId );
       
   211 	}
       
   212 
       
   213 /** gets a child part fo this part 
       
   214     /note This method leaves with KErrNotSupported if it is NOT multi-part.
       
   215  */
       
   216 EXPORT_C CMsgStoreMessagePart* CMsgStoreMessagePart::ChildPartL( TMsgStoreId aPartId, TBool aRecursive  )
       
   217 	{
       
   218 	iContext.VerifyTypeL( aPartId, EMsgStorePartBits );
       
   219 	
       
   220 	TMsgStoreId parentId = ( aRecursive ? KMsgStoreInvalidId : Id() );
       
   221 	
       
   222 	RBuf8 propertiesBuf;
       
   223 	CleanupClosePushL( propertiesBuf );
       
   224 	
       
   225 	iContext.iSession.ContainerPropertiesL( aPartId, parentId, KMsgStoreInvalidId, propertiesBuf );	
       
   226 	
       
   227 	if ( !aRecursive && parentId != Id() )
       
   228 		{
       
   229 		//the part may have been moved, so it is no longer a child of this part
       
   230 		User::Leave( KErrNotFound );
       
   231 		}
       
   232 	
       
   233 	CMsgStoreMessagePart* part = CMsgStoreMessagePart::NewL( iContext, aPartId, parentId, iMailBoxId, propertiesBuf );
       
   234 	
       
   235 	CleanupStack::PopAndDestroy( &propertiesBuf );
       
   236 	
       
   237 	return part;
       
   238 	}
       
   239 
       
   240 /** list all the child part to this part 
       
   241     /note This method leaves with KErrNotSupported if it is NOT multi-part.
       
   242 */
       
   243 EXPORT_C void CMsgStoreMessagePart::ChildPartsL( RPointerArray<CMsgStoreMessagePart>& aParts )
       
   244 {
       
   245 	
       
   246 	TPartsArray partsArray( iContext, iMailBoxId, aParts );
       
   247 	
       
   248 	iContext.iSession.ChildrenPropertiesL( iId,               // aId
       
   249 	                                       iParentId,         // aParentId
       
   250 	                                       EMsgStorePartBits, // aContainerType
       
   251 	                                       EFalse,            // aQuickProperties
       
   252 	                                       EFalse,            // aRecursive	                                        	                                        
       
   253 	                                       partsArray );	
       
   254 	
       
   255 	// make sure body come before attachments
       
   256 	TInt count = aParts.Count(); 
       
   257 	if ( count > 1 )
       
   258 		{
       
   259 		for ( TInt i = 0 ; i < count; i++ )
       
   260 			{
       
   261 			CMsgStoreMessagePart* part = aParts[i];
       
   262 			TUint index = 0;
       
   263 			if ( part->FindProperty( KMsgStorePropertyContentType, index ) )
       
   264 				{
       
   265 				const TDesC& contentType = part->PropertyValueDesL( index );
       
   266 				if ( contentType == KFSMailContentTypeMultipartAlternative )
       
   267 					{
       
   268 						if( i > 0 )  
       
   269 							{
       
   270 							//body is not the first child, move it to the first place
       
   271 							aParts.Remove(i);
       
   272 							aParts.Insert( part, 0 );
       
   273 							}
       
   274 						break;
       
   275 					}
       
   276 				}
       
   277 			}
       
   278 		}
       
   279 }
       
   280 
       
   281 EXPORT_C TBool CMsgStoreMessagePart::IsEmbeddedMessageL()
       
   282 	{
       
   283 	
       
   284 	TUint index;
       
   285 	TBool isEmbeddedMsg = EFalse;
       
   286 	
       
   287 	if ( FindProperty( KMsgStorePropertyIsEmbeddedMsg, index ) )
       
   288 		{
       
   289 		isEmbeddedMsg = PropertyValueBoolL( index );
       
   290 		}
       
   291 	
       
   292 	return isEmbeddedMsg;
       
   293 	
       
   294 	}
       
   295 
       
   296 
       
   297 CMsgStoreMessagePart* CMsgStoreMessagePart::NewL( CMsgStoreSessionContext& aSessionContext, 
       
   298 												  TMsgStoreId              aId, 
       
   299 												  TMsgStoreId              aParentId, 
       
   300 												  TMsgStoreId              aMailBoxId,
       
   301 												  const TDesC8&            aPropertiesBuf )
       
   302 	{												  
       
   303 	CMsgStoreMessagePart* self = new( ELeave ) CMsgStoreMessagePart( aSessionContext, aId, aParentId, aMailBoxId );
       
   304 	CleanupStack::PushL( self );
       
   305 	self->ConstructL( aPropertiesBuf );
       
   306 	
       
   307 	//check if the flag is embedded message exists
       
   308 	if ( self->IsEmbeddedMessageL() )
       
   309 		{
       
   310 		CleanupStack::PopAndDestroy( self );
       
   311 		//create an instance of embedded message
       
   312 		self = CMsgStoreMessage::NewL( aSessionContext, aId, aParentId, KMsgStoreInvalidId, aMailBoxId, aPropertiesBuf );
       
   313 		}
       
   314 	else
       
   315 		{
       
   316 		CleanupStack::Pop( self );
       
   317 		}
       
   318 	
       
   319 	return self;
       
   320 	}
       
   321 
       
   322 void CMsgStoreMessagePart::ConstructL( const TDesC8& aPropertiesBuf )
       
   323 	{
       
   324 	DeserializeL( aPropertiesBuf );
       
   325 	}
       
   326 
       
   327 CMsgStoreMessagePart::CMsgStoreMessagePart( CMsgStoreSessionContext& aSessionContext, TMsgStoreId aId, TMsgStoreId aParentId, TMsgStoreId aMailBoxId )
       
   328 : CMsgStorePropertyContainerWithContent( aSessionContext, aId, aParentId, aMailBoxId )
       
   329 	{
       
   330 	}
       
   331 		
       
   332 
       
   333