diff -r ccd0fd43f247 -r 208a4ba3894c harvesterplugins/messaging/email/qtemailfetcher/qtemailfetcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/harvesterplugins/messaging/email/qtemailfetcher/qtemailfetcher.cpp Mon May 03 12:32:15 2010 +0300 @@ -0,0 +1,249 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility class for fetching email. +* +*/ + +#include "qtemailfetcher.h" +#include +#include +//#include //If we happen to use QThread::yieldCurrentThread() + +//Symbian specific details; picked up from cemailplugin.cpp. +//Refactor it to cpixmaindefs.h +_LIT(KMsgBaseAppClassGeneric, "root msg email"); + +_LIT(KMsgSubject, "Subject"); +_LIT(KMsgRecipients, "Recipients"); +_LIT(KMsgBody, "Body"); +_LIT(KMimeTypeField, CPIX_MIMETYPE_FIELD); +_LIT(KMimeTypeMsg, "Messages"); + +//------------------------------------------------------------------------------ +QEmailFetcher::QEmailFetcher( MEmailItemObserver& aObserver ) + :iEmailObserver( aObserver ), + iEmailEventNotifier( NULL ), + iEmailService( NULL ), + iMailBoxListings( NULL ), + iMailFolderList( NULL ), + iEnvelopeListing( NULL ) + { + } + +//------------------------------------------------------------------------------ +QEmailFetcher::~QEmailFetcher() + { + delete iEmailEventNotifier; + delete iEmailService; + delete iMailBoxListings; + delete iMailFolderList; + } + +//------------------------------------------------------------------------------ +QEmailFetcher* QEmailFetcher::newInstance( MEmailItemObserver& aObserver ){ + QEmailFetcher* emailFetcher = NULL; + + //Leak free init. + try{ + QEmailFetcher* emailFetcher = new QEmailFetcher( aObserver ); + //Uncomment 'this' once the actual APIs are ready. + emailFetcher->iEmailService = new NmEmailService( emailFetcher ); + emailFetcher->iEmailEventNotifier = new NmEventNotifier( emailFetcher ); + emailFetcher->iMailBoxListings = new NmMailboxListing( emailFetcher ); + }catch(...){ //cleanup. + delete emailFetcher; + delete emailFetcher->iEmailService; + delete emailFetcher->iEmailEventNotifier; + delete emailFetcher->iMailBoxListings; + emailFetcher->iEmailService = NULL; + emailFetcher->iEmailEventNotifier = NULL; + emailFetcher->iMailBoxListings = NULL; + throw; //rethrow the exception to caller. + } + initialize( emailFetcher ); //Do the rest of the init. + return emailFetcher; //returns only if not null. +} + +//------------------------------------------------------------------------------ +void QEmailFetcher::initialize( QEmailFetcher* aThis ){ + //The use of 'aThis' is because the current function is static. + connect( aThis->iEmailService, SIGNAL(initialized(bool)), + aThis, SLOT(emailServiceIntialized(bool)) ); + aThis->iEmailService->initialise(); + aThis->connect( aThis->iEmailEventNotifier, + SIGNAL(messageEvent(MessageEvent, quint64, quint64, QList)), + aThis, + SLOT(handleMessageEvent(MessageEvent, quint64, quint64, QList)) ); +} + +//------------------------------------------------------------------------------ +void QEmailFetcher::emailServiceIntialized(bool aAllOk){ + if( aAllOk ){ + connect( iMailBoxListings, SIGNAL(mailboxesListed(int)), this, SLOT(handleMailboxesListed(int)) ); + } +} + +//------------------------------------------------------------------------------ +void QEmailFetcher::StartHarvesting(){ + iMailBoxListings->start(); +} + +//------------------------------------------------------------------------------ +namespace { + +// Taken from qt/src/corelib/kernel/qcore_symbian_p.cpp, as recomended in +// http://qt.nokia.com/files/pdf/whitepaper-using-qt-and-symbian-c-together, page 34. +// URL last accessed on April 6th, 2010. + +// Returned TPtrC is valid as long as the given parameter is valid and unmodified +static inline TPtrC qt_QString2TPtrC( const QString& string ) +{ + return TPtrC16(static_cast(string.utf16()), string.length()); +} + +//------------------------------------------------------------------------------ +// TODO Remove this code if qt_QString2TPtrC works. +// TODO If this function is used, remember to release memory. +// Ownership with caller. +//HBufC* qt_QString2HBufC(const QString& aString) +//{ +// HBufC *buffer; +//#ifdef QT_NO_UNICODE +// TPtrC8 ptr(reinterpret_cast(aString.toLocal8Bit().constData())); +//#else +// TPtrC16 ptr(qt_QString2TPtrC(aString)); +//#endif +// buffer = q_check_ptr(HBufC::New(ptr.Length())); +// buffer->Des().Copy(ptr); +// return buffer; +//} + +//------------------------------------------------------------------------------ +//Private free function creates CSearchDocument from EMailMessageEnvelope. +CSearchDocument* getSearchDocument( const NmMessageEnvelope& aEnvelope ){ + QList toList; + //Need to cast away const-ness since the get method is unfortunately not const. + const_cast(aEnvelope).getToRecipients( toList ); + + //We need ALL the recipients in a SINGLE field. + QString recipients = ""; + for( int i=0; i(aEnvelope).getPlainTextBody( body ); + QString msgBody = body.content(); + + CSearchDocument* doc = 0; + QT_TRAP_THROWING( + //Use qt_Qstring2TPtrC since we are working with const EmailMessageEnvelope. + doc = CSearchDocument::NewL( qt_QString2TPtrC( QString().setNum( aEnvelope.id() ) ), + KMsgBaseAppClassGeneric ); + doc->AddFieldL( KMimeTypeField, KMimeTypeMsg, CDocumentField::EStoreYes | CDocumentField::EIndexUnTokenized); + doc->AddFieldL( KMsgSubject, qt_QString2TPtrC( aEnvelope.subject() ), CDocumentField::EStoreYes | CDocumentField::EIndexTokenized ); + doc->AddFieldL( KMsgRecipients, qt_QString2TPtrC( recipients ), CDocumentField::EStoreYes | CDocumentField::EIndexTokenized ); + doc->AddFieldL( KMsgBody, qt_QString2TPtrC( msgBody ), CDocumentField::EStoreYes | CDocumentField::EIndexTokenized ); + //TODO: What should go in here? + doc->AddExcerptL( KNullDesC ); + ); + return doc; +} +} //anonymous namespace + +//------------------------------------------------------------------------------ +//Options to make async (like other plugins' Asynchronizer): +//1. Use http://doc.trolltech.com/4.6/qtimer.html and connect timeout() signal to something? +//Downside: +//Have to save the state of the function and resume. Achievable via static members. +//Remeber to reset counters. +//2. Use timer; unlike above, have handleMailboxesListed() simply trigger a +//Timer controlled function. +//3. Use QThread::currentThread()->yieldCurrentThread(); +//Downside: Not tested. +//4. As recommended by the email API documentation, use SingleShotTimer: +//QTimer::singleShot(nsecs,nmFolderListing,SLOT(start()); +// +//Recommendation: Use option 4. + +void QEmailFetcher::handleMailboxesListed(int aCount){ + QList mailBoxes; + if( aCount>0 && iMailBoxListings->getMailboxes( mailBoxes ) ){ + for( int i=0; i folders; + if ( aCount && iMailFolderList->getFolders( folders ) ) { + for( int i=0; istart(); + } + } +} + +//------------------------------------------------------------------------------ +void QEmailFetcher::processMessages(int aCount){ + if( aCount == NmMailboxListing::MailboxListingFailed ) return; //silently. + QList envelopes; + if ( aCount > 0 && iEnvelopeListing->getEnvelopes(envelopes) ) { + for( int i=0; i aMessageList){ + NmMessageEnvelope envelope; + const int messageCount = aMessageList.count(); + if( messageCount>0 ){ + if( aEvent == MessageCreated || aEvent == MessageChanged ){ + for( int i=0; igetEnvelope( aMailboxId, aFolderId, aMessageList.at( i ), envelope ) ){ + QT_TRAP_THROWING( + iEmailObserver.HandleDocumentL( getSearchDocument( envelope ), + //Doing this simply avoids *duplicate* code for update action. + aEvent == MessageCreated ? ECPixAddAction : ECPixUpdateAction ) ); + } + } + } + else if( aEvent == MessageDeleted ) { + //TODO We can do better. For delete, we dont have to create full document. Just the ID should be enough. + //We can have another function called getPartialSearchDocument so deletes will be faster. + for( int i=0; igetEnvelope( aMailboxId, aFolderId, aMessageList.at( i ), envelope ) ){ + QT_TRAP_THROWING( + iEmailObserver.HandleDocumentL( getSearchDocument( envelope ), ECPixRemoveAction ) ); + } + } + } + } +}