mobilemessaging/smsmtm/clientmtm/src/SMSCLNT.CPP
changeset 0 72b543305e3a
child 9 1d7827e39b52
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 // Copyright (c) 1999-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 // SMSCLNT.CPP
       
    15 //
       
    16 
       
    17 #include <txtrich.h>	// CRichText
       
    18 
       
    19 #include <msvuids.h>	// KUidMsvRootEntry etc.
       
    20 #include <mtmdef.hrh>	// KUidMtmQuerySupports etc.
       
    21 #include <mtmdef.h>		// KMsvMessagePartRecipient	etc.
       
    22 #include <msvids.h>		// KMsvGlobalOutBoxIndexEntryId etc.
       
    23 #include <msvftext.h>	// CMsvFindText
       
    24 #include <biodb.h>		// CBIODatabase
       
    25 #include <smss.rsg>
       
    26 #include <barsc.h>
       
    27 #include <barsread.h>
       
    28 
       
    29 #include "SMSCLNT.H"	// smsclntmtm
       
    30 #include "SMCMMAIN.H"	// panics
       
    31 #include "smscmds.h"	// ESmsMtmCommandReadServiceCenter etc.
       
    32 #include "smut.h"		// TSmsUtilities
       
    33 #include "SMUTHDR.H"	// CSmsHeader
       
    34 #include "SMUTSET.H"	// CSmsSettings
       
    35 #include <smutsimparam.h>
       
    36 #include <csmsemailfields.h>
       
    37 #include <csmsaccount.h>
       
    38 #include "csmssendmessageoperation.h"
       
    39 
       
    40 #include <msvenhancesearchsortutil.h>
       
    41 
       
    42 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
       
    43 #include "msvconsts.h"
       
    44 #include <mtmuidsdef.hrh>
       
    45 #include <tmsvsmsentry.h>
       
    46 #endif
       
    47 
       
    48 
       
    49 
       
    50 /**
       
    51 The maximum number of SMS PDUs allowed in a concatenated SMS message.
       
    52 Together with KSmcmMaxCharsInMessageConcatenated7Bit, this is the response to
       
    53 the query for the KUidMtmQueryMaxTotalMsgSizeValue capability.
       
    54 @see	CSmsClientMtm::QueryCapability
       
    55 @see	KSmcmMaxCharsInMessageConcatenated7Bit
       
    56 */
       
    57 const TInt KSmcmMaxMessageNumber=0x32;
       
    58 
       
    59 /**
       
    60 The maximum number of characters in a concatenated SMS PDU.
       
    61 Together with KSmcmMaxMessageNumber, this is the response to the query for the
       
    62 KUidMtmQueryMaxTotalMsgSizeValue capability.
       
    63 @see	CSmsClientMtm::QueryCapability
       
    64 @see	KSmcmMaxCharsInMessageConcatenated7Bit
       
    65 */
       
    66 const TInt KSmcmMaxCharsInMessageConcatenated7Bit=0x99;
       
    67 
       
    68 /**
       
    69 The maximum number of characters in a non-concatenated SMS PDU.
       
    70 This is the response to the query for the KUidMtmQueryMaxBodySizeValue
       
    71 capability.
       
    72 @see	CSmsClientMtm::QueryCapability
       
    73 */
       
    74 const TInt KSmcmMaxTotalMsgSize=160;
       
    75 
       
    76 /**
       
    77 The granularity of the in-memory buffer for CRichText objects.
       
    78 @see	CRichText::NewL
       
    79 */
       
    80 const TInt KSmcmRichTextConstant=256;
       
    81 
       
    82 
       
    83 // These default subject formats are used if the resource field has not been
       
    84 // migrated to include a localised set of subject formats.
       
    85 _LIT(KSmsDefaultForwardSubjectFormat,	"Fw: %S");
       
    86 _LIT(KSmsDefaultReplySubjectFormat,		"Re: %S");
       
    87 
       
    88 /**
       
    89 Static factory constuctor.
       
    90 
       
    91 @param	aRegisteredMtmDll
       
    92 The registry information for the SMS MTM.
       
    93 
       
    94 @param	aSession
       
    95 The message server session
       
    96 
       
    97 @leave KErrArgument
       
    98 Invalid data read from the SMS resource file
       
    99 
       
   100 @internalTechnology
       
   101 
       
   102 @see	CRegisteredMtmDll
       
   103 */
       
   104 EXPORT_C CSmsClientMtm* CSmsClientMtm::NewL(CRegisteredMtmDll& aRegisteredMtmDll,CMsvSession& aSession)
       
   105 	{
       
   106 	CSmsClientMtm* self=new(ELeave) CSmsClientMtm(aRegisteredMtmDll,aSession);
       
   107 	CleanupStack::PushL(self);
       
   108 	self->ConstructL();
       
   109 	CleanupStack::Pop(self);
       
   110 	return self;
       
   111 	}
       
   112 
       
   113 /**
       
   114 Destructor.
       
   115 */
       
   116 CSmsClientMtm::~CSmsClientMtm()
       
   117 	{
       
   118 	delete iServiceSettings;
       
   119 	delete iSmsHeader;
       
   120 	delete iEmailForwardSubjectFormat;
       
   121 	delete iEmailReplySubjectFormat;
       
   122 	}
       
   123 
       
   124 void CSmsClientMtm::HandleEntryEvent(enum MMsvEntryObserver::TMsvEntryEvent /*aEvent*/,TAny* ,TAny* ,TAny* )
       
   125 	{
       
   126 	}
       
   127 
       
   128 /**
       
   129 Reads SMS parameters from the SIM.
       
   130 
       
   131 It starts a new CSmsSimParamOperation, which uses the SMS Server MTM to read the 
       
   132 SMS parameters from the SIM. 
       
   133 
       
   134 If the phone is unable to supply the SMS parameters from the SIM, then the progress
       
   135 information of the CSmsSimParamOperation operation will contain an error. 
       
   136 
       
   137 @param	aObserverRequestStatus
       
   138 The request status to be completed when the read operation has completed.
       
   139 
       
   140 @return
       
   141 A SIM parameter reader operation. The read SIM parameters are stored in
       
   142 CSmsSimParamOperation::iSimParams. 
       
   143 */
       
   144 EXPORT_C CSmsSimParamOperation* CSmsClientMtm::ReadSimParamsL(TRequestStatus& aObserverRequestStatus)
       
   145 	{
       
   146 	RestoreServiceAndSettingsL();
       
   147 
       
   148 	CMsvEntry* entry = Session().GetEntryL(iServiceId);
       
   149 	CleanupStack::PushL(entry);
       
   150 
       
   151 	CSmsSimParamOperation* op = CSmsSimParamOperation::ReadSimParamsL(entry->Entry().iMtm, iServiceId, Session(), aObserverRequestStatus);
       
   152 
       
   153 	CleanupStack::PopAndDestroy(entry);
       
   154 	return op;
       
   155 	}
       
   156 
       
   157 /**
       
   158 Writes SMS parameters to the SIM.
       
   159 
       
   160 It starts a new CSmsSimParamOperation, which uses the SMS Server to write the 
       
   161 specified SIM parameters to the SIM.
       
   162 
       
   163 If the phone is unable to write the SMS parameters to the SIM, then the progress
       
   164 information of the CSmsSimParamOperation operation will contain an error.
       
   165 
       
   166 @param	aList
       
   167 The SIM parameters to be written.
       
   168 
       
   169 @param	aObserverRequestStatus
       
   170 The request status to be completed when the write operation has completed.
       
   171 
       
   172 @return
       
   173 A SIM parameter writer operation.
       
   174 */
       
   175 EXPORT_C CSmsSimParamOperation* CSmsClientMtm::WriteSimParamsL(const CMobilePhoneSmspList& aList, TRequestStatus& aObserverRequestStatus)
       
   176 	{
       
   177 	RestoreServiceAndSettingsL();
       
   178 
       
   179 	CMsvEntry* entry = Session().GetEntryL(iServiceId);
       
   180 	CleanupStack::PushL(entry);
       
   181 
       
   182 	CSmsSimParamOperation* op = CSmsSimParamOperation::WriteSimParamsL(aList, entry->Entry().iMtm, iServiceId, Session(), aObserverRequestStatus);
       
   183 
       
   184 	CleanupStack::PopAndDestroy(entry);
       
   185 
       
   186 	return op;
       
   187 	}
       
   188 
       
   189 /**
       
   190 Restores the SMS service ID and SMS service settings.
       
   191 
       
   192 The SMS service ID is obtained. The service settings for the obtained ID are 
       
   193 restored from the message server. The SMS service ID can be obtained using the
       
   194 CSmsClientMtm::ServiceId API and the SMS settings are accessed via the two
       
   195 CSmsClientMtm::ServiceSettings API overloads.
       
   196 
       
   197 This API should be used before using any of the other APIs that required the SMS
       
   198 service ID and SMS service settings to be set.
       
   199 
       
   200 @see	CSmsClientMtm::ServiceId
       
   201 @see	CSmsClientMtm::ServiceSettings
       
   202 */
       
   203 EXPORT_C void CSmsClientMtm::RestoreServiceAndSettingsL()
       
   204 	{
       
   205 	if (iServiceSettings == NULL)
       
   206 		{
       
   207 		iServiceSettings = CSmsSettings::NewL();
       
   208 		}
       
   209 
       
   210 	// Let's find the right service entry!
       
   211 	TSmsUtilities::ServiceIdL(Session(), iServiceId, KUidMsgTypeSMS);
       
   212 
       
   213 	CSmsAccount* account = CSmsAccount::NewLC();
       
   214 	// just v2
       
   215 	account->LoadSettingsL(*iServiceSettings);
       
   216 	CleanupStack::PopAndDestroy(account);    
       
   217 	}
       
   218 
       
   219 
       
   220 CSmsClientMtm::CSmsClientMtm(CRegisteredMtmDll& aRegisteredMtmDll,CMsvSession& aSession)
       
   221 : CBaseMtm(aRegisteredMtmDll,aSession)
       
   222 	{
       
   223 	}
       
   224 
       
   225 void CSmsClientMtm::ConstructL()
       
   226 	{
       
   227 	SwitchCurrentEntryL(KMsvRootIndexEntryId);  //  Creates rich text
       
   228 	
       
   229 	RFs& fileSession = Session().FileSession();
       
   230 
       
   231 	iSmsHeader=CSmsHeader::NewL(CSmsPDU::ESmsSubmit,Body(),fileSession);
       
   232 
       
   233 	TRAPD(err, RestoreServiceAndSettingsL());
       
   234 
       
   235 	if (err)
       
   236 		{
       
   237 		if (err != KErrNotFound)
       
   238 			{
       
   239 			User::Leave(err);
       
   240 			}
       
   241 
       
   242 		iServiceId = 0;
       
   243 		}
       
   244 
       
   245 	//Initialise iRealAddressOpen and iRealAddressClose from the SMS resouce file
       
   246 	RResourceFile resFile = TSmsUtilities::OpenResourceFileL(fileSession);
       
   247 	CleanupClosePushL(resFile);
       
   248 	TBuf<4> buf;
       
   249 	TSmsUtilities::ReadResourceStringL(resFile, R_ADDRESSEE_TELEPHONE_OPEN, buf);
       
   250 	if (buf.Length() > 0)
       
   251 		{
       
   252 		iRealAddressOpen = buf[0];
       
   253 		}
       
   254 	else
       
   255 		{
       
   256 		User::Leave(KErrArgument); 
       
   257 		}
       
   258 	
       
   259 	TSmsUtilities::ReadResourceStringL(resFile, R_ADDRESSEE_TELEPHONE_CLOSE, buf);
       
   260 	if (buf.Length() > 0)
       
   261 		{
       
   262 		iRealAddressClose = buf[0];
       
   263 		}
       
   264 	else
       
   265 		{
       
   266 		User::Leave(KErrArgument); 
       
   267 		}
       
   268 	iEmailForwardSubjectFormat	= ReadEmailSubjectFormatL(resFile, R_SMS_EMAIL_FORWARD_SUBJECT_FORMAT, KSmsDefaultForwardSubjectFormat);
       
   269 	iEmailReplySubjectFormat	= ReadEmailSubjectFormatL(resFile, R_SMS_EMAIL_REPLY_SUBJECT_FORMAT, KSmsDefaultReplySubjectFormat);
       
   270 
       
   271 	CleanupStack::PopAndDestroy(&resFile);
       
   272 	}
       
   273 	
       
   274 HBufC* CSmsClientMtm::ReadEmailSubjectFormatL(RResourceFile& aResourceFile, TInt aResourceId, const TDesC& aDefaultFormat)
       
   275 	{
       
   276 	HBufC* format = NULL;
       
   277 	if( aResourceFile.OwnsResourceId(aResourceId) )
       
   278 		{
       
   279 		HBufC8* buf = aResourceFile.AllocReadLC(aResourceId);
       
   280 		TResourceReader reader;
       
   281 		reader.SetBuffer(buf);
       
   282 		format = (reader.ReadTPtrC()).AllocL();
       
   283 		CleanupStack::PopAndDestroy(buf);	
       
   284 		}
       
   285 	else
       
   286 		{
       
   287 		format = aDefaultFormat.AllocL();
       
   288 		}
       
   289 	return format;
       
   290 	}
       
   291 
       
   292 CMsvOperation* CSmsClientMtm::CreateNewEntryL(TMsvEntry& aNewEntry, TMsvId aDestination,CSmsHeader& aSmsHeader,const CRichText& aBody,TRequestStatus& aCompletionStatus)
       
   293 	{
       
   294 	RestoreServiceAndSettingsL();
       
   295 
       
   296 	CMsvEntry* cEntry = CMsvEntry::NewL(Session(), aDestination, TMsvSelectionOrdering());
       
   297 	CleanupStack::PushL(cEntry);
       
   298 
       
   299 	cEntry->CreateL(aNewEntry);
       
   300 
       
   301 	const TMsvId msvid = aNewEntry.Id();
       
   302 	Session().CleanupEntryPushL(msvid);
       
   303 
       
   304 	// switch context to the new entry
       
   305 	cEntry->SetEntryL(msvid);
       
   306 	aNewEntry = cEntry->Entry(); //for the description and details fields
       
   307 
       
   308 	aSmsHeader.SetSmsSettingsL(*iServiceSettings);
       
   309 
       
   310 	// service centre was not being set 
       
   311 	//If we haven't been provided with a service centre address then use the default one
       
   312 	if(!aSmsHeader.ReplyPathProvided())
       
   313 		{
       
   314 		TInt defaultSC = iServiceSettings->DefaultServiceCenter();
       
   315 		if(defaultSC > -1)
       
   316 			{
       
   317 			aSmsHeader.SetServiceCenterAddressL( iServiceSettings->GetServiceCenter(defaultSC).Address() );	
       
   318 			}
       
   319 		}
       
   320 
       
   321 	// Check the context header to see an email message...
       
   322 	if( iSmsHeader->EmailFields().Length() > 0 )
       
   323 		{
       
   324 		// Yep - update the message as follows
       
   325 		// 1. Add the email <-> SMS gateway as the recipient of the new message.
       
   326 		// 2. Set the PID for interworking with email.
       
   327 		// 3. Set the entry description to be the email subject (if there is one).
       
   328 		// 4. Set the entry details to be the email address (if there is one).
       
   329 		DoAddRecipientL(&aSmsHeader, iSmsHeader->FromAddress(), KNullDesC);
       
   330 
       
   331 		CSmsPDU& pdu = aSmsHeader.Message().SmsPDU();
       
   332 		if( pdu.ProtocolIdentifierPresent() )
       
   333 			{
       
   334 			pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking);
       
   335 			pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice);
       
   336 			pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail);
       
   337 			}
       
   338 		
       
   339 		const CSmsEmailFields& fields = aSmsHeader.EmailFields();
       
   340 		if( fields.Subject().Length() > 0 )
       
   341 			{
       
   342 			// There is a subject - use this as the description
       
   343 			aNewEntry.iDescription.Set(fields.Subject());
       
   344 			}
       
   345 		if( fields.HasAddress() )
       
   346 			{
       
   347 			// There is an address - use first address as the details.
       
   348 			aNewEntry.iDetails.Set(fields.Addresses().MdcaPoint(0));			
       
   349 			}
       
   350 		}
       
   351 
       
   352 
       
   353 	CMsvStore* msvstore=cEntry->EditStoreL();
       
   354 	CleanupStack::PushL(msvstore);
       
   355 
       
   356 	aSmsHeader.StoreL(*msvstore);
       
   357 	msvstore->StoreBodyTextL(aBody);
       
   358 	msvstore->CommitL();
       
   359 
       
   360 	aNewEntry.iSize = msvstore->SizeL();
       
   361 	cEntry->ChangeL(aNewEntry);
       
   362 
       
   363 	CleanupStack::PopAndDestroy(msvstore);
       
   364 
       
   365 
       
   366 	TPckg<TMsvId> prog(msvid);
       
   367 	CMsvOperation* op = CMsvCompletedOperation::NewL(Session(), KUidMsgTypeSMS, prog, aNewEntry.iServiceId, aCompletionStatus);
       
   368 
       
   369 	// Now safe to pop the entry off the message server cleanup stack, and any
       
   370 	// other remaining resources.
       
   371 	Session().CleanupEntryPop();
       
   372 	CleanupStack::PopAndDestroy(cEntry);
       
   373 
       
   374 	return op;
       
   375 	}
       
   376 
       
   377 TBool CSmsClientMtm::ValidRecipients() const
       
   378 	{
       
   379 	TInt numrecipients = iSmsHeader->Recipients().Count();
       
   380 	TBool valid=numrecipients;
       
   381 
       
   382 	while (numrecipients-- && valid)
       
   383 		valid=ValidNumber(iSmsHeader->Recipients()[numrecipients]->Address());
       
   384 
       
   385 	return valid;
       
   386 	}
       
   387 
       
   388 TBool CSmsClientMtm::ValidNumber(const TDesC& aNumber) const
       
   389 	{
       
   390 	TBool valid=EFalse;
       
   391 	for (TInt i=0; i<aNumber.Length() && !valid; i++)  //  valid if at least one number in string
       
   392 		valid=(aNumber[i]>='0') && (aNumber[i]<='9');
       
   393 	return valid;
       
   394 	}
       
   395 
       
   396 void CSmsClientMtm::DoAddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias)
       
   397 	{
       
   398 	if (aAlias.Length())
       
   399 		{
       
   400 		HBufC* buf=HBufC::NewLC(aAlias.Length()+aRealAddress.Length()+3);
       
   401 		TPtr ptr = buf->Des();
       
   402 		ptr.Copy(aAlias);
       
   403 		ptr.Append(_L(" "));
       
   404 		ptr.Append(iRealAddressOpen);
       
   405 		ptr.Append(aRealAddress);
       
   406 		ptr.Append(iRealAddressClose);
       
   407 		iAddresseeList->AppendL(ptr);
       
   408 		CleanupStack::PopAndDestroy(buf);
       
   409 		}
       
   410 	else
       
   411 		iAddresseeList->AppendL(aRealAddress);
       
   412 	}
       
   413 
       
   414 void CSmsClientMtm::AddRecipientL(const TDesC& aRealAddress, const TDesC& aAlias)
       
   415 	{
       
   416 	DoAddRecipientL(iSmsHeader, aRealAddress, aAlias);
       
   417 	}
       
   418 
       
   419 void CSmsClientMtm::DoAddRecipientL(CSmsHeader* aSmsHeader, const TDesC& aRealAddress, const TDesC& aAlias)
       
   420 	{
       
   421 	CSmsNumber* recipient=CSmsNumber::NewL();
       
   422 	CleanupStack::PushL(recipient);
       
   423 	if ( aRealAddress.Locate('@') != KErrNotFound )
       
   424         {
       
   425         CSmsEmailFields* emailFields = NULL;
       
   426         if ( aSmsHeader->EmailFields().Length() > 0 )
       
   427             {
       
   428             emailFields = CSmsEmailFields::NewL( aSmsHeader->EmailFields() );
       
   429             }
       
   430         else
       
   431             {
       
   432             emailFields = CSmsEmailFields::NewL();
       
   433             }
       
   434         CleanupStack::PushL( emailFields );
       
   435        
       
   436 		recipient->SetEmailAddressL(aRealAddress, emailFields, aAlias);
       
   437        
       
   438         // Clears the CSmsHeaders EmailFields for non Email addresses
       
   439         aSmsHeader->SetEmailFieldsL( *emailFields );
       
   440         CleanupStack::PopAndDestroy( emailFields );
       
   441         }
       
   442 	else
       
   443 	    {
       
   444 	    recipient->SetAddressL(aRealAddress);
       
   445 	    if (aAlias.Length() > 0)
       
   446 	    	{	
       
   447 	        recipient->SetNameL(aAlias);
       
   448 	    	}
       
   449 	    }
       
   450     aSmsHeader->Recipients().AppendL(recipient);
       
   451     CleanupStack::Pop(recipient);
       
   452 	}
       
   453 
       
   454 void CSmsClientMtm::ResetHeader()
       
   455 	{
       
   456 	if (iSmsHeader)
       
   457 		iSmsHeader->Recipients().ResetAndDestroy();
       
   458 
       
   459 	if (iAddresseeList)
       
   460 		iAddresseeList->Reset();
       
   461 	}
       
   462 
       
   463 void CSmsClientMtm::FindInBodyL(const TDesC& aTextToFind, const TMsvPartList& aFoundList, TMsvPartList& aResult)
       
   464 	{
       
   465 	CMsvFindText* text=CMsvFindText::NewL();
       
   466 	CleanupStack::PushL(text);
       
   467 	if (text->FindRichTextL(aTextToFind,Body(),aFoundList))
       
   468 		aResult|=KMsvMessagePartBody;
       
   469 	CleanupStack::PopAndDestroy(text);
       
   470 	}
       
   471 
       
   472 void CSmsClientMtm::FindL(const TDesC& aTextToFind, const TMsvPartList aPartList, TMsvPartList& aFoundList)
       
   473 	{
       
   474 	
       
   475 	CMsvFindText* text=CMsvFindText::NewL();
       
   476 	CleanupStack::PushL(text);
       
   477 
       
   478 	// Enhance search and sort
       
   479   	// The setting variables are accessed by getting an instance to TMsvEnhanceSearchSortUtil  class
       
   480   	// This is accessed here by using GetExtensionData() defined in CBaseMtm which refers 
       
   481   	// to iExtensionData member variable
       
   482  	TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   483 		
       
   484 	if(searchsortutil != NULL)
       
   485 		{
       
   486 		// For callees other than CMsvSearchsortOpOnHeaderBody class, searchsortutil pointer will be NULL	
       
   487 		
       
   488 		TInt index=0;
       
   489 		TBool foundinname = EFalse;
       
   490 		TBool foundinaddress = EFalse;
       
   491 
       
   492 		// Retrieve the search sort setting flags
       
   493 		TUint32 searchsortsetting=searchsortutil->GetSearchSortSetting();
       
   494 		
       
   495 		if(aPartList & KMsvMessagePartTo)
       
   496 			{
       
   497 			TInt count=iSmsHeader->Recipients().Count();
       
   498 			/* 
       
   499 			Search for the To field in the the SMS header
       
   500 			First it looks in the Senders name
       
   501 			if not found, it tries to find it in the senders numbers
       
   502 			*/
       
   503 			
       
   504 			for(TInt i=0;i<count;i++)
       
   505 				{
       
   506 				if ((text->FindTextL(aTextToFind,(iSmsHeader->Recipients()).operator[](i)->Name(),aPartList)))
       
   507 					{
       
   508 					aFoundList|=KMsvMessagePartTo;
       
   509 					foundinname = ETrue;
       
   510 					index = i;
       
   511 					}
       
   512 				if(!foundinname)
       
   513 					{
       
   514 					if ((text->FindTextL(aTextToFind,(iSmsHeader->Recipients()).operator[](i)->Address(),aPartList)))
       
   515 						{
       
   516 						aFoundList|=KMsvMessagePartTo;
       
   517 						foundinaddress = ETrue;
       
   518 						index = i;
       
   519 						}
       
   520 					}
       
   521 				}
       
   522 			}
       
   523 			// Search for the From field
       
   524 		else if(aPartList & KMsvMessagePartFrom)
       
   525 			{
       
   526 			if ((text->FindTextL(aTextToFind,iSmsHeader->FromAddress(),aPartList)) 
       
   527 		 	|| (text->FindTextL(aTextToFind,iMsvEntry->Entry().iDetails,aPartList)))
       
   528 				{
       
   529 				aFoundList|=KMsvMessagePartFrom;
       
   530 				}
       
   531 			}
       
   532 			// Search for the Subject
       
   533 		else if (aPartList & KMsvMessagePartSubject)
       
   534 			{
       
   535 			if (text->FindTextL(aTextToFind,iMsvEntry->Entry().iDescription,aPartList))
       
   536 				{
       
   537 				aFoundList|=KMsvMessagePartDescription;
       
   538 				}
       
   539 			}
       
   540 		/* Copy the sort data if sorting is specified.
       
   541 		 The operations being performed could be only be sort or it could be search and sort
       
   542 		 If the operation is search and sort than copy the sort data only if the
       
   543 		 search operation succeeded	*/
       
   544 					
       
   545 		if ((aPartList & EMessagePartSort ) || ((aPartList & EMessagePartSearchSort) && (aPartList & EMessagePartLastQueryOption) && aFoundList)) 
       
   546 			{
       
   547 			if (aPartList & EMessagePartToSort )
       
   548    				{
       
   549    				if(foundinname) // Copy the sort data form the senders name
       
   550    					{
       
   551    					TPtrC ptr((iSmsHeader->Recipients()).operator[](index)->Name());
       
   552    					SetExtensionData(&ptr);
       
   553    					}
       
   554    				if(foundinaddress) // Copy data from senders Address
       
   555    					{
       
   556    					TPtrC ptr((iSmsHeader->Recipients()).operator[](index)->Address());	
       
   557    					SetExtensionData(&ptr);
       
   558    					}
       
   559    				}
       
   560 			else if(aPartList & EMessagePartFromSort )
       
   561    				{
       
   562    				SetExtensionData((TAny*)(iSmsHeader->FromAddress().Ptr()));
       
   563    				}
       
   564    			else if(aPartList & EMessagePartSubjectSort )
       
   565    				{
       
   566    				SetExtensionData((TAny*)&iMsvEntry->Entry().iDescription);
       
   567 				}
       
   568 			else 
       
   569    				// Fix for DEF124605. If a different sort field is specified than
       
   570    				// sets setting flag to EMessagePartInvalidSortField
       
   571    				{
       
   572    				searchsortutil->SetSearchSortSetting(EMessagePartInvalidSortField);
       
   573    				}
       
   574 			}
       
   575 		}
       
   576 	else
       
   577 		{
       
   578 	
       
   579 		// Implementation prior to PREQ1667
       
   580 		if (aPartList & KMsvMessagePartRecipient) 		
       
   581 			{
       
   582 			TInt count=iSmsHeader->Recipients().Count();
       
   583 	
       
   584 			for(TInt i=0;i<count;i++)
       
   585 				{
       
   586 				if ((text->FindTextL(aTextToFind,(iSmsHeader->Recipients()).operator[](i)->Name(),aPartList))
       
   587 			 	|| (text->FindTextL(aTextToFind,(iSmsHeader->Recipients()).operator[](i)->Address(),aPartList)))
       
   588 					{
       
   589 					aFoundList|=KMsvMessagePartRecipient;
       
   590 					}
       
   591 				}
       
   592 			}
       
   593 		else if(aPartList & KMsvMessagePartOriginator)
       
   594 			{
       
   595 			if((text->FindTextL(aTextToFind,iSmsHeader->FromAddress(),aPartList)) 
       
   596 			 || (text->FindTextL(aTextToFind,iMsvEntry->Entry().iDetails,aPartList)))
       
   597 				{
       
   598 				aFoundList|=KMsvMessagePartOriginator;
       
   599 				}
       
   600 			}
       
   601 		else if (aPartList & KMsvMessagePartDescription)
       
   602 			{
       
   603 			if (text->FindTextL(aTextToFind,iMsvEntry->Entry().iDescription,aPartList))
       
   604 				{
       
   605 				aFoundList|=KMsvMessagePartDescription;
       
   606 				}
       
   607 			}
       
   608 		}
       
   609 	CleanupStack::PopAndDestroy(text);
       
   610 	}
       
   611 
       
   612 
       
   613 TMsvPartList CSmsClientMtm::DoFindL(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   614 	{
       
   615 	__ASSERT_DEBUG(iMsvEntry, Panic(ESmscEntryNotSet));
       
   616 
       
   617 	TMsvPartList retList = 0;
       
   618 
       
   619 	// Enhance search and sort
       
   620   	// The setting variables are accessed by getting an instance to TMsvEnhanceSearchSortUtil  class
       
   621   	// This is accessed here by using GetExtensionData() defined in CBaseMtm which refers 
       
   622   	// to iExtensionData member variable
       
   623 	
       
   624  	TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   625 	
       
   626 	// For callees other than CMsvSearchsortOpOnHeaderBody class, searchsortutil pointer will be NULL	
       
   627 	if(searchsortutil !=NULL)
       
   628 		{
       
   629 		TUint32 searchsortsetting=searchsortutil->GetSearchSortSetting();
       
   630 		if ((aPartList & KMsvMessagePartBody) && !(searchsortsetting & EMessagePartBodyLoaded))
       
   631 			{
       
   632 			CMsvStore* msvstore=iMsvEntry->ReadStoreL();
       
   633 			CleanupStack::PushL(msvstore);
       
   634 			msvstore->RestoreBodyTextL(Body());			
       
   635 			FindInBodyL(aTextToFind,aPartList,retList); // Find in body	
       
   636 			CleanupStack::PopAndDestroy(msvstore);
       
   637 			
       
   638 			// The message body is loaded.Set the setting variable to specify that the body is loaded
       
   639 			// If the next search is also on body, than it wont be loaded next time around
       
   640 			
       
   641 			searchsortutil->SetSearchSortSetting(EMessagePartBodyLoaded); 
       
   642 			}
       
   643 		else if( (aPartList & KMsvMessagePartTo ) || (aPartList & KMsvMessagePartFrom ) || (aPartList & KMsvMessagePartSubject))
       
   644 			{
       
   645 			// Search for To, From and Subject
       
   646 			FindL(aTextToFind,aPartList,retList); // Find in header	
       
   647 			}
       
   648 		}
       
   649 	else
       
   650 		{
       
   651 		// Search implementation Prior to PREQ1667
       
   652 		if( (aPartList & KMsvMessagePartRecipient) || (aPartList & KMsvMessagePartOriginator) || (aPartList & KMsvMessagePartDescription))
       
   653 			{
       
   654 			FindL(aTextToFind,aPartList,retList); // Find in header	
       
   655 			}
       
   656 		else if(aPartList & KMsvMessagePartBody)
       
   657 			{
       
   658 			FindInBodyL(aTextToFind,aPartList,retList); // Find in body	
       
   659 			}
       
   660 
       
   661 		}
       
   662 	return retList;
       
   663 	}
       
   664 
       
   665 /*
       
   666 Used by ForwardL() and ReplyL() for initialising the contents of the new message
       
   667 */
       
   668 void CSmsClientMtm::BasicReplyForwardEntry(TMsvEntry& aNewEntry) const
       
   669 	{
       
   670 	aNewEntry.iMtm = KUidMsgTypeSMS;
       
   671  	// Fix for DEF000924: Need to be able to send/cancel an sms while another is being sent
       
   672  	aNewEntry.iRelatedId = Entry().Entry().iServiceId;
       
   673  	aNewEntry.iServiceId = KMsvLocalServiceIndexEntryId;
       
   674  	// End of fix
       
   675  	aNewEntry.iType = KUidMsvMessageEntry;
       
   676 	aNewEntry.iDate.UniversalTime();
       
   677 	}
       
   678 
       
   679 /*
       
   680  *	Methods from CBaseMtm
       
   681  */
       
   682 
       
   683 /** 
       
   684 Commits cached changes to the current message context to the message store.
       
   685 
       
   686 The current context must be set to a message entry with type KUidMsvServiceEntryValue,
       
   687 KUidMsvFolderEntryValue or KUidMsvMessageEntryValue. If the current context is
       
   688 not set, or is set to an entry with a type that is not supported by this function
       
   689 then a panic will occur.
       
   690 
       
   691 Both the SMS service ID and SMS service settings must have been set or a panic
       
   692 will occur. The CSmsClientMtm::RestoreServiceAndSettingsL API can restore both
       
   693 of these items.
       
   694 
       
   695 @panic	SMCM	1
       
   696 The current context has not been set (debug only).
       
   697 
       
   698 @panic	SMCM	4
       
   699 The type of the current context is not supported.
       
   700 
       
   701 @panic	SMCM	11
       
   702 The SMS Service settings have not been set (debug only).
       
   703 
       
   704 @panic	SMCM	12
       
   705 The ID for SMS Service has not been set (debug only).
       
   706 
       
   707 @see	CSmsClientMtm::RestoreServiceAndSettingsL
       
   708 */
       
   709 void CSmsClientMtm::SaveMessageL()
       
   710 	{
       
   711 	__ASSERT_DEBUG(iMsvEntry,Panic(ESmscEntryNotSet));
       
   712 
       
   713 	CMsvStore* msvstore=iMsvEntry->EditStoreL();
       
   714 	CleanupStack::PushL(msvstore);
       
   715 	
       
   716 	TMsvEntry entry(iMsvEntry->Entry());
       
   717 	TBool entryChanged = EFalse;
       
   718 	
       
   719 	switch (iMsvEntry->Entry().iType.iUid)
       
   720 		{
       
   721 		case KUidMsvServiceEntryValue:
       
   722 			{
       
   723 			__ASSERT_DEBUG(iServiceSettings, Panic(ESmscSettingsNotSet));
       
   724 			__ASSERT_DEBUG(iServiceId, Panic(ESmscServiceIdNotSet));
       
   725 
       
   726 			CSmsAccount* account = CSmsAccount::NewLC();
       
   727 			//just v2
       
   728 			account->SaveSettingsL(*iServiceSettings);
       
   729 			CleanupStack::PopAndDestroy(account);    
       
   730 			break;
       
   731 			}
       
   732 		case KUidMsvFolderEntryValue:
       
   733 			{
       
   734 			break;
       
   735 			}
       
   736 		case KUidMsvMessageEntryValue:
       
   737 			{
       
   738 			// since CreateMessageL creates message as in preparation and non-visible, the SaveMessageL
       
   739 			// must now make it visible and not in preparation
       
   740 
       
   741 			// If iDetails is empty, set it to be the first recipient in the header
       
   742 			if ((0 >= entry.iDetails.Length()) && (iSmsHeader->Recipients().Count() > 0))
       
   743 				{
       
   744 				CSmsNumber* recipient = iSmsHeader->Recipients().At(0);
       
   745 				if(recipient->Name().Length() > 0)
       
   746 					entry.iDetails.Set(recipient->Name());
       
   747 				else
       
   748 					entry.iDetails.Set(recipient->Address());
       
   749 				}
       
   750 			
       
   751 			// If iDescription is empty, set it to be the first part of the body text
       
   752 			if(Body().DocumentLength()>0 && 0 >= entry.iDescription.Length())
       
   753 				{
       
   754 				entry.iDescription.Set(Body().Read(0,iServiceSettings->DescriptionLength()));	
       
   755 				}
       
   756 			entry.SetVisible(ETrue);
       
   757 			entry.SetInPreparation(EFalse);	
       
   758 			entry.SetMultipleRecipients(iSmsHeader->Recipients().Count() > 1);
       
   759 			entryChanged = ETrue;
       
   760 
       
   761 			iSmsHeader->StoreL(*msvstore);
       
   762 			StoreBodyL(*msvstore);
       
   763 			break;
       
   764 			}
       
   765 		default:
       
   766 			Panic(ESmscUnrecognizedEntryType);
       
   767 		}
       
   768 	msvstore->CommitL();
       
   769 
       
   770  	// Set the iSize member of the TMsvEntry
       
   771  	if (iMsvEntry->HasStoreL())
       
   772  		{
       
   773  		const TInt size = msvstore->SizeL();		
       
   774  		if (entry.iSize != size)
       
   775  			{
       
   776  			entry.iSize = size; 			
       
   777  			entryChanged = ETrue;
       
   778  			}
       
   779  		}
       
   780 
       
   781 	CleanupStack::PopAndDestroy(msvstore);
       
   782 
       
   783 	if ( entryChanged )
       
   784 		{
       
   785 		// The entry info has been updated - commit to the store.		
       
   786 		iMsvEntry->ChangeL(entry);
       
   787 		}
       
   788 	}
       
   789 
       
   790 /**
       
   791 Loads the cache with the message data for the current context.
       
   792 
       
   793 The current context must be set to a message entry with type KUidMsvServiceEntryValue,
       
   794 KUidMsvFolderEntryValue or KUidMsvMessageEntryValue. If the current context is
       
   795 not set, or is set to an entry with a type that is not supported by this function
       
   796 then a panic will occur.
       
   797 
       
   798 If the current context is of type KUidMsvServiceEntryValue then the SMS service
       
   799 settings are restore from the context. The SMS service settings can be accessed
       
   800 using the overloaded CSmsClientMtm::ServiceSettings APIs .
       
   801 
       
   802 If the current context is of type KUidMsvMessageEntryValue then the SMS message
       
   803 object is restore from the context. This can be accessed using the overloaded 
       
   804 CSmsClientMtm::SmsHeader APIs.
       
   805 
       
   806 If the current context is of type KUidMsvFolderEntryValue then this function 
       
   807 does nothing.
       
   808 
       
   809 @panic	SMCM	1
       
   810 The current context has not been set (debug only).
       
   811 
       
   812 @panic	SMCM	4
       
   813 The entry type of the current context was not recognised.
       
   814 
       
   815 @see	CSmsClientMtm::SmsHeader
       
   816 @see	CSmsClientMtm::ServiceSettings
       
   817 */
       
   818 void CSmsClientMtm::LoadMessageL()
       
   819 	{
       
   820 	__ASSERT_DEBUG(iMsvEntry,Panic(ESmscEntryNotSet));
       
   821 
       
   822 	RestoreServiceAndSettingsL();
       
   823 
       
   824 	ResetHeader();
       
   825 	Body().Reset();
       
   826 	CMsvStore* msvstore=iMsvEntry->ReadStoreL();
       
   827 	CleanupStack::PushL(msvstore);
       
   828 	switch (iMsvEntry->Entry().iType.iUid)
       
   829 		{
       
   830 		case KUidMsvServiceEntryValue:
       
   831 			{
       
   832 			CSmsAccount* account = CSmsAccount::NewLC();
       
   833 			// just v2
       
   834 			account->LoadSettingsL(*iServiceSettings);
       
   835 			CleanupStack::PopAndDestroy(account);    
       
   836 			break;
       
   837 			}
       
   838 		case KUidMsvFolderEntryValue:
       
   839 			{
       
   840 			break;
       
   841 			}
       
   842 		case KUidMsvMessageEntryValue:
       
   843 			{
       
   844 			CSmsHeader* smsheader=CSmsHeader::NewL(CSmsPDU::ESmsSubmit,Body());
       
   845 			CleanupStack::PushL(smsheader);
       
   846 			smsheader->RestoreL(*msvstore);
       
   847 			// the following part inserts the recipients from header also to the smsclient
       
   848 			// the recipients are restored inside the csmsheader already
       
   849 			if (smsheader->Type()==CSmsPDU::ESmsSubmit)
       
   850 				{
       
   851 				for (TInt i=0; i<smsheader->Recipients().Count(); ++i)
       
   852 					{
       
   853 					CSmsNumber* recipient=smsheader->Recipients()[i];
       
   854 					DoAddAddresseeL(recipient->Address(),recipient->Name());
       
   855 					}
       
   856 				}
       
   857 				
       
   858 		// Get a reference to TMsvEnhanceSearchSortUtil  instance set by CMsvSearchsortOpOnHeaderBody class
       
   859 		// If advanced search and sort is being performed than do not load the body here
       
   860 		// For API's other than CMsvSearchsortOpOnHeaderBody-> FindInHeaderBodyL(), a call to LoadMessageL()
       
   861 		// loads the body.
       
   862 	
       
   863 			TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   864 			if ( searchsortutil == NULL )
       
   865 				{
       
   866 				msvstore->RestoreBodyTextL(Body()); // Restore Body text
       
   867 				}
       
   868 			CleanupStack::Pop(smsheader); 
       
   869 			delete iSmsHeader;
       
   870 			iSmsHeader=smsheader;
       
   871 			break;
       
   872 			}
       
   873 		default:
       
   874 			Panic(ESmscUnrecognizedEntryType);
       
   875 		}
       
   876 	CleanupStack::PopAndDestroy(msvstore);
       
   877 	}
       
   878 /** 
       
   879 Validates the current message context.
       
   880 
       
   881 The addresses for the message are checked to be well-formed SMS addresses.
       
   882 
       
   883 The current context must be set. If the current context is not set then a panic
       
   884 will occur.
       
   885 
       
   886 @param	aPartList
       
   887 Indicates the message parts for which the validation has been requested.
       
   888 
       
   889 @return
       
   890 If valid KErrNone is returned. If invalid, the invalid parts of the message are
       
   891 identified. The return error value is the bitmask of the TMsvPartList IDs for
       
   892 each invalid part
       
   893 
       
   894 @panic	SMCM	1
       
   895 The current context has not been set (debug only).
       
   896 
       
   897 @panic	SMCM	6
       
   898 The addressee list and recipient list do not match (debug only).
       
   899 */
       
   900 TMsvPartList CSmsClientMtm::ValidateMessage(TMsvPartList aPartList)
       
   901 	{
       
   902 	__ASSERT_DEBUG(iMsvEntry, Panic(ESmscEntryNotSet));
       
   903 	__ASSERT_DEBUG(iSmsHeader->Recipients().Count()==iAddresseeList->Count(), Panic(ESmscRecpAddresseeMiscount));
       
   904 
       
   905 	TMsvPartList partlist=TMsvPartList(0);
       
   906 	if (aPartList&KMsvMessagePartRecipient)
       
   907 		if (!ValidRecipients())  
       
   908 			partlist|=KMsvMessagePartRecipient;
       
   909 
       
   910 	return partlist;
       
   911 	}
       
   912 
       
   913 /**
       
   914 Searches the specified message part(s) for the plain-text version of the text 
       
   915 to be found.
       
   916 
       
   917 @param	aTextToFind
       
   918 The plain-text version of the text to be found. 
       
   919 
       
   920 @param	aPartList
       
   921 Indicates the message parts which should be searched. 
       
   922 
       
   923 @return
       
   924 If the text was not found, or searching is unsupported, 0. If the text was found,
       
   925 a bitmask of the TMsvPartList IDs for each part in which the text was present.
       
   926 */
       
   927 TMsvPartList CSmsClientMtm::Find(const TDesC& aTextToFind,TMsvPartList aPartList)
       
   928 	{
       
   929 	TMsvPartList retList = 0;
       
   930 	TRAP_IGNORE(retList = DoFindL(aTextToFind, aPartList));
       
   931 	return retList;
       
   932 	}
       
   933 
       
   934 /**
       
   935 Creates a new SMS message as a reply to the current message context.
       
   936 
       
   937 The SMS in the current context must be of type SMS-DELIVER, indicating a mobile
       
   938 terminated message.
       
   939 
       
   940 The current context must be set to a message entry with type KUidMsvMessageEntryValue.
       
   941 If the current context is not set, or is set to an entry not of type
       
   942 KUidMsvMessageEntryValuethen a panic will occur.
       
   943 
       
   944 The new SMS message has the recipient set to the sender of the message in the
       
   945 current context. It has a type SMS-SUBMIT, indicating a mobile originated meesage.
       
   946 If the SMS service settings CSmsSettings::ReplyQuoted is true then the reply
       
   947 message will contain the body of the original message, including any EMS elements.
       
   948 
       
   949 @param	aDestination
       
   950 The message entry (folder) under which to create the new message.
       
   951 
       
   952 @param	aPartList
       
   953 Ignored.
       
   954 
       
   955 @param	aCompletionStatus
       
   956 The request status to be completed when the operation has finished.
       
   957 
       
   958 @return
       
   959 An operation object. If the relpy email is successful created, the operation will
       
   960 complete with KErrNone. The operation's progress information is a TPckg<TMsvId>,
       
   961 containing the TMsvId of the new SMS message. If the reply message fails to be 
       
   962 created, the operation completes with the relevant error code.
       
   963 
       
   964 @leave	KErrNotSupported
       
   965 The current context does not have a PDU type of SMS-DELIVER.
       
   966 
       
   967 @panic	SMCM	1
       
   968 The current context has not been set (debug only).
       
   969 
       
   970 @panic	SMCM	2
       
   971 The current context was not of type KUidMsvMessageEntry (debug only).
       
   972 */
       
   973 CMsvOperation* CSmsClientMtm::ReplyL(TMsvId aDestination,TMsvPartList /*aPartList*/, TRequestStatus& aCompletionStatus)
       
   974 	{
       
   975 	LoadMessageL();
       
   976 
       
   977 	__ASSERT_DEBUG(iMsvEntry, Panic(ESmscEntryNotSet));
       
   978 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvMessageEntry, Panic(ESmscWrongContextType));
       
   979 
       
   980 	if (iSmsHeader->Type()!=CSmsPDU::ESmsDeliver)
       
   981 		{
       
   982 		User::Leave(KErrNotSupported);
       
   983 		}
       
   984 
       
   985 	CRichText* body = CRichText::NewL(iParaFormatLayer, iCharFormatLayer,CEditableText::EFlatStorage,KSmcmRichTextConstant);
       
   986 	CleanupStack::PushL(body);
       
   987 
       
   988 	CSmsHeader* smsheader=CSmsHeader::NewL(CSmsPDU::ESmsSubmit,Body());
       
   989 	CleanupStack::PushL(smsheader);
       
   990 
       
   991 	// Check to see if we are copying the contents of the original message
       
   992 	if(iServiceSettings->ReplyQuoted() && iMsvEntry->Entry().iBioType==NULL)
       
   993 		{
       
   994 		// Copy original rich text
       
   995 		body->AppendTakingSolePictureOwnershipL(Body());
       
   996 		// Copy ems elements from original message to new message
       
   997 		iSmsHeader->Message().CopyEmsElementsL(smsheader->Message());
       
   998 		}
       
   999 		
       
  1000 	if( iSmsHeader->EmailFields().Length() > 0 )
       
  1001 		{
       
  1002 		// The context message is an email message - set the email fields for
       
  1003 		// the new message.
       
  1004 		smsheader->SetReplyEmailFieldsL(iSmsHeader->EmailFields(), *iEmailReplySubjectFormat);
       
  1005 		}
       
  1006 	else
       
  1007 		{
       
  1008 		// Get the reply to address if there is one else the from address.
       
  1009 		DoAddRecipientL(smsheader, iSmsHeader->ReplyAddressL(), iMsvEntry->Entry().iDetails);
       
  1010 		}
       
  1011 
       
  1012 	if(iSmsHeader->Deliver().ReplyPath())
       
  1013 		{
       
  1014 		smsheader->Submit().SetServiceCenterAddressL(iSmsHeader->Deliver().ServiceCenterAddress());
       
  1015 		smsheader->SetReplyPathProvided(ETrue);
       
  1016 		}
       
  1017 	else smsheader->SetReplyPathProvided(EFalse);
       
  1018 	
       
  1019 	TMsvEntry entry;
       
  1020 	BasicReplyForwardEntry(entry);
       
  1021 
       
  1022 	CMsvOperation* operation = CreateNewEntryL(entry, aDestination, *smsheader, *body, aCompletionStatus);
       
  1023 
       
  1024 	CleanupStack::PopAndDestroy(2, body);
       
  1025 	return operation;
       
  1026 	}
       
  1027 
       
  1028 /** 
       
  1029 Creates a SMS forwarded message from the current message context.
       
  1030 
       
  1031 The SMS in the current context must be of type SMS-DELIVER, a mobile terminated 
       
  1032 message, or SMS-SUBMIT, a mobile originated message. 
       
  1033 
       
  1034 The current context must be set to a message entry with type KUidMsvMessageEntryValue.
       
  1035 If the current context is not set, or is set to an entry not of type
       
  1036 KUidMsvMessageEntryValuethen a panic will occur.
       
  1037 
       
  1038 The new SMS message will have type SMS-SUBMIT, a mobile originated message. The 
       
  1039 recipient is left blank. The contents that are copied to the new message include
       
  1040 the message body, iBioType and description. Also, any EMS components are also
       
  1041 copied.
       
  1042 
       
  1043 @param	aDestination
       
  1044 The message entry (folder) under which to create the new message.
       
  1045 
       
  1046 @param	aPartList
       
  1047 Ignored.
       
  1048 
       
  1049 @param	aCompletionStatus
       
  1050 The request status to be completed when the operation has finished.
       
  1051 
       
  1052 @return
       
  1053 An operation object. If the forward email is successful created, the operation
       
  1054 will complete with KErrNone. The operation's progress information is a 
       
  1055 TPckg<TMsvId>, containing the TMsvId of the new SMS message. If the forward 
       
  1056 message fails to be created, the operation completes with the relevant error code.
       
  1057 
       
  1058 @leave	KErrNotSupported
       
  1059 The current context has a PDU type that is neither SMS-SUBMIT nor SMS-DELIVER.
       
  1060 
       
  1061 @panic	SMCM	1
       
  1062 The current context has not been set (debug only).
       
  1063 
       
  1064 @panic	SMCM	2
       
  1065 The current context was not of type KUidMsvMessageEntry (debug only).
       
  1066 */
       
  1067 CMsvOperation* CSmsClientMtm::ForwardL(TMsvId aDestination,TMsvPartList /*aPartList*/, TRequestStatus& aCompletionStatus)
       
  1068 	{
       
  1069 	LoadMessageL();
       
  1070 
       
  1071 	__ASSERT_DEBUG(iMsvEntry, Panic(ESmscEntryNotSet));
       
  1072 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvMessageEntry, Panic(ESmscWrongContextType));
       
  1073 
       
  1074 	// Only forwarding of Submitted or Delivered Messages is supported - ie only
       
  1075 	// SMS messages that either been sent or received. 
       
  1076 	CSmsPDU::TSmsPDUType smsType = iSmsHeader->Type();
       
  1077 	if (smsType!=CSmsPDU::ESmsSubmit && smsType!=CSmsPDU::ESmsDeliver)
       
  1078 		User::Leave(KErrNotSupported);
       
  1079 
       
  1080 	CRichText* body = CRichText::NewL(iParaFormatLayer, iCharFormatLayer,CEditableText::EFlatStorage,KSmcmRichTextConstant);
       
  1081 	CleanupStack::PushL(body);
       
  1082 	body->AppendTakingSolePictureOwnershipL(Body());
       
  1083 
       
  1084 	CSmsHeader* smsheader=CSmsHeader::NewL(CSmsPDU::ESmsSubmit,Body());
       
  1085 	CleanupStack::PushL(smsheader);
       
  1086 
       
  1087 	smsheader->SetReplyPathProvided(EFalse);
       
  1088 
       
  1089 	// Copy any EMS elements
       
  1090 	iSmsHeader->Message().CopyEmsElementsL(smsheader->Message());
       
  1091 	
       
  1092 	if( iSmsHeader->EmailFields().Length() > 0 )
       
  1093 		{
       
  1094 		// The context message is an email message - set the email fields for
       
  1095 		// the new message.
       
  1096 		smsheader->SetForwardEmailFieldsL(iSmsHeader->EmailFields(), *iEmailForwardSubjectFormat);
       
  1097 		}
       
  1098 	
       
  1099 	// Set the contents of the new TMsvEntry
       
  1100 	const TMsvEntry& originalEntry = Entry().Entry();
       
  1101 	TMsvEntry entry;
       
  1102 	BasicReplyForwardEntry(entry);
       
  1103 	entry.iBioType = originalEntry.iBioType; // added since 6.1
       
  1104 	entry.iDescription.Set(originalEntry.iDescription); // added since 6.1		
       
  1105 
       
  1106 	CMsvOperation* operation = CreateNewEntryL(entry, aDestination,*smsheader,*body,aCompletionStatus);
       
  1107 
       
  1108 	CleanupStack::PopAndDestroy(2, body);
       
  1109 	return operation;
       
  1110 	}
       
  1111 
       
  1112 /**
       
  1113 Adds an addressee to the current context.
       
  1114 
       
  1115 The current context must be an SMS messge of type SMS-SUBMIT, indicating a 
       
  1116 mobile originated message. The address is added to the recipient list for the 
       
  1117 message.
       
  1118 
       
  1119 For SMS an address is a telephone number. There is no validation done on the 
       
  1120 input argument aRealAddress to ensure that it is a valid telephone number.
       
  1121 
       
  1122 The TSmsUtilities::GetDetails API can be used prior to this API to find the if
       
  1123 a unique alias exists in the contacts database for this particular telephone 
       
  1124 number.
       
  1125 
       
  1126 The current context must be set to a message entry with type KUidMsvMessageEntryValue.
       
  1127 If the current context is set to an entry not of type KUidMsvMessageEntryValuethen
       
  1128 a panic will occur.
       
  1129 
       
  1130 The SMS MTM maintains an addressee list that matches the recipient list in the 
       
  1131 SMS message header object. If the two list cannot be maintained together then
       
  1132 this function will leave and both lists are unchanged.
       
  1133 
       
  1134 @param	aRealAddress
       
  1135 A string representing the address to be added to the recipient list for the
       
  1136 current context.
       
  1137 
       
  1138 @leave	KErrNotSupported
       
  1139 The current contxt PDU type is not SMS-SUBMIT.
       
  1140 
       
  1141 @panic	SMCM	2
       
  1142 The current context was not of type KUidMsvMessageEntry (debug only).
       
  1143 
       
  1144 @panic	SMCM	6
       
  1145 The addressee list and recipient list do not match (debug only).
       
  1146 */
       
  1147 void CSmsClientMtm::AddAddresseeL(const TDesC& aRealAddress)
       
  1148 	{
       
  1149 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvMessageEntry, Panic(ESmscWrongContextType));
       
  1150 	if (iSmsHeader->Type()!=CSmsPDU::ESmsSubmit)
       
  1151 		User::Leave(KErrNotSupported);
       
  1152 	__ASSERT_DEBUG(iAddresseeList->Count()==iSmsHeader->Recipients().Count(),Panic(ESmscRecpAddresseeMiscount));
       
  1153 	TPtr ptr(NULL,0);
       
  1154 	DoAddAddresseeL(aRealAddress,ptr);
       
  1155 	TRAPD(ret,AddRecipientL(aRealAddress,ptr));
       
  1156 	if (ret!=KErrNone)
       
  1157 		{
       
  1158 		iAddresseeList->Delete(iAddresseeList->Count()-1);
       
  1159 		User::Leave(ret);
       
  1160 		}
       
  1161 	}
       
  1162 
       
  1163 /** 
       
  1164 Adds an addressee with an alias to the current context.
       
  1165 
       
  1166 The SMS message in the current context must be of type SMS-SUBMIT, indicating a
       
  1167 mobile originated message. The address is added to the recipient list for the 
       
  1168 message.
       
  1169 
       
  1170 For SMS an address is a telephone number. There is no validation done on the 
       
  1171 input argument aRealAddress to ensure that it is a valid telephone number.
       
  1172 
       
  1173 The TSmsUtilities::GetDetails API can be used prior to this API to find the if
       
  1174 a unique alias exists in the contacts database for this particular telephone 
       
  1175 number.
       
  1176 
       
  1177 The current context must be set to a message entry with type KUidMsvMessageEntryValue.
       
  1178 If the current context is set to an entry not of type KUidMsvMessageEntryValuethen
       
  1179 a panic will occur.
       
  1180 
       
  1181 The SMS MTM maintains an addressee list that matches the recipient list in the 
       
  1182 SMS message header object. If the two list cannot be maintained together then
       
  1183 this function will leave and both lists are unchanged.
       
  1184 
       
  1185 @param	aRealAddress
       
  1186 A string representing the address to be added to the recipient list for the 
       
  1187 current message.
       
  1188 
       
  1189 @param	aAlias
       
  1190 The alias information for the address.
       
  1191 
       
  1192 @leave	KErrNotSupported
       
  1193 The current contxt PDU type is not SMS-SUBMIT.
       
  1194 
       
  1195 @panic	SMCM	2
       
  1196 The current context was not of type KUidMsvMessageEntry (debug only).
       
  1197 
       
  1198 @panic	SMCM	6
       
  1199 The addressee list and recipient list do not match (debug only).
       
  1200 */
       
  1201 void CSmsClientMtm::AddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias)
       
  1202 	{
       
  1203 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvMessageEntry, Panic(ESmscWrongContextType));
       
  1204 	if (iSmsHeader->Type()!=CSmsPDU::ESmsSubmit)
       
  1205 		User::Leave(KErrNotSupported);
       
  1206 	__ASSERT_DEBUG(iAddresseeList->Count()==iSmsHeader->Recipients().Count(),Panic(ESmscRecpAddresseeMiscount));
       
  1207 	DoAddAddresseeL(aRealAddress,aAlias);
       
  1208 	TRAPD(ret,AddRecipientL(aRealAddress,aAlias));
       
  1209 	if (ret!=KErrNone)
       
  1210 		{
       
  1211 		iAddresseeList->Delete(iAddresseeList->Count()-1);
       
  1212 		User::Leave(ret);
       
  1213 		}
       
  1214 	}
       
  1215 
       
  1216 /** 
       
  1217 Removes a recipient from the current address list.
       
  1218 
       
  1219 The recipient to be removed is specified by its index in the list of recipients.
       
  1220 This function can only be used when the current context is a mobile-originated
       
  1221 message (is a SMS-SUBMIT type message).
       
  1222 
       
  1223 The index must be valid or a panic will occur. A valid index is not negative and
       
  1224 does not exceed the upper bounds of the list.
       
  1225 
       
  1226 The current context must be set to a message entry with type KUidMsvMessageEntryValue.
       
  1227 If the current context is set to an entry not of type KUidMsvMessageEntryValuethen
       
  1228 a panic will occur.
       
  1229 
       
  1230 The SMS MTM maintains an addressee list that matches the recipient list in the 
       
  1231 SMS message header object. The address is removed from both lists.
       
  1232 
       
  1233 @param aIndex
       
  1234 The index of recipient to be removed.
       
  1235 
       
  1236 @panic	SMCM	0
       
  1237 The current contxt PDU type is not SMS-SUBMIT (debug only).
       
  1238 
       
  1239 @panic	SMCM	2
       
  1240 The current context was not a mesasge type context (debug only).
       
  1241 
       
  1242 @panic	SMCM	5
       
  1243 The specified index exceeds the recipient list range (debug only).
       
  1244 
       
  1245 @panic	SMCM	6
       
  1246 The addressee list and recipient list do not match (debug only).
       
  1247 */
       
  1248 void CSmsClientMtm::RemoveAddressee(TInt aIndex)
       
  1249 	{
       
  1250 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvMessageEntry, Panic(ESmscWrongContextType));
       
  1251 	__ASSERT_DEBUG(iSmsHeader->Type() == CSmsPDU::ESmsSubmit, Panic(ESmutPanicUnsupportedMsgType));
       
  1252 	__ASSERT_DEBUG((aIndex>=0) && (aIndex<iAddresseeList->Count()),Panic(ESmscAddresseeIndexOutOfRange));
       
  1253 	__ASSERT_DEBUG(iAddresseeList->Count()==iSmsHeader->Recipients().Count(),Panic(ESmscRecpAddresseeMiscount));
       
  1254 	delete iSmsHeader->Recipients()[aIndex];
       
  1255 	iSmsHeader->Recipients().Delete(aIndex);
       
  1256 	iAddresseeList->Delete(aIndex);
       
  1257 	}
       
  1258 
       
  1259 /**
       
  1260 Queries if the MTM supports the capability specified by the supplied UID.
       
  1261 
       
  1262 @param	aCapability
       
  1263 The UID of capability to be queried.
       
  1264 
       
  1265 @param	aResponse
       
  1266 An output argument for the response value. The format of the response varies
       
  1267 according to the capability. 
       
  1268 
       
  1269 @return
       
  1270 A value of KErrNone if the specified capability is recognised and a response
       
  1271 is returned. KErrNotSupported indicates that the capability is not recognised.
       
  1272 
       
  1273 @see	mtmuids.h
       
  1274 */
       
  1275 TInt CSmsClientMtm::QueryCapability(TUid aCapability, TInt& aResponse)
       
  1276 	{
       
  1277 	TInt error=KErrNone;
       
  1278 	aResponse=ETrue;
       
  1279 	switch (aCapability.iUid)
       
  1280 		{
       
  1281 		case KUidMtmQueryMaxBodySizeValue:
       
  1282 			{
       
  1283 			aResponse=KSmcmMaxTotalMsgSize;
       
  1284 			break;
       
  1285 			}
       
  1286 		case KUidMtmQueryMaxTotalMsgSizeValue:
       
  1287 			{
       
  1288 			aResponse = KSmcmMaxMessageNumber*KSmcmMaxCharsInMessageConcatenated7Bit;
       
  1289 			break;
       
  1290 			}
       
  1291 		case KUidMtmQuerySupportedBodyValue:
       
  1292 			{
       
  1293 			aResponse = KMtm7BitBody + KMtm8BitBody + KMtm16BitBody;
       
  1294 			break;
       
  1295 			}
       
  1296 		case KUidMtmQueryCanSendMsgValue:
       
  1297 		case KUidMtmQueryCanReceiveMsgValue:
       
  1298 		case KUidMtmQuerySupportsBioMsgValue:
       
  1299 		case KUidMtmQuerySupportsSchedulingValue:
       
  1300 		case KUidMtmQuerySendAsMessageSendSupportValue:
       
  1301 			break;
       
  1302 		case KUidMtmQueryMaxRecipientCountValue:
       
  1303 			{
       
  1304 			aResponse=KErrNotFound;	// not limited
       
  1305 			break;
       
  1306 			}
       
  1307 		case KUidMsvMtmQueryEditorUidValue:
       
  1308 			{
       
  1309 			aResponse=KUidMsgSmsEditorAppVal;
       
  1310 			break;
       
  1311 			}
       
  1312 		case KUidMtmQuerySupportAttachmentsValue:
       
  1313 		case KUidMtmQueryOffLineAllowedValue:
       
  1314 		case KUidMtmQuerySupportSubjectValue:
       
  1315 		case KUidMtmQuerySendAsRequiresRenderedImageValue:
       
  1316 		case KUidMtmQuerySendAsRenderingUidValue:
       
  1317 		case KUidMtmQuerySupportsFolderValue:
       
  1318 		case KUidMtmQuerySupportsRecipientTypeValue:
       
  1319 		default:
       
  1320 			error=KErrNotSupported;
       
  1321 		}
       
  1322 	return error;
       
  1323 	}
       
  1324 
       
  1325 /**
       
  1326 Unused for SMS.
       
  1327 
       
  1328 This function should not be used as it will cause a panic.
       
  1329 
       
  1330 @param aFunctionId
       
  1331 Unused.
       
  1332 
       
  1333 @param aSelection
       
  1334 Unused.
       
  1335 
       
  1336 @param aParameter
       
  1337 Unused. 
       
  1338 
       
  1339 @panic	SMCM	3
       
  1340 This command is not supported in SMS and should not be used.
       
  1341 
       
  1342 @internalComponent
       
  1343 */
       
  1344 void CSmsClientMtm::InvokeSyncFunctionL(TInt /*aFunctionId*/,const CMsvEntrySelection& /*aSelection*/, TDes8& /*aParameter*/)
       
  1345 	{
       
  1346 	Panic(ESmscPanicUnexpectedCommand);
       
  1347 	}
       
  1348 
       
  1349 /**
       
  1350 Invokes asynchronous SMS-specific operations.
       
  1351 
       
  1352 The specified operation is performed by the SMS server MTM.
       
  1353 
       
  1354 If the requested command is not supported then a panic will occur. The list of
       
  1355 supported commands is given by TSmsMtmCommand.
       
  1356 
       
  1357 The current context must be set. If the current context is not set then a panic
       
  1358 will occur.
       
  1359 
       
  1360 @param	aFunctionId
       
  1361 The ID of the operation to perform. The specific operations are defined by the
       
  1362 TSmsMtmCommand enumeration.
       
  1363 
       
  1364 @param	aSelection
       
  1365 A selection of messages, the use of which is specific to the selected operation.
       
  1366 
       
  1367 @param	aParameter
       
  1368 A packaged object, the use of which is specific to the selected operation.
       
  1369 
       
  1370 @param	aCompletionStatus
       
  1371 The request status to be notified when the operation completes. 
       
  1372 
       
  1373 @return
       
  1374 An object encapsulating the requested operation if the specified operation was
       
  1375 successfully started. If the operation failed to be started an completing 
       
  1376 operation is returned with its status set to the relevant error code.
       
  1377 
       
  1378 @see	TSmsMtmCommand 
       
  1379 
       
  1380 @panic	SMCM	1
       
  1381 The message entry has not been set (debug only).
       
  1382 
       
  1383 @panic	SMCM	3
       
  1384 The specified operation is not supported in SMS.
       
  1385 */
       
  1386 CMsvOperation* CSmsClientMtm::InvokeAsyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter, TRequestStatus& aCompletionStatus)
       
  1387 	{
       
  1388 	__ASSERT_DEBUG(iMsvEntry,Panic(ESmscEntryNotSet));
       
  1389 	switch (aFunctionId)
       
  1390 		{
       
  1391 		case KMTMStandardFunctionsSendMessage:
       
  1392 			// perform a regular send with standardised progress information for SendAs2
       
  1393 			return CSmsSendMessageOperation::NewL(Session(), aSelection, aParameter, aCompletionStatus);
       
  1394 		case ESmsMtmCommandScheduleCopy:
       
  1395 		case ESmsMtmCommandScheduleMove:
       
  1396 		case ESmsMtmCommandDeleteSchedule:
       
  1397 		case ESmsMtmCommandCheckSchedule:
       
  1398 		case ESmsMtmCommandSendScheduledCopy:
       
  1399 		case ESmsMtmCommandSendScheduledMove:
       
  1400 		case ESmsMtmCommandEnumeratePhoneStores:
       
  1401 		case ESmsMtmCommandDeleteFromPhoneStore:
       
  1402 		case ESmsMtmCommandCopyFromPhoneStore:
       
  1403 		case ESmsMtmCommandMoveFromPhoneStore:
       
  1404 		case ESmsMtmCommandCopyToPhoneStore:
       
  1405 		case ESmsMtmCommandMoveToPhoneStore:
       
  1406 			break;
       
  1407 		default:
       
  1408 			Panic(ESmscPanicUnexpectedCommand);
       
  1409 		}
       
  1410 	return Session().TransferCommandL(aSelection,aFunctionId,(TDesC8&)aParameter, aCompletionStatus);
       
  1411 	}
       
  1412 
       
  1413 
       
  1414 /**
       
  1415 Informs the MTM that the context's BIO field is being changed.
       
  1416 
       
  1417 The change is as a result of a call to CSendAs::SetBioTypeL(). This function is
       
  1418 used by CSendAs::CreateMessageL to create a new outgoing SMS message
       
  1419 
       
  1420 @param	aBioTypeUid
       
  1421 The new value for the BIO field.
       
  1422 
       
  1423 @panic	SMCM	10
       
  1424 The BIO field contains the wrong value (debug only).
       
  1425 */
       
  1426 EXPORT_C void CSmsClientMtm::BioTypeChangedL(TUid aBioTypeUid)
       
  1427 	{
       
  1428 	// Looks up the default send bearer and sets the
       
  1429 	// character encoding of the Submit() accordingly.
       
  1430 	RestoreServiceAndSettingsL();
       
  1431 
       
  1432 	CBIODatabase* bdb = CBIODatabase::NewLC(Session().FileSession());
       
  1433 	TBioMsgId bioMsgId;
       
  1434 	bdb->GetDefaultSendBearerL(aBioTypeUid, bioMsgId);
       
  1435 
       
  1436 	CSmsSettings* settings = CSmsSettings::NewL();
       
  1437 	CleanupStack::PushL(settings);
       
  1438 
       
  1439 	settings->CopyL(*iServiceSettings);
       
  1440 
       
  1441 	iSmsHeader->SetBioMsgIdType(bioMsgId.iType);
       
  1442 
       
  1443 	TSmsDataCodingScheme::TSmsAlphabet alpha = TSmsDataCodingScheme::ESmsAlphabet8Bit;
       
  1444 
       
  1445 	// Set the SMS Data Encoding Scheme
       
  1446 	switch (bioMsgId.iType)
       
  1447 		{
       
  1448 		case EBioMsgIdNbs:
       
  1449 			{
       
  1450 			switch (bioMsgId.iCharacterSet.iUid)
       
  1451 				{
       
  1452 //				case KCharacterSetIdentifierIso88591:
       
  1453 				case KCharacterSetIdentifierCodePage1252:
       
  1454 					{
       
  1455 					alpha = TSmsDataCodingScheme::ESmsAlphabet8Bit;
       
  1456 					break;
       
  1457 					}
       
  1458 				case KCharacterSetIdentifierSms7Bit:
       
  1459 					{
       
  1460 					alpha = TSmsDataCodingScheme::ESmsAlphabet7Bit;
       
  1461 					break;
       
  1462 					}
       
  1463 				default:
       
  1464 					{
       
  1465 					alpha = TSmsDataCodingScheme::ESmsAlphabetUCS2;
       
  1466 					break;
       
  1467 					}
       
  1468 				}
       
  1469 			break;
       
  1470 			}
       
  1471 		case EBioMsgIdWap:
       
  1472 		case EBioMsgIdWapSecure:
       
  1473 		default:
       
  1474 			{
       
  1475 			//ESmsAlphabet8Bit;
       
  1476 			break;
       
  1477 			}
       
  1478 		};
       
  1479 
       
  1480 	settings->SetCharacterSet(alpha);
       
  1481 	iSmsHeader->SetSmsSettingsL(*settings);
       
  1482 
       
  1483 	// service centre was not being set 
       
  1484 	TInt defaultSC = iServiceSettings->DefaultServiceCenter();
       
  1485 	if(defaultSC > -1)
       
  1486 		{
       
  1487 		iSmsHeader->SetServiceCenterAddressL( iServiceSettings->GetServiceCenter(defaultSC).Address() );	
       
  1488 		}
       
  1489 
       
  1490 	__ASSERT_DEBUG(iSmsHeader->BioMsgIdType() == bioMsgId.iType, Panic(ESmscBioMsgIdTypeError));
       
  1491 
       
  1492 	CleanupStack::PopAndDestroy(2, bdb);
       
  1493 	}
       
  1494 
       
  1495 /** 
       
  1496 Creates a new outgoing SMS message entry as a child of the current context.
       
  1497 
       
  1498 Used by CSendAs::CreateMessageL to create an outgoing SMS message.
       
  1499 
       
  1500 @param	aServiceId
       
  1501 The ID of the service to own the entry (not used).
       
  1502 
       
  1503 @see	CSendAs::CreateMessageL
       
  1504 */
       
  1505 EXPORT_C void CSmsClientMtm::CreateMessageL(TMsvId /*aServiceId*/)
       
  1506 	{
       
  1507 	RestoreServiceAndSettingsL();
       
  1508 
       
  1509  	// Fix for DEF000924: Need to be able to send/cancel an sms while another 
       
  1510 	// is being sent create an invisible blank entry.
       
  1511  	TMsvEntry entry;
       
  1512  	entry.iType = KUidMsvMessageEntry;
       
  1513  	entry.iRelatedId = iServiceId;
       
  1514  	entry.iServiceId = KMsvLocalServiceIndexEntryId;
       
  1515  	entry.iMtm = Type();
       
  1516  	entry.SetVisible(EFalse);
       
  1517  	entry.SetInPreparation(ETrue);
       
  1518  	
       
  1519  	// Fix for DEF061945: Need to initialise the iDate member of the new entry
       
  1520  	entry.iDate.UniversalTime();
       
  1521  	// store entry in folder
       
  1522  	iMsvEntry->CreateL(entry);
       
  1523  	SwitchCurrentEntryL(entry.Id());
       
  1524  	// End of fix
       
  1525 
       
  1526 	delete iSmsHeader;
       
  1527 	iSmsHeader=NULL;
       
  1528 	iSmsHeader=CSmsHeader::NewL(CSmsPDU::ESmsSubmit,Body());
       
  1529 	iSmsHeader->SetSmsSettingsL(*iServiceSettings);
       
  1530 
       
  1531 	// service centre was not being set 
       
  1532 	TInt defaultSC = iServiceSettings->DefaultServiceCenter();
       
  1533 	if(defaultSC > -1)
       
  1534 		{
       
  1535 		if (iServiceSettings->ServiceCenterCount() > defaultSC )
       
  1536 			{
       
  1537 			iSmsHeader->SetServiceCenterAddressL( iServiceSettings->GetServiceCenter(defaultSC).Address() );	
       
  1538 			}
       
  1539 		}
       
  1540  	}
       
  1541 
       
  1542 /**
       
  1543 Resets the current SMS message.
       
  1544 
       
  1545 The recipient list in the SMS message header object is emptied. As the SMS MTM 
       
  1546 maintains an addressee list that matches the recipient list in the SMS message 
       
  1547 header object, this addressee list is also emptied.
       
  1548 */
       
  1549 void CSmsClientMtm::ContextEntrySwitched()
       
  1550 	{
       
  1551 	ResetHeader();
       
  1552 	}
       
  1553 
       
  1554 /** 
       
  1555 This method is from CBaseMtm, The default implementation is available in CBaseMtm. 
       
  1556 The implementation of this function assumes that the new service for setting the 
       
  1557 charset encoding value for a SMS message is supported.
       
  1558 TAny* is equivalent to void*.
       
  1559 @param	a0				 			The collective parameters of TAny*
       
  1560 @param	a1				 			The collective parameters of TAny*,Charset encoding value is actually extracted from a1.
       
  1561 @param aExtensionId 	 			Uid of the extension interface.
       
  1562 @return KErrNone					If charset is changed successfully in SMS settings for a message.
       
  1563 @return KErrExtensionNotSupported 	If the message is other than SMS.					
       
  1564 @return Other 			 			Standard system-wide error codes.
       
  1565 */
       
  1566 
       
  1567 EXPORT_C TInt CSmsClientMtm::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
       
  1568 	{
       
  1569 	TInt ret=KErrNone;
       
  1570 	switch(aExtensionId)
       
  1571 		{
       
  1572 		case KUIDCharacterSet:
       
  1573 			{
       
  1574 	    	TSmsDataCodingScheme::TSmsAlphabet tsmsAlphabet = (TSmsDataCodingScheme::TSmsAlphabet)(TUint)*(TUint*)a1;
       
  1575 	    	TRAP(ret,SetMessageCharacterSetL(tsmsAlphabet));
       
  1576 			return ret;
       
  1577 			}
       
  1578 		default:
       
  1579 			{
       
  1580 			// Chain to base class
       
  1581 			return CBaseMtm::Extension_(aExtensionId, a0, a1);
       
  1582 			}
       
  1583 		}
       
  1584 	}
       
  1585 
       
  1586 /**
       
  1587 This is the actual functionality for setting the character encoding value other than 7-bit ASCII.
       
  1588 TSmsDataCodingScheme is used for collecting the encoding value for setting the charset for a message.
       
  1589 This setting is for per-message basis.
       
  1590 @param aTsmsAlphabet 	 			Enum of Sms datacoding scheme for the character encoding value.
       
  1591 @return void.
       
  1592 */
       
  1593    
       
  1594 void CSmsClientMtm::SetMessageCharacterSetL(TSmsDataCodingScheme::TSmsAlphabet aTsmsAlphabet)
       
  1595 	{
       
  1596 	CSmsSettings* settings = CSmsSettings::NewL();
       
  1597 	CleanupStack::PushL(settings);
       
  1598 
       
  1599 	settings->CopyL(*iServiceSettings);
       
  1600 	settings->SetCharacterSet(aTsmsAlphabet);
       
  1601 	iSmsHeader->SetSmsSettingsL(*settings);
       
  1602 	CleanupStack::PopAndDestroy(settings);
       
  1603 	}
       
  1604 
       
  1605 /** 
       
  1606 Commits cached changes to the current message context to the message store.
       
  1607 
       
  1608 The current context must be set to a message entry with type KUidMsvServiceEntryValue,
       
  1609 KUidMsvFolderEntryValue or KUidMsvMessageEntryValue. If the current context is
       
  1610 not set, or is set to an entry with a type that is not supported by this function
       
  1611 then a panic will occur.
       
  1612 
       
  1613 Both the SMS service ID and SMS service settings must have been set or a panic
       
  1614 will occur. The CSmsClientMtm::RestoreServiceAndSettingsL API can restore both
       
  1615 of these items.
       
  1616 
       
  1617 @panic  SMCM    1
       
  1618 The current context has not been set (debug only).
       
  1619 
       
  1620 @panic  SMCM    4
       
  1621 The type of the current context is not supported.
       
  1622 
       
  1623 @panic  SMCM    11
       
  1624 The SMS Service settings have not been set (debug only).
       
  1625 
       
  1626 @panic  SMCM    12
       
  1627 The ID for SMS Service has not been set (debug only).
       
  1628 
       
  1629 @see    CSmsClientMtm::RestoreServiceAndSettingsL
       
  1630 */
       
  1631 EXPORT_C void CSmsClientMtm::SaveMessageL(CMsvStore& aEditStore, TMsvEntry& aEntry)
       
  1632     {
       
  1633     switch (aEntry.iType.iUid)
       
  1634         {
       
  1635         case KUidMsvServiceEntryValue:
       
  1636             {
       
  1637             __ASSERT_DEBUG(iServiceSettings, Panic(ESmscSettingsNotSet));
       
  1638             __ASSERT_DEBUG(iServiceId, Panic(ESmscServiceIdNotSet));
       
  1639             CSmsAccount* account = CSmsAccount::NewLC();
       
  1640             account->SaveSettingsL(*iServiceSettings);
       
  1641             CleanupStack::PopAndDestroy(account);    
       
  1642             break;
       
  1643             }
       
  1644         case KUidMsvFolderEntryValue:
       
  1645             {
       
  1646             break;
       
  1647             }
       
  1648         case KUidMsvMessageEntryValue:
       
  1649             {
       
  1650             if ((0 >= aEntry.iDetails.Length()) && (iSmsHeader->Recipients().Count() > 0))
       
  1651                 {
       
  1652                 CSmsNumber* recipient = iSmsHeader->Recipients().At(0);
       
  1653                 if(recipient->Name().Length() > 0)
       
  1654                     aEntry.iDetails.Set(recipient->Name());
       
  1655                 else
       
  1656                     aEntry.iDetails.Set(recipient->Address());
       
  1657                 }
       
  1658             if(Body().DocumentLength()>0 && 0 >= aEntry.iDescription.Length())
       
  1659                 {
       
  1660                 aEntry.iDescription.Set(Body().Read(0,iServiceSettings->DescriptionLength()));   
       
  1661                 }
       
  1662             aEntry.SetVisible(ETrue);
       
  1663             aEntry.SetInPreparation(EFalse);           
       
  1664             aEntry.SetMultipleRecipients(iSmsHeader->Recipients().Count() > 1);
       
  1665             iSmsHeader->StoreL(aEditStore);
       
  1666             StoreBodyL(aEditStore);
       
  1667             break;
       
  1668             }
       
  1669         default:
       
  1670             Panic(ESmscUnrecognizedEntryType);
       
  1671         }
       
  1672     
       
  1673     const TInt size = aEditStore.SizeL();        
       
  1674     if (aEntry.iSize != size)
       
  1675         {
       
  1676         aEntry.iSize = size;             
       
  1677         }
       
  1678     }