mobilemessaging/unieditor/application/src/UniEditorVCardOperation.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2006,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:   CUniEditorVCardOperationn, operation for adding VCard into the message
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========== INCLUDE FILES ================================
       
    21 
       
    22 #include <MsgMediaInfo.h>
       
    23 #include <contactmatcher.h>
       
    24 #include <msgtextutils.h>
       
    25 #include <MsgMediaResolver.h>
       
    26 #include <MPbk2ContactNameFormatter.h>
       
    27 
       
    28 #include "UniEditorLogging.h"
       
    29 #include "UniEditorVCardOperation.h"
       
    30 #include "UniEditorEnum.h"
       
    31 
       
    32 _LIT8( KVCardMiMeType, "text/X-vCard" );
       
    33 _LIT( KTempVCardFileName, "vCard.vcf" );
       
    34 _LIT( KTempVCardFileSuffix, ".vcf");
       
    35 
       
    36 _LIT(KInvalidFileNameChars, "?*<>/\"|\\:");
       
    37 _LIT(KReplaceChar, "_");
       
    38 
       
    39 // ---------------------------------------------------------
       
    40 // CUniEditorVCardOperation::NewL
       
    41 //
       
    42 // Factory method.
       
    43 // ---------------------------------------------------------
       
    44 //
       
    45 CUniEditorVCardOperation* CUniEditorVCardOperation::NewL(
       
    46         MUniEditorOperationObserver& aObserver,
       
    47         CUniEditorDocument& aDocument,
       
    48         RFs& aFs )
       
    49     {
       
    50     CUniEditorVCardOperation* self = new ( ELeave ) CUniEditorVCardOperation(
       
    51         aObserver, 
       
    52         aDocument, 
       
    53         aFs );
       
    54     CleanupStack::PushL( self );
       
    55     self->ConstructL();
       
    56     CleanupStack::Pop( self );
       
    57     return self;
       
    58     }
       
    59 
       
    60 // ---------------------------------------------------------
       
    61 // CUniEditorVCardOperation::CUniEditorVCardOperation
       
    62 //
       
    63 // Constructor.
       
    64 // ---------------------------------------------------------
       
    65 //
       
    66 CUniEditorVCardOperation::CUniEditorVCardOperation(
       
    67         MUniEditorOperationObserver& aObserver,
       
    68         CUniEditorDocument& aDocument,
       
    69         RFs& aFs ) :
       
    70     CUniEditorOperation( aObserver, aDocument, aFs, EUniEditorOperationVCard ), 
       
    71     iNewVCardAttaId( KMsvNullIndexEntryId ),
       
    72     iAddedVCardCount( 0 ),
       
    73     iCurrentContactIndex( -1 )
       
    74     {
       
    75     }
       
    76 
       
    77 // ---------------------------------------------------------
       
    78 // CUniEditorVCardOperation::CUniEditorVCardOperation
       
    79 //
       
    80 // Destructor. iContact, iContacts and iCheckNames must be deleted
       
    81 // in this order!
       
    82 // ---------------------------------------------------------
       
    83 //
       
    84 CUniEditorVCardOperation::~CUniEditorVCardOperation()
       
    85     {
       
    86     Cancel();
       
    87 
       
    88     delete iContact;
       
    89     delete iContacts;
       
    90     delete iCheckNames;
       
    91     delete iStoreContact;
       
    92     delete iVCardEng;
       
    93     delete iVCardExportOp;
       
    94     delete iEditStore;
       
    95     
       
    96     iVCardStream.Close();
       
    97     }
       
    98 
       
    99 // ---------------------------------------------------------
       
   100 // CUniEditorVCardOperation::ConstructL
       
   101 //
       
   102 // 2nd phase constructor.
       
   103 // ---------------------------------------------------------
       
   104 //
       
   105 void CUniEditorVCardOperation::ConstructL()
       
   106     {
       
   107     BaseConstructL();
       
   108 
       
   109     iCheckNames = CMsgCheckNames::NewL();
       
   110 
       
   111     iVCardEng = CVPbkVCardEng::NewL( iCheckNames->ContactMatcher().GetContactManager() );
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------
       
   115 // CUniEditorVCardOperation::Start
       
   116 //
       
   117 // ---------------------------------------------------------
       
   118 //
       
   119 void CUniEditorVCardOperation::Start()
       
   120     {
       
   121     iOperationState = EUniProcessVCardStart;
       
   122     CompleteSelf( KErrNone );    
       
   123     }
       
   124 
       
   125 // ---------------------------------------------------------
       
   126 // CUniEditorVCardOperation::GetContactsL
       
   127 //
       
   128 // ---------------------------------------------------------
       
   129 //
       
   130 void CUniEditorVCardOperation::GetContactsL()
       
   131     {
       
   132     ResetAll();
       
   133 
       
   134     // Create a new empty array
       
   135     iContacts = CVPbkContactLinkArray::NewL();
       
   136 
       
   137     iCheckNames->FetchRecipientsL( *iContacts, CMsgCheckNames::EMsgTypeAll );
       
   138     
       
   139     if ( iContacts->Count() > 0 )
       
   140         {
       
   141         iOperationState = EUniProcessVCardExportNext;
       
   142         CompleteSelf( KErrNone );
       
   143         }
       
   144     else
       
   145         {
       
   146         iOperationState = EUniProcessVCardComplete;
       
   147         CompleteSelf( KErrNone );
       
   148         }
       
   149     }
       
   150 
       
   151 // ---------------------------------------------------------
       
   152 // CUniEditorVCardOperation::ExportVCardAndAddAttachmentL
       
   153 //
       
   154 // ---------------------------------------------------------
       
   155 //
       
   156 void CUniEditorVCardOperation::ExportVCardAndAddAttachmentL()
       
   157     {
       
   158     Reset();
       
   159     
       
   160     // Initial value is -1, so we start to handle the contact in index 0.
       
   161     iCurrentContactIndex++;
       
   162     
       
   163     if ( iCurrentContactIndex < iContacts->Count() )
       
   164         {
       
   165         // Handle next contact.
       
   166         iContact = const_cast<MVPbkContactLink *>(
       
   167             &iContacts->At( iCurrentContactIndex ) )->CloneLC();
       
   168         CleanupStack::Pop();    // Cloned link.
       
   169 
       
   170         iOperationState = EUniProcessVCardCreatingEmptyVCardAttachment;
       
   171         CompleteSelf( KErrNone );
       
   172         }
       
   173     else
       
   174         {
       
   175         // No more contacts, so we can clean up and complete.
       
   176         // Clean up is done, in order to get iContact deleted, before
       
   177         // its contact manager is deleted. Bad design in virtual phonebook.
       
   178         iOperationState = EUniProcessVCardComplete;
       
   179         CompleteSelf( KErrNone );
       
   180         }
       
   181     }
       
   182 
       
   183 // ---------------------------------------------------------
       
   184 // CUniEditorVCardOperation::AddedVCardCount
       
   185 //
       
   186 // ---------------------------------------------------------
       
   187 //
       
   188 TInt CUniEditorVCardOperation::AddedVCardCount()
       
   189     {
       
   190     return iAddedVCardCount;
       
   191     }
       
   192 
       
   193 // ---------------------------------------------------------
       
   194 // CUniEditorVCardOperation::CreateEmptyVCardAttachmentL
       
   195 //
       
   196 // ---------------------------------------------------------
       
   197 //    
       
   198 void CUniEditorVCardOperation::CreateEmptyVCardAttachmentL()
       
   199     {
       
   200     iCheckNames->ContactMatcher().GetStoreContactL( *iContact, &iStoreContact );
       
   201     
       
   202     // If this store contact is a group, then we don't add it to object list.
       
   203     if ( !iStoreContact->Group() )
       
   204         {
       
   205         MVPbkStoreContactFieldCollection& fieldCollection = iStoreContact->Fields();
       
   206 
       
   207         HBufC* contactName = iCheckNames->ContactMatcher().ContactNameFormatterL().GetContactTitleL( fieldCollection, 0 );
       
   208 
       
   209         // Form a name for the attachment. If contactName is NULL, then 
       
   210         // attachment is name vCard.vcf. 
       
   211         if ( contactName )
       
   212             {
       
   213             // Reserve more space for filename to include .vcf
       
   214             contactName = contactName->ReAllocL( 
       
   215                 contactName->Length() + KTempVCardFileSuffix().Length() ); // ReAllocL deletes original
       
   216             CleanupStack::PushL( contactName );
       
   217             
       
   218             // Modify contact's name to be a file name.
       
   219             TPtr contactFilePtr = contactName->Des();
       
   220             contactFilePtr.Append( KTempVCardFileSuffix );
       
   221             }
       
   222         else
       
   223             {
       
   224             // Use hard coded filename vCard.vcf.
       
   225             contactName = KTempVCardFileName().AllocLC();
       
   226             }
       
   227 
       
   228         // Remove illegal characters from file name. Phonebook allows characters
       
   229         // to be inserted to contact's name, which are not allowed by Symbian file
       
   230         // system.
       
   231         TPtr contactNamePtr = contactName->Des();   // May contain illegal characters
       
   232         HBufC* validName = HBufC::NewLC( contactName->Length() );
       
   233         TPtr validNamePtr = validName->Des();   // Does not contain illegal characters
       
   234 
       
   235         // Loop throuh characters and replace illegal characters with underscore.
       
   236         for ( TInt i = 0; i < contactName->Length(); ++i )
       
   237             {
       
   238             TChar ch = contactNamePtr[i];
       
   239             if ( KInvalidFileNameChars().Locate( ch ) == KErrNotFound )
       
   240                 {
       
   241                 validNamePtr.Append( ch );
       
   242                 }
       
   243             else
       
   244                 {
       
   245                 validNamePtr.Append( KReplaceChar );
       
   246                 }
       
   247             }
       
   248         validNamePtr.TrimAll();
       
   249         
       
   250         // Create empty stored attachment to store.
       
   251         RFile newVCardFile;
       
   252         iEditStore = iDocument.Mtm().Entry().EditStoreL();
       
   253         MMsvAttachmentManagerSync& managerSync = iEditStore->AttachmentManagerExtensionsL();
       
   254         CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
   255         CleanupStack::PushL( attachment );
       
   256         managerSync.CreateAttachmentL( validNamePtr, newVCardFile, attachment );
       
   257         CleanupStack::Pop( attachment); // ownership transferred
       
   258         CleanupStack::PopAndDestroy( 2, contactName );  // validName, contactName
       
   259         
       
   260         // Store the id, it is used when attachment created above is saved to 
       
   261         // object list.
       
   262         iNewVCardAttaId = attachment->Id();
       
   263         iVCardStream.Attach( newVCardFile );
       
   264         
       
   265         // Call vCard engine to export a contact to a stored attachment. 
       
   266         // Engine will call VPbkSingleContactOperationComplete or
       
   267         // VPbkSingleContactOperationFailed
       
   268         iVCardExportOp = iVCardEng->ExportVCardL( iVCardStream,
       
   269                                                   *iContact,
       
   270                                                   *this);
       
   271         SetPending();
       
   272         }
       
   273     else
       
   274         {
       
   275         // Don't add group name as a vCard, results are not nice.
       
   276         iOperationState = EUniProcessVCardExportNext;
       
   277         CompleteSelf( KErrNone );
       
   278         }
       
   279     }
       
   280 
       
   281 // ---------------------------------------------------------
       
   282 // CUniEditorVCardOperation::DoCancelCleanup
       
   283 //
       
   284 // ---------------------------------------------------------
       
   285 //
       
   286 void CUniEditorVCardOperation::DoCancelCleanup()
       
   287     {
       
   288     Reset();
       
   289     }
       
   290 
       
   291 // ---------------------------------------------------------
       
   292 // CUniEditorVCardOperation::RunL
       
   293 //
       
   294 // ---------------------------------------------------------
       
   295 //
       
   296 void CUniEditorVCardOperation::RunL()
       
   297     {
       
   298     PrintOperationAndState();
       
   299     if ( iStatus.Int() != KErrNone )
       
   300         {
       
   301         SetError( iStatus.Int() );
       
   302         iOperationState = EUniProcessVCardError;
       
   303         }
       
   304         
       
   305     switch( iOperationState )
       
   306         {
       
   307         case EUniProcessVCardStart:
       
   308             {
       
   309             // Get contacts to export
       
   310             GetContactsL();
       
   311             break;
       
   312             }
       
   313         case EUniProcessVCardExportNext:
       
   314             {
       
   315             // Start handling of single contact.
       
   316             ExportVCardAndAddAttachmentL();
       
   317             break;
       
   318             }           
       
   319         case EUniProcessVCardCreatingEmptyVCardAttachment:
       
   320             {
       
   321             // Create an empty attachment to message store.
       
   322             CreateEmptyVCardAttachmentL();
       
   323             break;
       
   324             }    
       
   325         case EUniProcessVCardComplete:
       
   326             {
       
   327             // All contacts handled, tell appUi that we are complete.
       
   328             ReportEvent( EUniEditorOperationComplete );
       
   329             break;
       
   330             }
       
   331         case EUniProcessVCardCancel:
       
   332             {
       
   333             // Somebody cancelled us, tell appUi that we were cancelled.
       
   334             ReportEvent( EUniEditorOperationCancel );
       
   335             break;
       
   336             }
       
   337         case EUniProcessVCardError:
       
   338             {
       
   339             Reset();
       
   340             iObserver.EditorOperationEvent( EUniEditorOperationVCard,
       
   341                                             EUniEditorOperationError );
       
   342             break;
       
   343             }
       
   344         default:
       
   345             {
       
   346             // Huh, this can also be possible.
       
   347             iObserver.EditorOperationEvent( EUniEditorOperationVCard,
       
   348                                             EUniEditorOperationError );
       
   349             break;
       
   350             }
       
   351         }
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------
       
   355 // CUniEditorVCardOperation::VPbkSingleContactOperationComplete
       
   356 //
       
   357 // ---------------------------------------------------------
       
   358 //
       
   359 void CUniEditorVCardOperation::VPbkSingleContactOperationComplete( MVPbkContactOperationBase& aOperation, 
       
   360                                                                    MVPbkStoreContact* /*aContact*/ )
       
   361     {
       
   362     iLastError = KErrNone;
       
   363     
       
   364     if ( &aOperation == iVCardExportOp )
       
   365         {
       
   366         TDataType type( KVCardMiMeType );
       
   367 
       
   368         // Release and close stream.
       
   369         TRAP_IGNORE( iVCardStream.CommitL() );
       
   370         iVCardStream.Close();
       
   371 
       
   372         // Get attachment handle again, since iVCardStream.Attach() function 
       
   373         // call makes the original handle invalid.
       
   374         MMsvAttachmentManager* manager = NULL;
       
   375         TRAP_IGNORE( manager = &iEditStore->AttachmentManagerL() );
       
   376         
       
   377         RFile storedVCard;
       
   378         TRAPD( err, storedVCard = manager->GetAttachmentFileL( iNewVCardAttaId ) );
       
   379         
       
   380         if ( err == KErrNone )
       
   381             {
       
   382             // Add stored attachment to object list.        
       
   383             CMsgMediaInfo* media = NULL;
       
   384             
       
   385             TRAP_IGNORE( media = CMsgMediaInfo::NewL( storedVCard, 
       
   386                                                       type, 
       
   387                                                       EMsgMediaUnknown ) );
       
   388                     
       
   389             // Count the size of the message after current vCard is inserted.    
       
   390             TInt vCardSize = media->FileSize();
       
   391             TInt sizeAfterInsert = iDocument.MessageSize() + vCardSize;
       
   392             
       
   393             if ( sizeAfterInsert <= iDocument.MaxMessageSize() )
       
   394                 {
       
   395                 // Must be committed and deleted since only one client can access 
       
   396                 // entry in edit mode and AddStoredAttachmentL function want's to 
       
   397                 // edit it too.
       
   398                 TRAP_IGNORE( iEditStore->CommitL() );
       
   399                 
       
   400                 delete iEditStore;
       
   401                 iEditStore = NULL;
       
   402                 
       
   403                 TRAP_IGNORE( iDocument.DataModel()->AddStoredAttachmentL( iNewVCardAttaId, 
       
   404                                                                           media ) );
       
   405                 media = NULL;   // Not owned anymore
       
   406                 
       
   407                 // Increase success counter, used to show correct note
       
   408                 // when all contacts are handled.
       
   409                 iAddedVCardCount++;
       
   410                 
       
   411                 // Object is now saved to unieditor's object list.
       
   412                 }
       
   413             else
       
   414                 {
       
   415                 // Delete created media info
       
   416                 delete media;
       
   417                 media = NULL;
       
   418                 
       
   419                 TRAP_IGNORE( 
       
   420                     {
       
   421                     MMsvAttachmentManagerSync& managerSync = iEditStore->AttachmentManagerExtensionsL();    
       
   422                     managerSync.RemoveAttachmentL( CUniDataUtils::IndexPositionOfAttachmentL( *manager, 
       
   423                                                                                               iNewVCardAttaId ) );
       
   424                     iEditStore->CommitL();
       
   425                     iNewVCardAttaId = KMsvNullIndexEntryId;
       
   426                     });
       
   427                     
       
   428                 SetError( EUniInsertTooBig );
       
   429                 
       
   430                 // Try whether next vCard fits to max message size.
       
   431                 }
       
   432             
       
   433             // Current contact handled, start next one. Whether there still
       
   434             // exist unhandled contacts, it is decided elsewhere.
       
   435             iOperationState = EUniProcessVCardExportNext;
       
   436             CompleteOperation( KErrNone );
       
   437             
       
   438             // Close temporary attachment handle.
       
   439             storedVCard.Close();
       
   440             }
       
   441         else
       
   442             {
       
   443             // Couldn't get a handle to a stored attachment,
       
   444             // let's give up.
       
   445             iOperationState = EUniProcessVCardError;
       
   446             CompleteOperation( err );
       
   447             }        
       
   448         }
       
   449     }
       
   450 
       
   451 // ---------------------------------------------------------
       
   452 // CUniEditorVCardOperation::VPbkSingleContactOperationFailed
       
   453 //
       
   454 // ---------------------------------------------------------
       
   455 //
       
   456 void CUniEditorVCardOperation::VPbkSingleContactOperationFailed(
       
   457     MVPbkContactOperationBase& /*aOperation*/, TInt aError )
       
   458     {
       
   459     iLastError = aError;
       
   460     
       
   461     SetError( iLastError );
       
   462 
       
   463     Reset();
       
   464     
       
   465     iOperationState = EUniProcessVCardError;
       
   466     CompleteOperation( iLastError );
       
   467     }
       
   468 
       
   469 // ---------------------------------------------------------
       
   470 // CUniEditorVCardOperation::Reset
       
   471 //
       
   472 // ---------------------------------------------------------
       
   473 void CUniEditorVCardOperation::Reset()
       
   474     {
       
   475     delete iContact;
       
   476     iContact = NULL;
       
   477 
       
   478     delete iStoreContact;
       
   479     iStoreContact = NULL;
       
   480 
       
   481     delete iVCardExportOp;
       
   482     iVCardExportOp = NULL;
       
   483 
       
   484     delete iEditStore;
       
   485     iEditStore = NULL;
       
   486         
       
   487     iNewVCardAttaId = KMsvNullIndexEntryId;
       
   488     iVCardStream.Close();
       
   489     }
       
   490 
       
   491 // ---------------------------------------------------------
       
   492 // CUniEditorVCardOperation::ResetAll
       
   493 //
       
   494 // ---------------------------------------------------------
       
   495 //
       
   496 void CUniEditorVCardOperation::ResetAll()
       
   497     {
       
   498     // First reset counters.
       
   499     iCurrentContactIndex = -1;
       
   500     iAddedVCardCount = 0;
       
   501 
       
   502     if ( iContacts )
       
   503         {
       
   504         delete iContacts;
       
   505         iContacts = NULL;
       
   506         }
       
   507     
       
   508     Reset();
       
   509     
       
   510     // Reset any previous errors, since we are started again.
       
   511     ResetErrors();
       
   512     }
       
   513 
       
   514 // ---------------------------------------------------------
       
   515 // CUniEditorVCardOperation::ReportEvent
       
   516 //
       
   517 // ---------------------------------------------------------
       
   518 //
       
   519 void CUniEditorVCardOperation::ReportEvent( TUniEditorOperationEvent aEvent )
       
   520     {
       
   521     iObserver.EditorOperationEvent( EUniEditorOperationVCard, aEvent );
       
   522     }
       
   523 
       
   524 // EOF