contactextensions/predefinedcontacts/src/PdcXMLContentHandler.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2007 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:    Implementation of the Xml:MContentHandler interface
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include <MVPbkContactStore.h>              // MVPbkContactStore
       
    20 #include <MVPbkStoreContact.h>              // MVPbkStoreContact
       
    21 #include <MVPbkFieldType.h>                 // MVPbkFieldType
       
    22 #include <MVPbkContactStoreProperties.h>    // MVPbkContactStoreProperties
       
    23 #include <MVPbkContactFieldData.h>          // MVPbkContactFieldData
       
    24 #include <MVPbkContactFieldTextData.h>      // MVPbkContactFieldTextData
       
    25 #include <MVPbkContactFieldBinaryData.h>    // MVPbkContactFieldBinaryData
       
    26 #include <MVPbkContactFieldDateTimeData.h>  // MVPbkContactFieldDateTimeData
       
    27 #include <cntdef.h>                         // TContactItemId
       
    28 #include <CVPbkContactLinkArray.h>          // CVPbkContactLinkArray
       
    29 #include <CPbkFieldInfo.h> 
       
    30 #include <utf.h>
       
    31 #include <cntfield.h> // CPbkContactItem
       
    32 #include <CVPbkContactIdConverter.h>
       
    33 #include <VPbkContactStoreUris.h>
       
    34 #include <MVPbkContactStoreList.h>
       
    35 #include <CPbkContactEngine.h>      // Phonebook Engine
       
    36 #include <CPbkContactItem.h>        // Phonebook Contact
       
    37 #include <e32cmn.h> 
       
    38 
       
    39 // User includes
       
    40 #include "pdcstringconstants.h"     // PdcStringTable
       
    41 #include "PdcXMLContentHandler.h"   // CPdcXmlContentHandler
       
    42 #include "pdcxmlmapping.h"          // KFieldResIdLookupTable
       
    43 #include "PhCltTypes.h"             //For TPhCltTelephoneNumber
       
    44 
       
    45 // Constants
       
    46 /**
       
    47  * The default size of the content buffer
       
    48  */
       
    49 const TInt KDefaultContentBufferSize = 128;
       
    50 
       
    51 /**
       
    52  * Index of the start contact tag in pcstringtable
       
    53  */
       
    54 const TInt KContactStartTagIndex = 0;
       
    55 const TInt KSpeeddialNoTagIndex = PdcStringTable::ESpeeddialNo;
       
    56 const TInt KSpeeddialAssignedTagIndex = PdcStringTable::ESpeeddialNoAssign;
       
    57 const TInt KSpeeddialIndexInit = 0;
       
    58 
       
    59 // To distinguish the invalid assigned field index -1, 
       
    60 // set the initial value of speeddialAssign tag with -2
       
    61 const TInt KSpeeddialAssignedFieldIndexInit = -2;
       
    62 
       
    63 using namespace Xml;
       
    64 
       
    65 // The speeddial supported assigning fields
       
    66 const TInt CPdcXmlContentHandler::iSpeeddailSupportedAssignedFieldsIndexSet[phoneNumberCount] = 
       
    67     {
       
    68     PdcStringTable::EGeneral, 
       
    69     PdcStringTable::EMobile,
       
    70     PdcStringTable::EVideoNo,
       
    71     PdcStringTable::EFax,
       
    72     -1    
       
    73     };
       
    74 
       
    75 // ======== MEMBER FUNCTIONS ========
       
    76 
       
    77 // ---------------------------------------------------------------------------
       
    78 // CPdcXmlContentHandler::NewL
       
    79 // Symbian 1st phase constructor
       
    80 // @return Self pointer to CPdcXmlContentHandler
       
    81 // @param    aContactStore   contacts store
       
    82 // @param    aLinkArray  links to  contacts added.
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 CPdcXmlContentHandler* CPdcXmlContentHandler::NewL( 
       
    86          MVPbkContactStore& aContactStore, CVPbkContactLinkArray& aLinkArray )
       
    87     {
       
    88     CPdcXmlContentHandler* self = new( ELeave )
       
    89         CPdcXmlContentHandler(aContactStore, aLinkArray );
       
    90     CleanupStack::PushL( self );
       
    91     self->ConstructL();
       
    92     CleanupStack::Pop( self );
       
    93     return self;
       
    94     }
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // CPdcXmlContentHandler::~CPdcXmlContentHandler
       
    98 // Destructor.
       
    99 // ---------------------------------------------------------------------------
       
   100 //
       
   101 CPdcXmlContentHandler::~CPdcXmlContentHandler()
       
   102     {
       
   103     iContentBuffer.Close();
       
   104     
       
   105     delete iContactItem;
       
   106 
       
   107     delete iWait;
       
   108     }
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 // CPdcXmlContentHandler::CPdcXmlContentHandler
       
   112 // C++ constructor
       
   113 // @param    aContactStore   contacts store
       
   114 // @param    aLinkArray  links to  contacts added.
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 CPdcXmlContentHandler::CPdcXmlContentHandler( MVPbkContactStore& aContactStore ,
       
   118                                           CVPbkContactLinkArray& aLinkArray)
       
   119     : iContactStore( aContactStore ), 
       
   120       iLinkArray( aLinkArray ),
       
   121       iSpeeddialIndex(KSpeeddialIndexInit),
       
   122       iSpeeddialAssignedFieldIndex(KSpeeddialAssignedFieldIndexInit)
       
   123     {
       
   124 
       
   125     }
       
   126     
       
   127 // ---------------------------------------------------------------------------
       
   128 // CPdcXmlContentHandler::ConstructL
       
   129 // Second-phase constructor
       
   130 // ---------------------------------------------------------------------------
       
   131 //
       
   132 void CPdcXmlContentHandler::ConstructL()
       
   133     {
       
   134     iContentBuffer.CreateL( KDefaultContentBufferSize );
       
   135     iWait = new ( ELeave ) CActiveSchedulerWait();
       
   136     }
       
   137     
       
   138 // ---------------------------------------------------------------------------
       
   139 // CPdcXmlContentHandler::SetStringPoolL
       
   140 // Sets the string pool
       
   141 // @param aStringPool   parser's stringPool
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 void CPdcXmlContentHandler::SetStringPoolL( RStringPool& aStringPool)
       
   145     {
       
   146     iStringPool = &aStringPool;
       
   147     iStringPool->OpenL( PdcStringTable::Table );
       
   148     }    
       
   149     
       
   150 // ---------------------------------------------------------------------------
       
   151 // CPdcXmlContentHandler::GetTagIndexL
       
   152 // 
       
   153 // @param aElement  
       
   154 // ---------------------------------------------------------------------------
       
   155 //  
       
   156 TInt CPdcXmlContentHandler::GetTagIndexL( const RTagInfo& aElement ) const
       
   157     { 
       
   158     
       
   159     const TDesC8& localName = aElement.LocalName ().DesC();
       
   160     
       
   161 	RStringF tagName = iStringPool->OpenFStringL ( localName );
       
   162 
       
   163 	TInt index = tagName.Index ( PdcStringTable::Table );
       
   164     tagName.Close();
       
   165     
       
   166 	return index;
       
   167     }
       
   168     
       
   169 // ---------------------------------------------------------------------------
       
   170 // CPdcXmlContentHandler::AddTextFieldL
       
   171 // Adds a field to a contact, using the resource id of the field
       
   172 // @param aFieldResId  resource id of field
       
   173 // @param aBuffer   buffer containing data to be added
       
   174 // ---------------------------------------------------------------------------
       
   175 //   
       
   176 void CPdcXmlContentHandler::AddFieldL( TInt aFieldResId,
       
   177                                                        const TDesC8& aBuffer )
       
   178     {
       
   179     ASSERT( iContactItem );
       
   180     
       
   181     const MVPbkFieldTypeList& list = 
       
   182                 iContactItem->ParentStore().StoreProperties().SupportedFields();
       
   183     
       
   184     const MVPbkFieldType* fieldType = list.Find( aFieldResId );
       
   185     
       
   186     MVPbkStoreContactField* contactField = 
       
   187                                     iContactItem->CreateFieldLC( *fieldType );
       
   188                                     
       
   189     MVPbkContactFieldData& fieldData = contactField->FieldData();
       
   190                
       
   191     TVPbkFieldStorageType storageType = fieldData.DataType();
       
   192     switch ( storageType )
       
   193         {
       
   194         case EVPbkFieldStorageTypeText:
       
   195             {
       
   196             SetTextFieldL( fieldData, aBuffer );
       
   197             }
       
   198             break;
       
   199         case EVPbkFieldStorageTypeBinary:
       
   200             {
       
   201             SetBinaryFieldL( fieldData, aBuffer );        
       
   202             }
       
   203             break;
       
   204         case EVPbkFieldStorageTypeDateTime:
       
   205             {
       
   206             SetDateFieldL( fieldData, aBuffer );
       
   207             }
       
   208             break;
       
   209         case EVPbkFieldStorageTypeNull:
       
   210         default:
       
   211             {
       
   212             // Un-handled storage type
       
   213             ASSERT( 0 );
       
   214             }   
       
   215         }               
       
   216                          
       
   217     iContactItem->AddFieldL( contactField );
       
   218     CleanupStack::Pop( contactField );
       
   219     }
       
   220  
       
   221  // ---------------------------------------------------------------------------
       
   222 // CPdcXmlContentHandler::AddTextFieldL
       
   223 // Adds a field to a contact, using the resource id of the field
       
   224 // @param aFieldResId  resource id of field
       
   225 // @param aBuffer   buffer containing data to be added
       
   226 // ---------------------------------------------------------------------------
       
   227 //      
       
   228 void CPdcXmlContentHandler::SetTextFieldL( MVPbkContactFieldData& aFieldData,
       
   229                                                         const TDesC8& aBuffer )
       
   230     {
       
   231     MVPbkContactFieldTextData& textData = 
       
   232     MVPbkContactFieldTextData::Cast( aFieldData );
       
   233     
       
   234     // Expand the text from TDes8 to TDes16
       
   235     RBuf16 expandedBuffer;
       
   236     expandedBuffer.CreateL( aBuffer.Length() );
       
   237     expandedBuffer.CleanupClosePushL();
       
   238     
       
   239     //convert the UTF-8 to Unicode for displaying the Chinese correctly.
       
   240     //expandedBuffer.Copy( aBuffer );
       
   241     CnvUtfConverter::ConvertToUnicodeFromUtf8( expandedBuffer, aBuffer );
       
   242 
       
   243     // If there is a maximum length to the field, reduce
       
   244     // the text size if needed.
       
   245     TInt maxLength = textData.MaxLength();
       
   246     if ( maxLength != KVPbkUnlimitedFieldLength 
       
   247                                 && expandedBuffer.Length() > maxLength )
       
   248         {
       
   249         expandedBuffer.SetLength( maxLength );
       
   250         }
       
   251     
       
   252     textData.SetTextL( expandedBuffer );
       
   253     CleanupStack::PopAndDestroy(); // expanded buffer
       
   254     }
       
   255 
       
   256  // ---------------------------------------------------------------------------
       
   257 // CPdcXmlContentHandler::AddTextFieldL
       
   258 // Adds a field to a contact, using the resource id of the field
       
   259 // @param aFieldResId  resource id of field
       
   260 // @param aBuffer   buffer containing data to be added
       
   261 // ---------------------------------------------------------------------------
       
   262 //      
       
   263 void CPdcXmlContentHandler::SetBinaryFieldL( MVPbkContactFieldData& aFieldData,
       
   264                                                         const TDesC8& aBuffer )
       
   265     {
       
   266     MVPbkContactFieldBinaryData& binaryData = 
       
   267                 MVPbkContactFieldBinaryData::Cast( aFieldData );
       
   268                 
       
   269     // If there is a maximum length to the field, reduce
       
   270     // the  size if needed.
       
   271     TPtrC8 data( aBuffer );
       
   272     TInt maxLength = binaryData.MaxLength();
       
   273     if ( maxLength != KVPbkUnlimitedFieldLength && data.Length() > maxLength )
       
   274         {
       
   275         data.Set( data.Left( maxLength ) );
       
   276         }
       
   277     
       
   278     binaryData.SetBinaryDataL( data );            
       
   279     }
       
   280             
       
   281  // ---------------------------------------------------------------------------
       
   282 // CPdcXmlContentHandler::AddTextFieldL
       
   283 // Adds a field to a contact, using the resource id of the field
       
   284 // @param aFieldResId  resource id of field
       
   285 // @param aBuffer   buffer containing data to be added
       
   286 // ---------------------------------------------------------------------------
       
   287 //      
       
   288 void CPdcXmlContentHandler::SetDateFieldL( MVPbkContactFieldData& aFieldData,
       
   289                                                         const TDesC8& aBuffer )
       
   290     {
       
   291     MVPbkContactFieldDateTimeData& timeData =
       
   292             MVPbkContactFieldDateTimeData::Cast( aFieldData );
       
   293     
       
   294     // Expand the text from TDes8 to TDes16
       
   295     RBuf16 expandedBuffer;
       
   296     expandedBuffer.CreateL( aBuffer.Length() );
       
   297     expandedBuffer.CleanupClosePushL();
       
   298     expandedBuffer.Copy( aBuffer );
       
   299     
       
   300     // Set the time
       
   301     TTime time;
       
   302     User::Leave( time.Set( expandedBuffer ) );
       
   303     timeData.SetDateTime( time );
       
   304     
       
   305     CleanupStack::PopAndDestroy(); // expanded buffer
       
   306     }  
       
   307 
       
   308 // ---------------------------------------------------------------------------
       
   309 // CPdcXmlContentHandler::OnStartDocumentL
       
   310 // IGNORED
       
   311 // This method is a callback to indicate the start of the document.
       
   312 // @param				aDocParam Specifies the various parameters of the 
       
   313 //                      document.
       
   314 // @param				aDocParam.iCharacterSetName The character encoding of
       
   315 //                      the document.
       
   316 // @param				aErrorCode is the error code. This is always EErrNone 
       
   317 //                      for the libxml2 XML parser. 
       
   318 //					    
       
   319 // ---------------------------------------------------------------------------
       
   320 // 
       
   321 void CPdcXmlContentHandler::OnStartDocumentL(
       
   322                 const RDocumentParameters& /*aDocParam*/, TInt /*aErrorCode*/)
       
   323     {
       
   324     }
       
   325 
       
   326 // ---------------------------------------------------------------------------
       
   327 // CPdcXmlContentHandler::OnEndDocumentL
       
   328 // IGNORED
       
   329 // This method is a callback to indicate the end of the document.
       
   330 // @param				aErrorCode is the error code.This is always EErrNone 
       
   331 //                      for the libxml2 XML parser. 
       
   332 // ---------------------------------------------------------------------------
       
   333 //   
       
   334 void CPdcXmlContentHandler::OnEndDocumentL(TInt /*aErrorCode*/)
       
   335     {
       
   336     }
       
   337 
       
   338 // ---------------------------------------------------------------------------
       
   339 // CPdcXmlContentHandler::OnStartElementL
       
   340 // This method is a callback to indicate an element has been parsed. If the 
       
   341 // element is the start of a new contact, it creates a new contact item. 
       
   342 // @param				aElement is a handle to the element's details.
       
   343 // @param				aAttributes contains the attributes for the element.
       
   344 // @param				aErrorCode is the error code.This is always EErrNone
       
   345 //                      for thelibxml2 XML parser. 
       
   346 // ---------------------------------------------------------------------------
       
   347 //   
       
   348 void CPdcXmlContentHandler::OnStartElementL(const RTagInfo& aElement, 
       
   349                    const RAttributeArray& /*aAttributes*/, TInt /*aErrorCode*/)
       
   350     {
       
   351     TInt tagIndex = GetTagIndexL( aElement );
       
   352     
       
   353     // Only need to check for start of a new contact tag, as the processing of 
       
   354     // the data will take place in OnEndElementL(). 
       
   355     if ( tagIndex == KContactStartTagIndex )
       
   356         {
       
   357         // Found new contact tag, check not already processing a contact
       
   358         if ( iContactItem )
       
   359             {
       
   360             // If there is already a contact, the XML file
       
   361             // is corrupt, so leave
       
   362             User::Leave( KErrCorrupt );
       
   363             }
       
   364       
       
   365         // Create a new contact item
       
   366         iContactItem = iContactStore.CreateNewContactLC();
       
   367         CleanupStack::Pop(); // iContactItem
       
   368         }
       
   369     else
       
   370         {
       
   371         // Check it is a recongised tag
       
   372         iKnownTag = ETrue;
       
   373 		if(tagIndex == -1)
       
   374           {
       
   375           iKnownTag = FALSE;
       
   376           }
       
   377         }  
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------------------------
       
   381 // CPdcXmlContentHandler::OnEndElementL
       
   382 // This method is a callback to indicate the end of the element has been 
       
   383 // reached. If it the end of field tag, it adds the data for that field to
       
   384 // the current contact item. If it the contact end tag, the contact is 
       
   385 // committed. 
       
   386 // @param				aElement is a handle to the element's details.
       
   387 // @param				aErrorCode is the error code.This is always EErrNone 
       
   388 //                      for the libxml2 XML parser. 
       
   389 // ---------------------------------------------------------------------------
       
   390 //   
       
   391 void CPdcXmlContentHandler::OnEndElementL(const RTagInfo& aElement,
       
   392                                                           TInt /*aErrorCode*/)
       
   393     {
       
   394    	// Get the index of the tag
       
   395     TInt tagIndex = GetTagIndexL( aElement );    
       
   396 
       
   397     // If the end tag marks the end of the contact, add the contact to the 
       
   398     // contact store.
       
   399     switch( tagIndex )
       
   400     	{
       
   401     	case KContactStartTagIndex:
       
   402     		{
       
   403             MVPbkStoreContactFieldCollection const& fieldCollection =
       
   404                 iContactItem->Fields();
       
   405     		TInt fieldCount = fieldCollection.FieldCount();
       
   406     		if( fieldCount > 0 )
       
   407     		    {
       
   408     		    //add contact to cntdb and assign speeddial number
       
   409         	    TRAPD( err, AddContactL() );
       
   410         	    if ( err != KErrNone )
       
   411         	    	{
       
   412         	    	LOGTEXT2( _L("AddContactL() ERR:%d"), err ); 
       
   413         	    	User::LeaveIfError( err );
       
   414         	    	}
       
   415         	    LOGTEXT(_L("add contact successfully")); 
       
   416     		    }
       
   417     		//reset flags
       
   418             iSpeeddialIndex = KSpeeddialIndexInit;
       
   419             iSpeeddialAssignedFieldIndex = KSpeeddialAssignedFieldIndexInit; 
       
   420     		// Tidy up the current contact item.
       
   421     		delete iContactItem;
       
   422             iContactItem = NULL;
       
   423         	break;	
       
   424     		}
       
   425     	case KSpeeddialNoTagIndex:
       
   426     		{
       
   427     		if( iContentBuffer.Length() > 0 )
       
   428     		    {
       
   429 	            //convert the speeddial value
       
   430                 TLex8 lex(iContentBuffer);
       
   431                 TInt value;
       
   432         	    if( KErrNone == lex.Val(value) )
       
   433             	    {
       
   434                     if( value >= KCntMinSpeedDialIndex  &&
       
   435                             value <= KCntMaxSpeedDialIndex ) 
       
   436                 	    {
       
   437                 	    iSpeeddialIndex = value; 
       
   438                 	    }
       
   439             	    }
       
   440     		    }
       
   441             break;
       
   442     		}
       
   443     	case KSpeeddialAssignedTagIndex:
       
   444     		{
       
   445     		//get the speed dial assigned field index
       
   446         	if( iContentBuffer.Length() > 0 )
       
   447             	{
       
   448     			const TDesC8& localName = iContentBuffer;
       
   449 		
       
   450 				RStringF tagName = iStringPool->OpenFStringL ( localName );
       
   451                 iSpeeddialAssignedFieldIndex =
       
   452                     tagName.Index ( PdcStringTable::Table);
       
   453     			tagName.Close();
       
   454             	}
       
   455             break;  
       
   456     		}
       
   457     	default:
       
   458     		{
       
   459     		if ( tagIndex != KErrNotFound )
       
   460             	{
       
   461             	// Lookup the tag in the field resource id versus xml tag mapping
       
   462             	TInt fieldResId = KFieldResIdLookupTable[tagIndex];
       
   463             	if ( fieldResId != KErrNotFound && iContentBuffer.Length() > 0 )
       
   464                 	{
       
   465 					AddFieldL( fieldResId, iContentBuffer );
       
   466                 	}
       
   467             	}
       
   468     		}
       
   469     	}
       
   470 
       
   471     iKnownTag = EFalse;
       
   472     iContentBuffer.SetLength( 0 ); // reset the buffer
       
   473     }
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // CPdcXmlContentHandler::OnContentL
       
   477 // This method stores the content of an element. When an OnEndElementL is 
       
   478 // received this means there is no more data to be saved.
       
   479 // @param		    aBytes is the raw content data for the element. 
       
   480 //					The client is responsible for converting the data to the 
       
   481 //					required character set if necessary.
       
   482 //					In some instances the content may be binary and must not 
       
   483 //                  be converted.
       
   484 // @param			aErrorCode is the error code.This is always EErrNone for
       
   485 //                  the libxml2 XML parser. 
       
   486 // ---------------------------------------------------------------------------
       
   487 //   
       
   488 void CPdcXmlContentHandler::OnContentL( const TDesC8& aBytes,
       
   489         TInt /*aErrorCode*/ )
       
   490     {
       
   491     // If the tag is known store the data for later use    
       
   492     if ( iKnownTag )
       
   493         {
       
   494         // Check that there is enough room in the buffer
       
   495         TInt maxLength = iContentBuffer.MaxLength();
       
   496         TInt newLength = iContentBuffer.Length() + aBytes.Length();
       
   497         if ( newLength > maxLength )
       
   498             {
       
   499             iContentBuffer.ReAllocL( newLength );
       
   500             }
       
   501         
       
   502         // Append the data to the content buffer    
       
   503         iContentBuffer.Append( aBytes );
       
   504 
       
   505         }   
       
   506     }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // CPdcXmlContentHandler::
       
   510 // IGNORED
       
   511 // This method is a notification of the beginning of the scope of a 
       
   512 // prefix-URI Namespace mapping.This method is always called before the 
       
   513 // corresponding OnStartElementL method.
       
   514 // @param				aPrefix is the Namespace prefix being declared.
       
   515 // @param				aUri is the Namespace URI the prefix is mapped to.
       
   516 // @param				aErrorCode is the error code.This is always EErrNone
       
   517 //                      for the libxml2 XML parser. 
       
   518 // ---------------------------------------------------------------------------
       
   519 //   
       
   520 void CPdcXmlContentHandler::OnStartPrefixMappingL(const RString& /*aPrefix*/,
       
   521                                 const RString& /*aUri*/, TInt /*aErrorCode*/)
       
   522     {
       
   523     }
       
   524 
       
   525 // ---------------------------------------------------------------------------
       
   526 // CPdcXmlContentHandler::
       
   527 // IGNORED
       
   528 // This method is a notification of the end of the scope of a prefix-URI mapping.
       
   529 // This method is called after the corresponding DoEndElementL method.
       
   530 // @param				aPrefix is the Namespace prefix that was mapped.
       
   531 // @param				aErrorCode is the error code.This is always EErrNone 
       
   532 //                      for the libxml2 XML parser. 
       
   533 // ---------------------------------------------------------------------------
       
   534 // 
       
   535 void CPdcXmlContentHandler::OnEndPrefixMappingL( const RString& /*aPrefix*/,
       
   536         TInt /*aErrorCode*/)
       
   537     { 
       
   538     }
       
   539 
       
   540 // ---------------------------------------------------------------------------
       
   541 // CPdcXmlContentHandler::
       
   542 // IGNORED
       
   543 // This method is a notification of ignorable whitespace in element content.
       
   544 // @param		aBytes are the ignored bytes from the document being parsed.
       
   545 // @param		aErrorCode is the error code.This is always EErrNone for the
       
   546 //              libxml2 XML parser. 
       
   547 // ---------------------------------------------------------------------------
       
   548 //   
       
   549 void CPdcXmlContentHandler::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, 
       
   550                                                           TInt /*aErrorCode*/)
       
   551     {  
       
   552     }
       
   553 
       
   554 // ---------------------------------------------------------------------------
       
   555 // CPdcXmlContentHandler::
       
   556 // IGNORED
       
   557 // This method is a notification of a skipped entity. If the parser encounters
       
   558 // an external entity it does not need to expand it - it can return the entity 
       
   559 // as aName for the client to deal with.
       
   560 // @param				aName is the name of the skipped entity.
       
   561 // @param				aErrorCode is the error code.This is always EErrNone
       
   562 //                      for the libxml2 XML parser. 
       
   563 // ---------------------------------------------------------------------------
       
   564 //   
       
   565 void CPdcXmlContentHandler::OnSkippedEntityL( const RString& /*aName*/,
       
   566                                                          TInt /*aErrorCode*/)
       
   567     {
       
   568     }
       
   569 
       
   570 // ---------------------------------------------------------------------------
       
   571 // CPdcXmlContentHandler::
       
   572 // IGNORED
       
   573 // This method is a receive notification of a processing instruction.
       
   574 // @param				aTarget is the processing instruction target.
       
   575 // @param				aData is the processing instruction data. If empty 
       
   576 //                      none was supplied.
       
   577 // @param				aErrorCode is the error code.This is always EErrNone
       
   578 //                      for the libxml2 XML parser. 
       
   579 // ---------------------------------------------------------------------------
       
   580 //   
       
   581 void CPdcXmlContentHandler::OnProcessingInstructionL(
       
   582         const TDesC8& /*aTarget*/,
       
   583         const TDesC8& /*aData*/,
       
   584         TInt /*aErrorCode*/ )
       
   585     {
       
   586     }
       
   587 
       
   588 // ---------------------------------------------------------------------------
       
   589 // CPdcXmlContentHandler::
       
   590 // IGNORED
       
   591 // This method indicates an error has occurred.
       
   592 // @param				aError is the error code
       
   593 // ---------------------------------------------------------------------------
       
   594 //   
       
   595 void CPdcXmlContentHandler::OnError( TInt aErrorCode )
       
   596     {
       
   597     LOGTEXT2(_L("CPdcXmlContentHandler::OnError = %d"), aErrorCode);
       
   598     }
       
   599 
       
   600 // ---------------------------------------------------------------------------
       
   601 // CPdcXmlContentHandler::
       
   602 // IGNORED
       
   603 // This method obtains the interface matching the specified uid.
       
   604 // @return				0 if no interface matching the uid is found.
       
   605 // 					Otherwise, the this pointer cast to that interface.
       
   606 // @param				aUid the uid identifying the required interface.
       
   607 // ---------------------------------------------------------------------------
       
   608 //   
       
   609 TAny* CPdcXmlContentHandler::GetExtendedInterface(const TInt32 /*aUid*/)
       
   610     {
       
   611     return NULL;
       
   612     }
       
   613     
       
   614 // ---------------------------------------------------------------------------
       
   615 // CPdcXmlContentHandler::
       
   616 // Called when a contact operation has succesfully completed.
       
   617 //
       
   618 // @param aResult   The result of the operation. The client takes
       
   619 //                  the ownership of the iStoreContact immediately
       
   620 //                  if set in aResult.
       
   621 // ---------------------------------------------------------------------------
       
   622 //   
       
   623 void CPdcXmlContentHandler::ContactOperationCompleted( 
       
   624         TContactOpResult /*aResult*/ )
       
   625     {
       
   626     // Store the fact that the operation has completed successfully
       
   627     iContactObserverError = KErrNone;
       
   628 
       
   629     // Stop the wait operation, program execution returns to OnEndElementL()
       
   630     iWait->AsyncStop();
       
   631     }
       
   632 
       
   633 // ---------------------------------------------------------------------------
       
   634 // CPdcXmlContentHandler::
       
   635 // Called when a contact operation has failed.
       
   636 //
       
   637 // @param aOpCode           The operation that failed.
       
   638 // @param aErrorCode        System error code of the failure.
       
   639 //							KErrAccessDenied when EContactCommit 
       
   640 //							means that contact hasn't been locked.
       
   641 // @param aErrorNotified    ETrue if the implementation has already
       
   642 //                          notified user about the error, 
       
   643 //                          EFalse otherwise.
       
   644 // ---------------------------------------------------------------------------
       
   645 //   
       
   646 void CPdcXmlContentHandler::ContactOperationFailed
       
   647     (TContactOp /*aOpCode*/, TInt aErrorCode, TBool /*aErrorNotified*/)
       
   648         {
       
   649 
       
   650         // Store the error code
       
   651         iContactObserverError = aErrorCode;
       
   652 
       
   653         // Stop the wait operation, program execution returns to OnEndElementL()
       
   654         iWait->AsyncStop();
       
   655         }
       
   656         
       
   657 // ---------------------------------------------------------------------------
       
   658 // CPdcXmlContentHandler::
       
   659 // IGNORED
       
   660 // This method assign speeddial number from predefinedcontacts .
       
   661 // ---------------------------------------------------------------------------
       
   662 // 
       
   663 void CPdcXmlContentHandler::AddContactL()
       
   664 	{
       
   665 	
       
   666     LOGTEXT( _L("CPdcXmlContentHandler::AddContactL") );
       
   667     
       
   668 	// A CActiveSchedulerWait is used to make the asyncronous commiting
       
   669     // of the contact item syncronous by waiting for the callback 
       
   670     // to either ContactOperationCompleted or ContactOperationFailed
       
   671 	iContactItem->CommitL( *this );
       
   672 	iWait->Start();
       
   673 
       
   674 	// The contact has been added syncronously, so create the link to 
       
   675     // the contact and add to the link array.
       
   676 	
       
   677 	MVPbkContactLink* link = iContactItem->CreateLinkLC();	    
       
   678 	iLinkArray.AppendL( link );
       
   679 	CleanupStack::Pop( );
       
   680 	
       
   681 	    
       
   682 	//if the speeddial is valid
       
   683     if( iSpeeddialIndex > 0 )
       
   684     	{    	
       
   685     	LOGTEXT(_L("Start assign speeddial."));    	
       
   686     		        
       
   687         TVPbkContactStoreUriPtr uri(
       
   688                 VPbkContactStoreUris::DefaultCntDbUri() );
       
   689         MVPbkContactStore* defaultStore =
       
   690                 iContactManager->ContactStoresL().Find( uri );
       
   691     	User::LeaveIfNull(defaultStore);
       
   692     	
       
   693     	LOGTEXT(_L("CVPbkContactIdConverter::NewL"));    
       
   694     	CVPbkContactIdConverter* idConverter;
       
   695     	idConverter = CVPbkContactIdConverter::NewL( *defaultStore ); 
       
   696     	CleanupStack::PushL(idConverter);
       
   697     	
       
   698 	    LOGTEXT(_L("idConverter->LinkToIdentifier"));
       
   699     	TContactItemId contactIndex= idConverter->LinkToIdentifier( *link ); 
       
   700     	CleanupStack::PopAndDestroy(idConverter);
       
   701         
       
   702     	LOGTEXT(_L("CPbkContactEngine::NewL"));
       
   703     	CPbkContactEngine* pbkEngine;
       
   704     	pbkEngine = CPbkContactEngine::NewL(); 
       
   705 		CleanupStack::PushL( pbkEngine );
       
   706 		
       
   707 		LOGTEXT( _L("pbkEngine->OpenContactL") );
       
   708         CPbkContactItem* item = pbkEngine->OpenContactL( contactIndex );	
       
   709     	CleanupStack::PushL( item );
       
   710 
       
   711     	TInt fieldIndex = GetSpeeddialAssignedFieldIndexL( item );
       
   712     	   	    	    
       
   713         if( 0 <= fieldIndex )
       
   714             {
       
   715             LOGTEXT( _L("SetFieldAsSpeedDialL") );
       
   716 		    pbkEngine->SetFieldAsSpeedDialL( *item, fieldIndex, iSpeeddialIndex );
       
   717             }  
       
   718 
       
   719         CleanupStack::PopAndDestroy( item );
       
   720 		LOGTEXT(_L("pbkEngine->CloseContactL"));	
       
   721         pbkEngine->CloseContactL( contactIndex );
       
   722         
       
   723         LOGTEXT( _L("PopAndDestroy(pbkEngine)") );
       
   724         CleanupStack::PopAndDestroy( pbkEngine );
       
   725     	}
       
   726  	}
       
   727 
       
   728 // ---------------------------------------------------------------------------
       
   729 // CPdcXmlContentHandler::GetSpeeddialAssignedFieldIndexL
       
   730 // This method get the speeddial assigned field index
       
   731 // @param aItem 
       
   732 // ---------------------------------------------------------------------------
       
   733 // 
       
   734 TInt CPdcXmlContentHandler::GetSpeeddialAssignedFieldIndexL(
       
   735         CPbkContactItem* aItem )
       
   736 	{
       
   737 	LOGTEXT(_L("GetSpeeddialAssignedFieldIndexL"));      
       
   738     TInt fieldIndex = -1;
       
   739 
       
   740     // If the user don't assign the speed dial in the xml, 
       
   741     // use the default assigned method
       
   742     if( KSpeeddialAssignedFieldIndexInit == iSpeeddialAssignedFieldIndex )
       
   743         {
       
   744         iSpeeddialAssignedFieldIndex = GetDefaultSpeeddialAssignedFieldIndexL();
       
   745         }
       
   746    
       
   747     // if the user assign the speeddial to an xml field, then check the validity 
       
   748     // and get the contact item field index.
       
   749     if(0 <= iSpeeddialAssignedFieldIndex)    
       
   750 	    {
       
   751 	    TBool fieldIsValid = EFalse;
       
   752 	    
       
   753         fieldIsValid = CheckValidityOfSpeeddialAssignedFieldL(
       
   754                 iSpeeddialAssignedFieldIndex );
       
   755 	    
       
   756         // If the assigned field is a valid field,
       
   757         // mapping the cntmodel field and get the index.
       
   758 	    if( fieldIsValid )
       
   759 	        {
       
   760 			fieldIndex = ContactItemFieldIndexL( aItem );
       
   761             }     
       
   762         }               		
       
   763 
       
   764    	return fieldIndex;
       
   765 	}	
       
   766 
       
   767 //
       
   768 // ---------------------------------------------------------------------------
       
   769 // CPdcXmlContentHandler::GetDefaultSpeeddialAssignedFieldIndexL
       
   770 // This method get the default speeddial assigned field index.
       
   771 // @param 
       
   772 // ---------------------------------------------------------------------------
       
   773 // 	
       
   774 TInt CPdcXmlContentHandler::GetDefaultSpeeddialAssignedFieldIndexL()
       
   775 	{
       
   776 	LOGTEXT(_L("GetDefaultSpeeddialAssignedFieldIndexL"));  
       
   777 	TInt index = 0;
       
   778 	TInt defaultFieldIndex = -1;
       
   779 
       
   780 	defaultFieldIndex = iSpeeddailSupportedAssignedFieldsIndexSet[index];
       
   781    
       
   782     while(0 < defaultFieldIndex)
       
   783         {   
       
   784         MVPbkStoreContactFieldCollection const& fieldCollection =
       
   785                 iContactItem->Fields();
       
   786         TInt fieldCount = fieldCollection.FieldCount();
       
   787         TInt searchIndex;
       
   788         
       
   789         for( searchIndex = 0; searchIndex < fieldCount; searchIndex++ )
       
   790             {
       
   791             MVPbkStoreContactField* storeContactField =
       
   792                     fieldCollection.FieldAtLC( searchIndex );
       
   793             const MVPbkFieldType* fieldType =
       
   794                     storeContactField->BestMatchingFieldType();
       
   795             TInt fieldResourceId = fieldType->FieldTypeResId();
       
   796             if( fieldResourceId == KFieldResIdLookupTable[defaultFieldIndex] )
       
   797             	{
       
   798                 MVPbkContactFieldData& fieldData =
       
   799                         storeContactField->FieldData();
       
   800                 
       
   801                 if(!fieldData.IsEmpty())
       
   802                     {
       
   803                     CleanupStack::PopAndDestroy(); //pop iStoreContactField
       
   804                     return defaultFieldIndex;   
       
   805                     }
       
   806             	}
       
   807             CleanupStack::PopAndDestroy(); //pop iStoreContactField
       
   808             }
       
   809 
       
   810         ++index;
       
   811         defaultFieldIndex = iSpeeddailSupportedAssignedFieldsIndexSet[index];    
       
   812         }
       
   813     
       
   814     return defaultFieldIndex;
       
   815 	}
       
   816 
       
   817 // ---------------------------------------------------------------------------
       
   818 // CPdcXmlContentHandler::CheckValidityOfSpeeddialAssignedFieldL
       
   819 // This method check the validity of assigned field by index
       
   820 // @param aFieldIndex 
       
   821 // ---------------------------------------------------------------------------
       
   822 // 
       
   823 TBool CPdcXmlContentHandler::CheckValidityOfSpeeddialAssignedFieldL( 
       
   824         TInt aFieldIndex )
       
   825 	{
       
   826 	LOGTEXT(_L("CheckValidityOfSpeeddialAssignedFieldL")); 
       
   827 	//check the speeddial assigned field is a valid field
       
   828 	TBool validity = EFalse;
       
   829 	TInt index = 0;
       
   830 	
       
   831 	TInt tempIndex = iSpeeddailSupportedAssignedFieldsIndexSet[index];
       
   832 	    	
       
   833 	while( tempIndex >= 0 )
       
   834 	    {	
       
   835 	    if( aFieldIndex == tempIndex )
       
   836 	    	{		
       
   837             MVPbkStoreContactFieldCollection const& fieldCollection =
       
   838                     iContactItem->Fields();
       
   839             TInt fieldCount = fieldCollection.FieldCount();
       
   840             TInt searchIndex;
       
   841             for( searchIndex = 0; searchIndex < fieldCount; searchIndex++ )
       
   842             	{
       
   843                 MVPbkStoreContactField* storeContactField =
       
   844                         fieldCollection.FieldAtLC( searchIndex );
       
   845                 const MVPbkFieldType* fieldType =
       
   846                         storeContactField->BestMatchingFieldType();
       
   847             	TInt fieldResourceId = fieldType->FieldTypeResId();
       
   848             	
       
   849             	if( fieldResourceId == KFieldResIdLookupTable[aFieldIndex] )
       
   850             		{
       
   851                     MVPbkContactFieldData& fieldData =
       
   852                             storeContactField->FieldData();
       
   853                     // If the phonenumber field doesn't have data,
       
   854                     // set the index invalid.
       
   855                     if( !fieldData.IsEmpty() )
       
   856             	        {
       
   857             	        validity = ETrue;
       
   858             	        }
       
   859             	    CleanupStack::PopAndDestroy(); //pop iStoreContactField
       
   860             	    break;
       
   861             		}
       
   862             	CleanupStack::PopAndDestroy(); //pop iStoreContactField
       
   863             	}
       
   864 	    	}
       
   865 	    if( validity )
       
   866 	    	{
       
   867 	    	break;
       
   868 	    	}
       
   869 	    ++index;
       
   870 	    tempIndex = iSpeeddailSupportedAssignedFieldsIndexSet[index];
       
   871 	    }
       
   872 	    
       
   873 	return validity;
       
   874 	}
       
   875 
       
   876 // ---------------------------------------------------------------------------
       
   877 // CPdcXmlContentHandler::ContactItemFieldIndexL
       
   878 // This method get the speeddial assigned field index
       
   879 // @param aItem 
       
   880 // ---------------------------------------------------------------------------
       
   881 // 
       
   882 TInt CPdcXmlContentHandler::ContactItemFieldIndexL(CPbkContactItem* aItem)
       
   883 	{
       
   884     LOGTEXT(_L("ContactItemFieldIndex"));
       
   885     
       
   886     TInt fieldIndex  = -1;
       
   887     TBuf<20> speeddialAssignedField;  
       
   888          
       
   889     MVPbkStoreContactFieldCollection const& fieldCollection =
       
   890             iContactItem->Fields();
       
   891     TInt count = fieldCollection.FieldCount();
       
   892     TInt searchIndex;
       
   893     
       
   894     for( searchIndex = 0; searchIndex < count; searchIndex++)
       
   895     	{
       
   896         MVPbkStoreContactField* storeContactField =
       
   897                 fieldCollection.FieldAtLC( searchIndex );
       
   898         const MVPbkFieldType* fieldType =
       
   899                 storeContactField->BestMatchingFieldType();
       
   900         TInt fieldResourceId = fieldType->FieldTypeResId();
       
   901         
       
   902         if( fieldResourceId ==
       
   903                 KFieldResIdLookupTable[iSpeeddialAssignedFieldIndex] )
       
   904     		{
       
   905     		speeddialAssignedField = storeContactField->FieldLabel();
       
   906     		CleanupStack::PopAndDestroy(); //pop iStoreContactField
       
   907     		break;
       
   908     		}
       
   909     	CleanupStack::PopAndDestroy(); //pop iStoreContactField
       
   910     	}
       
   911 
       
   912 	CPbkFieldArray& fields = aItem->CardFields();
       
   913     const TInt fieldCount = fields.Count();   
       
   914             
       
   915     for ( TInt i = 0; i < fieldCount; ++i )
       
   916         {
       
   917         CContactItemField& itemfield = fields[i].ItemField();
       
   918         TBuf<20> buf = itemfield.Label();
       
   919             		
       
   920 	    // find the user assigned field for speeddial
       
   921         if( 0 == speeddialAssignedField.Compare(buf) )
       
   922             {
       
   923             fieldIndex = i;
       
   924             break;
       
   925             }
       
   926         }
       
   927     return fieldIndex;
       
   928 	}
       
   929 	
       
   930 // ---------------------------------------------------------------------------
       
   931 // CPdcXmlContentHandler::
       
   932 // This method get the pointer of contactmanager from XML importer
       
   933 // @param aContactManager 
       
   934 // ---------------------------------------------------------------------------
       
   935 // 
       
   936 void CPdcXmlContentHandler::SetContactManager(
       
   937         CVPbkContactManager* aContactManager )
       
   938     {
       
   939 	iContactManager = aContactManager;
       
   940     }
       
   941 
       
   942