messagingapp/msgappfw/plugins/previewplugin/src/ccspreviewpluginhandler.cpp
branchRCL_3
changeset 26 ebe688cedc25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgappfw/plugins/previewplugin/src/ccspreviewpluginhandler.cpp	Tue Aug 31 15:11:31 2010 +0300
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (c) 2007 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:  CS Preview Plugin Handler, This class creates and updates sqlite based db
+ *                with the message-preview data.
+ *
+ */
+// USER INCLUDES
+#include "ccspreviewpluginhandler.h"
+#include "UniObject.h"
+#include "msgbiouids.h"
+// SYSTEM INCLUDES
+#include <bioscmds.h>
+#include <biocmtm.h>
+#include <mmsclient.h>
+#include <mtclreg.h>
+#include <msvids.h>
+#include <e32const.h>
+#include <SendUiConsts.h>
+#include <utf.h>
+#include <centralrepository.h>
+#include <MmsConformance.h>
+#include <mmsconst.h>
+#include <msgmediainfo.h>
+#include <MsgMediaResolver.h>
+#include <fileprotectionresolver.h>
+#include <MmsEngineInternalCRKeys.h>
+//CONSTANTS
+//DB-file
+_LIT(KDbFileName, "c:[2002A542]conversations.db");
+//Encoding
+_LIT(KEncodingStmnt,"PRAGMA encoding=\"UTF-8\"");
+//Size
+_LIT(KCacheSizeStmnt,"PRAGMA default_cache_size = 1024");
+// Create table query statement
+_LIT(KSqlCreateStmt, "CREATE TABLE IF NOT EXISTS conversation_messages ( message_id  INTEGER PRIMARY KEY, msg_processingstate INTEGER DEFAULT 0, subject TEXT(100), body_text TEXT(160), preview_path TEXT, msg_property INTEGER, preview_icon BLOB DEFAULT NULL ) " );
+//Create an empty record for the given message id
+_LIT(KSqlBasicInsertStmt, "INSERT OR REPLACE INTO conversation_messages ( message_id ) VALUES( :message_id )");
+//Insert without bitmap query
+_LIT(KSqlInsertStmt, "INSERT OR REPLACE INTO conversation_messages ( message_id, msg_processingstate, subject, body_text, preview_path, msg_property ) VALUES( :message_id, :msg_processingstate, :subject, :body_text, :preview_path,  :msg_property )");
+//update processing-state flag of a message
+_LIT(KSqlUpdateProcessingStateStmt, "UPDATE conversation_messages SET msg_processingstate=:msg_processingstate WHERE message_id=:message_id " );
+//update with bitmap query
+_LIT(KSqlUpdateBitmapStmt, "UPDATE conversation_messages SET preview_icon=:preview_icon WHERE message_id=:message_id " );
+// query to see if msg is under process at the moment
+_LIT(KSelectProcessingStateStmt, " SELECT message_id, msg_processingstate FROM conversation_messages WHERE message_id=:message_id ");
+// Remove record from conversation_messages table.
+_LIT(KRemoveMsgStmnt,"DELETE FROM conversation_messages WHERE message_id=:message_id");
+//Insert vcard meta-daa query
+_LIT(KSqlInsertBioMsgStmt, "INSERT OR REPLACE INTO conversation_messages ( message_id, msg_processingstate, preview_path ) VALUES( :message_id, :msg_processingstate, :preview_path )");
+
+const TInt KDefaultMaxSize = 300 * 1024;
+//Preview thumbnail size
+const TInt KWidth = 9.5 * 6.7;
+const TInt KHeight = 9.5 * 6.7;
+
+// NOTE:- DRAFTS ENTRIES ARE NOT HANDLED IN THE PLUGIN
+
+// ============================== MEMBER FUNCTIONS ============================
+// ----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::NewL
+// Two Phase Construction
+// ----------------------------------------------------------------------------
+//
+CCsPreviewPluginHandler* CCsPreviewPluginHandler::NewL(
+    CCsPreviewPlugin *aMsgObserver)
+{
+    PRINT ( _L("Enter CCsMsgHandler::NewL") );
+
+    CCsPreviewPluginHandler* self = new (ELeave) CCsPreviewPluginHandler();
+    CleanupStack::PushL(self);
+    self->ConstructL(aMsgObserver);
+    CleanupStack::Pop(self);
+
+    PRINT ( _L("End CCsPreviewPluginHandler::NewL") );
+
+    return self;
+}
+
+// ----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::~CCsPreviewPluginHandler
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CCsPreviewPluginHandler::~CCsPreviewPluginHandler()
+{
+    PRINT ( _L("Enter CCsPreviewPluginHandler::~CCsPreviewPluginHandler") );
+
+    iSqlDb.Close();
+    iThumbnailRequestArray.Close();
+    ifsSession.Close();
+
+    if (iMmsMtm)
+    {
+        delete iMmsMtm;
+        iMmsMtm = NULL;
+    }
+
+    if (iBioClientMtm)
+        {
+        delete iBioClientMtm;
+        iBioClientMtm = NULL;
+        }
+
+    if (iMtmRegistry)
+    {
+        delete iMtmRegistry;
+        iMtmRegistry = NULL;
+    }
+
+    if (iSession)
+    {
+        delete iSession;
+        iSession = NULL;
+    }
+
+    if (iThumbnailManager)
+    {
+        delete iThumbnailManager;
+        iThumbnailManager = NULL;
+    }
+
+    PRINT ( _L("End CCsPreviewPluginHandler::~CCsPreviewPluginHandler") );
+}
+
+// ----------------------------------------------------------------------------
+// CCsMsgHandler::ConstructL
+// Two Phase Construction
+// ----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::ConstructL(CCsPreviewPlugin *aMsgObserver)
+{
+    PRINT ( _L("Enter CCsPreviewPluginHandler::ConstructL") );
+
+    iMsgObserver = aMsgObserver;
+
+    //file session connect
+    User::LeaveIfError(ifsSession.Connect());
+
+    //create msv session
+    iSession = CMsvSession::OpenSyncL(*this);
+
+    //create mtm registry
+    iMtmRegistry = CClientMtmRegistry::NewL(*iSession);
+
+    //create mms client mtm
+    iMmsMtm = static_cast<CMmsClientMtm*> (iMtmRegistry-> NewMtmL(
+            KSenduiMtmMmsUid));
+
+    // create biomsg client mtm
+    iBioClientMtm = static_cast<CBIOClientMtm*> (iMtmRegistry->NewMtmL(
+            KSenduiMtmBioUid));
+
+    //create thumbnail manager
+    iThumbnailManager = CThumbnailManager::NewL(*this);
+
+    // open DB
+    TInt error = iSqlDb.Open(KDbFileName);
+
+    PRINT1 ( _L("End CCsPreviewPluginHandler::ConstructL open DB file error=%d"), error );
+
+    // if not found, create DB
+    if (error == KErrNotFound)
+    {
+        //create sqlite-DB
+        TSecurityPolicy defaultPolicy(TSecurityPolicy::EAlwaysPass);
+        RSqlSecurityPolicy securityPolicy;
+        securityPolicy.Create(defaultPolicy);
+
+        // TODO, setting UID security policy
+        //TSecurityPolicy readPolicy(ECapabilityReadUserData);  
+        //securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, readPolicy);
+
+        iSqlDb.Create(KDbFileName, securityPolicy);
+
+        //Create the table inside DB
+        iSqlDb.Exec(KSqlCreateStmt);
+        iSqlDb.Exec(KEncodingStmnt);
+        iSqlDb.Exec(KCacheSizeStmnt);
+    }
+    else
+    {
+        User::LeaveIfError(error);
+    }
+
+    //get the max size of mms from the repository
+    TRAP_IGNORE(
+            CRepository* repository = CRepository::NewL(KCRUidMmsEngine);
+            CleanupStack::PushL(repository);
+
+            //Fetch and set max mms composition size
+            TInt maxSize = KDefaultMaxSize;
+            repository->Get( KMmsEngineMaximumSendSize, maxSize );
+            iMaxMmsSize = maxSize;
+
+            //Fetch and set creation mode
+            TInt creationMode = EMmsCreationModeRestricted;
+            repository->Get(KMmsEngineCreationMode, creationMode);
+            iCreationMode = creationMode;
+
+            CleanupStack::PopAndDestroy(repository);
+    );
+    PRINT ( _L("End CCsPreviewPluginHandler::ConstructL") );
+}
+
+// ----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::CCsPreviewPluginHandler
+// Two Phase Construction
+// ----------------------------------------------------------------------------
+//
+CCsPreviewPluginHandler::CCsPreviewPluginHandler()
+{
+}
+
+// ----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::HandleSessionEventL
+// Implemented for MMsvSessionObserver
+// ----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::HandleSessionEventL(TMsvSessionEvent aEvent,
+    TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
+{
+    PRINT1 ( _L("Enter CCsPreviewPluginHandler::HandleSessionEventL aEvent=%d"),aEvent );
+
+    CMsvEntrySelection* selection = NULL;
+    TMsvId parent;
+
+    //args
+    if (aArg1 == NULL || aArg2 == NULL)
+    {
+        PRINT ( _L("Enter CCsPreviewPluginHandler::HandleSessionEventL arguments invalid"));
+        return;
+    }
+
+    //start, processing the event
+    selection = (CMsvEntrySelection*) aArg1;
+    parent = *(TMsvId*) aArg2;
+
+    //Drafts not handled
+    if (KMsvDraftEntryIdValue == parent)
+    {
+        return;
+    }
+
+    switch (aEvent)
+    {
+        case EMsvEntriesChanged:
+        case EMsvEntriesMoved:
+        {
+            HandleEventL(selection);
+        }
+        break;
+
+        case EMsvEntriesDeleted:
+        {
+            for (TInt i = 0; i < selection->Count(); i++)
+            {
+                RSqlStatement sqlDeleteStmt;
+                CleanupClosePushL(sqlDeleteStmt);
+                sqlDeleteStmt.PrepareL(iSqlDb, KRemoveMsgStmnt);
+
+                TInt messageIdIndex = sqlDeleteStmt.ParameterIndex(_L(
+                    ":message_id"));
+                User::LeaveIfError(sqlDeleteStmt.BindInt(messageIdIndex, selection->At(i)));
+
+                User::LeaveIfError(sqlDeleteStmt.Exec());
+                CleanupStack::PopAndDestroy(&sqlDeleteStmt);
+            }
+        }
+        break;
+    }
+
+    PRINT ( _L("Exit CCsPreviewPluginHandler::HandleSessionEventL") );
+}
+
+// ---------------------------------------------------------------------
+// CCsPreviewPluginHandler::HandleEvent
+// Handle events
+// ---------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::HandleEventL(CMsvEntrySelection* aSelection)
+{
+    PRINT ( _L("Enter CCsPreviewPluginHandler::HandleEvent start.") );
+
+    TMsvEntry entry;
+    TMsvId service;
+    TInt error = KErrNone;
+
+    for (TInt i = 0; i < aSelection->Count(); i++)
+    {
+        error = iSession->GetEntry(aSelection->At(i), service, entry);
+
+        if ((KErrNone == error) && !entry.InPreparation() && entry.Visible())
+        {
+            PRINT ( _L("Enter CCsPreviewPluginHandler::HandleEvent for loop started.") );
+            if ((KSenduiMtmMmsUidValue == entry.iMtm.iUid))
+                {
+                HandleMMSEntryL(entry);
+                }
+            else if ((KSenduiMtmSmsUidValue == entry.iMtm.iUid) || (KSenduiMtmBioUidValue == entry.iMtm.iUid))
+                {
+                if ((KMsgBioUidVCard.iUid == entry.iBioType))
+                    {                 
+                    HandleVCardEntryL(entry);
+                    }
+                }
+            }
+        }//end for loop
+
+    PRINT ( _L("Exit CCsPreviewPluginHandler::HandleEvent end.") );
+    }
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::HandleMMSEntryL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::HandleMMSEntryL(const TMsvEntry& aEntry)
+    {
+    PRINT ( _L("Enter CCsPreviewPluginHandler::HandleMMSEntry start.") );
+
+    TInt msgId = aEntry.Id();
+
+    // check if the msg is already under processing Or processed
+    if (EPreviewMsgNotProcessed != msgProcessingState(msgId))
+        {
+        // skip processing this event for the given message
+        return;
+        }
+
+    // start processing message, set flag
+    setMsgProcessingState(msgId, EPreviewMsgProcessing);
+
+    // update db with message preview data
+    RSqlStatement sqlInsertStmt;
+    CleanupClosePushL(sqlInsertStmt);
+    sqlInsertStmt.PrepareL(iSqlDb, KSqlInsertStmt);
+
+    // parse message
+    iMmsMtm->SwitchCurrentEntryL(msgId);
+    iMmsMtm->LoadMessageL();
+
+    CUniDataModel* iUniDataModel = CUniDataModel::NewL(ifsSession, *iMmsMtm);
+    CleanupStack::PushL(iUniDataModel);
+    iUniDataModel->RestoreL(*this, ETrue);
+
+    //msg property
+    TInt msgProperty = 0;
+    if (iUniDataModel->AttachmentList().Count() > 0)
+        {
+        msgProperty |= EPreviewAttachment;
+        }
+
+    //check for msg forward
+    //Validate if the mms msg can be forwarded or not
+    if (ValidateMsgForForward(iUniDataModel))
+        {
+        msgProperty |= EPreviewForward;
+        }
+
+    TPtrC videoPath;
+    TPtrC imagePath;
+
+    // preview parsing
+    TInt slideCount = iUniDataModel->SmilModel().SlideCount();
+    TBool isBodyTextSet = EFalse;
+    TBool isImageSet = EFalse;
+    TBool isAudioSet = EFalse;
+    TBool isVideoSet = EFalse;
+
+    for (int i = 0; i < slideCount; i++)
+        {
+        int slideobjcount = iUniDataModel->SmilModel().SlideObjectCount(i);
+        for (int j = 0; j < slideobjcount; j++)
+            {
+            CUniObject *obj = iUniDataModel->SmilModel(). GetObjectByIndex(i,
+                    j);
+            CMsgMediaInfo *mediaInfo = obj->MediaInfo();
+
+            TPtrC8 mimetype = obj->MimeType();
+            TMsvAttachmentId attachId = obj->AttachmentId();
+
+            //bodytext
+            if (!isBodyTextSet
+                    && (mimetype.Find(_L8("text")) != KErrNotFound))
+                {
+                //bind bodytext into statement
+                BindBodyText(sqlInsertStmt, attachId);
+                isBodyTextSet = ETrue;
+                }
+
+            //image parsing
+            if (!isVideoSet && !isImageSet && (mimetype.Find(_L8("image"))
+                    != KErrNotFound))
+                {
+                //get thumbnail for this image
+                isImageSet = ETrue;
+                imagePath.Set(mediaInfo->FullFilePath());
+                msgProperty |= EPreviewImage;
+
+                if (EFileProtNoProtection != mediaInfo->Protection())
+                    {
+                    msgProperty |= EPreviewProtectedImage;
+                    }
+                if (mediaInfo->Corrupt())
+                    {
+                    msgProperty |= EPreviewCorruptedImage;
+                    }
+
+                if (!(EPreviewProtectedImage & msgProperty)
+                        && !(EPreviewCorruptedImage & msgProperty))
+                    {
+                    //Generate thumbnail for non protected,
+                    //non corrupted image.
+                    GetThumbNailL(attachId, mimetype, msgId);
+                    }
+                }
+
+            //audio content
+            if (!isVideoSet && !isAudioSet && (mimetype.Find(_L8("audio"))
+                    != KErrNotFound))
+                {
+                isAudioSet = ETrue;
+                msgProperty |= EPreviewAudio;
+                if (EFileProtNoProtection != mediaInfo->Protection())
+                    {
+                    msgProperty |= EPreviewProtectedAudio;
+                    }
+                if (mediaInfo->Corrupt())
+                    {
+                    msgProperty |= EPreviewCorruptedAudio;
+                    }
+                }
+
+            //video content
+            if (!(isImageSet || isAudioSet) && !isVideoSet && (mimetype.Find(
+                    _L8("video")) != KErrNotFound))
+                {
+                videoPath.Set(mediaInfo->FullFilePath());
+                isVideoSet = ETrue;
+                msgProperty |= EPreviewVideo;
+                if (EFileProtNoProtection != mediaInfo->Protection())
+                    {
+                    msgProperty |= EPreviewProtectedVideo;
+                    }
+                if (mediaInfo->Corrupt())
+                    {
+                    msgProperty |= EPreviewCorruptedVideo;
+                    }
+                }
+            }
+        }
+
+    //set preview path
+    TInt previewPathIndex = sqlInsertStmt.ParameterIndex(_L(
+            ":preview_path"));
+    if (isVideoSet)
+        {
+        User::LeaveIfError(
+                sqlInsertStmt.BindText(previewPathIndex, videoPath));
+        }
+    else if (isImageSet)
+        {
+        User::LeaveIfError(
+                sqlInsertStmt.BindText(previewPathIndex, imagePath));
+        }
+
+    //msg_id
+    TInt msgIdIndex = sqlInsertStmt.ParameterIndex(_L(":message_id"));
+    User::LeaveIfError(sqlInsertStmt.BindInt(msgIdIndex, msgId));
+
+    //subjext
+    TInt subjectIndex = sqlInsertStmt.ParameterIndex(_L(":subject"));
+    User::LeaveIfError(sqlInsertStmt.BindText(subjectIndex,
+            iMmsMtm->SubjectL()));
+
+    //msg_property
+    TInt msgPropertyIndex = sqlInsertStmt.ParameterIndex(_L(
+            ":msg_property"));
+    User::LeaveIfError(sqlInsertStmt.BindInt(msgPropertyIndex, msgProperty));
+
+    //msg_processingstate
+    TInt msgProcessingStateIndex = sqlInsertStmt.ParameterIndex(
+            _L(":msg_processingstate"));
+    User::LeaveIfError(sqlInsertStmt.BindInt(msgProcessingStateIndex,
+            EPreviewMsgProcessed));
+
+    //execute sql stament
+    User::LeaveIfError(sqlInsertStmt.Exec());
+
+    //cleanup
+    CleanupStack::PopAndDestroy(2, &sqlInsertStmt);
+
+    PRINT ( _L("Enter CCsPreviewPluginHandler::HandleMMSEntry end.") );
+    }
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::HandleVCardEntryL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::HandleVCardEntryL(const TMsvEntry& aEntry)
+    {
+    PRINT ( _L("Enter CCsPreviewPluginHandler::HandleBioMsgEntry start.") );
+
+    TMsvId msgId = aEntry.Id();   
+    
+    // check if the msg is already under processing Or processed
+    TInt msgProcessState = EPreviewMsgNotProcessed;
+    msgProcessState = msgProcessingState(msgId);
+    if (EPreviewMsgProcessed == msgProcessState)
+        {
+        return;
+        }
+    //get attachments
+    CMsvEntry* cMsvEntry = CMsvEntry::NewL(iBioClientMtm->Session(), msgId,
+               TMsvSelectionOrdering());
+    
+    CleanupStack::PushL(cMsvEntry);
+    CMsvStore* store = cMsvEntry->ReadStoreL();
+    CleanupStack::PushL(store);
+    MMsvAttachmentManager& attachMan = store->AttachmentManagerL();
+
+    TInt attachmentCount = attachMan.AttachmentCount();
+    if (attachmentCount)
+        {
+        // get attachment file path
+        RFile file = attachMan.GetAttachmentFileL(0);
+        CleanupClosePushL(file);
+        TFileName fullName;
+        User::LeaveIfError(file.FullName(fullName));
+
+        // update db with meta-data
+        RSqlStatement sqlInsertStmt;
+        CleanupClosePushL(sqlInsertStmt);
+        sqlInsertStmt.PrepareL(iSqlDb, KSqlInsertBioMsgStmt);
+       
+        //msg_id
+        TInt msgIdIndex = sqlInsertStmt.ParameterIndex(_L(":message_id"));
+        User::LeaveIfError(sqlInsertStmt.BindInt(msgIdIndex, msgId));
+
+        //set attachment path
+        TInt previewPathIndex = sqlInsertStmt.ParameterIndex(_L(
+                ":preview_path"));
+        User::LeaveIfError(sqlInsertStmt.BindText(previewPathIndex, fullName));
+
+        //msg_processingstate
+        TInt msgProcessingStateIndex = sqlInsertStmt.ParameterIndex(
+                _L(":msg_processingstate"));
+        User::LeaveIfError(sqlInsertStmt.BindInt(msgProcessingStateIndex,
+                EPreviewMsgProcessed));
+
+        //execute sql stament
+        User::LeaveIfError(sqlInsertStmt.Exec());
+
+        //cleanup
+        CleanupStack::PopAndDestroy(&sqlInsertStmt);
+        CleanupStack::PopAndDestroy(&file);
+        }
+
+    CleanupStack::PopAndDestroy(2, cMsvEntry);//cMsvEntry,store
+
+    PRINT ( _L("Enter CCsPreviewPluginHandler::HandleBioMsgEntry End.") );
+    }
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::RestoreReady()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::RestoreReady(TInt /*aParseResult*/, TInt /*aError*/)
+{
+
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::ThumbnailReady()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::ThumbnailReady(TInt aError,
+    MThumbnailData& aThumbnail, TThumbnailRequestId aId)
+{
+    // This function must not leave.
+    if (!aError)
+    {
+        PRINT ( _L("CCsPreviewPluginHandler::ThumbnailReady received.") );
+        TInt err;
+        TRAP(err, HandleThumbnailReadyL(aThumbnail, aId));
+        PRINT1 ( _L("CCsPreviewPluginHandler::ThumbnailReady handling error= %d."), err );
+    }
+    else
+    {
+        // An error occurred while getting the thumbnail.
+        PRINT1 ( _L("End CCsPreviewPluginHandler::ThumbnailReady error= %d."), aError );
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::ThumbnailPreviewReady()
+// callback
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::ThumbnailPreviewReady(
+    MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/)
+{
+
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::HandleThumbnailReadyL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::HandleThumbnailReadyL(MThumbnailData& aThumbnail,
+    TThumbnailRequestId aId)
+{
+    //match response to request
+    ThumbnailRequestData tempObj;
+    tempObj.iRequestId = aId;
+
+    TInt index = iThumbnailRequestArray.Find(tempObj,
+        CCsPreviewPluginHandler::CompareByRequestId);
+    if (index < 0)
+    {
+        PRINT ( _L("End CCsPreviewPluginHandler::HandleThumbnailReady request match not found.") );
+        return;
+    }
+
+    // get msg-id corresponding to the request-id
+    TInt msgId = iThumbnailRequestArray[index].iMsgId;
+    //remove the request from requestarray
+    iThumbnailRequestArray.Remove(index);
+
+    // get bitmap
+    CFbsBitmap* bitmap = aThumbnail.Bitmap();
+
+    // sql-statment to set preview-icon
+    RSqlStatement sqlInsertStmt;
+    CleanupClosePushL(sqlInsertStmt);
+    sqlInsertStmt.PrepareL(iSqlDb, KSqlUpdateBitmapStmt);
+
+    TInt msgIdIndex = sqlInsertStmt.ParameterIndex(_L(":message_id"));
+    TInt previewIconIndex = sqlInsertStmt.ParameterIndex(_L(":preview_icon"));
+
+    User::LeaveIfError(sqlInsertStmt.BindInt(msgIdIndex, msgId));
+
+    RSqlParamWriteStream previewIconStream;
+    CleanupClosePushL(previewIconStream);
+
+    //bind data
+    User::LeaveIfError(previewIconStream.BindBinary(sqlInsertStmt, previewIconIndex));
+    bitmap->ExternalizeL(previewIconStream);
+    previewIconStream.CommitL();
+
+    //execute the statent
+    User::LeaveIfError(sqlInsertStmt.Exec());
+
+    CleanupStack::PopAndDestroy(2,&sqlInsertStmt);//sqlInsertStmt,previewIconStream
+}
+
+TBool CCsPreviewPluginHandler::ValidateMsgForForward(CUniDataModel* aUniDataModel)
+{
+    TBool retValue = ETrue;
+
+    //1. Check the slide count more than 1
+    if (aUniDataModel->SmilModel().SlideCount() > 1)
+    {
+        retValue = EFalse;
+        return retValue;
+    }
+
+    //2. message sixe check
+    //Fetch and set max mms composition size
+    if (iMmsMtm->MessageSize() > iMaxMmsSize)
+    {
+        retValue = EFalse;
+        return retValue;
+    }
+
+    //3. If there is restricted content then return false
+    RArray<TMsvAttachmentId>* pathList = GetSlideAttachmentIds(
+            0, 
+            aUniDataModel);
+    
+    CleanupStack::PushL(pathList);
+
+    for (int i = 0; i < pathList->Count(); i++)
+    {
+        TMsvAttachmentId aId = (*pathList)[i];
+        CMsvStore * store = iMmsMtm->Entry().ReadStoreL();
+        CleanupStack::PushL(store);
+        MMsvAttachmentManager& attachMan = store->AttachmentManagerL();
+        RFile fileHandle = attachMan.GetAttachmentFileL(aId);
+        //close the store
+        CleanupStack::PopAndDestroy(store);
+
+        if (CheckModeForInsertL(fileHandle) != EInsertSuccess)
+        {
+            retValue = EFalse;
+            break;
+        }
+    }
+
+    if (retValue == EFalse)
+    {
+        CleanupStack::PopAndDestroy(pathList);
+        return retValue;
+    }
+
+    CleanupStack::Pop(pathList);
+    delete pathList;
+    pathList = NULL;
+
+    //4. check the same case for all attachments
+    pathList = GetAttachmentIdList(aUniDataModel);
+    CleanupStack::PushL(pathList);
+
+    for (int i = 0; i < pathList->Count(); i++)
+    {
+        TMsvAttachmentId aId = (*pathList)[i];
+        CMsvStore * store = iMmsMtm->Entry().ReadStoreL();
+        CleanupStack::PushL(store);
+        MMsvAttachmentManager& attachMan = store->AttachmentManagerL();
+        RFile fileHandle = attachMan.GetAttachmentFileL(aId);
+        //close the store
+        CleanupStack::PopAndDestroy(store);
+        
+        if (CheckModeForInsertL(fileHandle) != EInsertSuccess)
+        {
+            retValue = EFalse;
+            break;
+        }
+    }
+
+    CleanupStack::PopAndDestroy(pathList);
+    return retValue;
+}
+
+RArray<TMsvAttachmentId>*
+CCsPreviewPluginHandler::GetSlideAttachmentIds(TInt aSlideNum,
+                                        CUniDataModel* aUniDataModel)
+{
+    TInt slideObjectCount =
+            aUniDataModel->SmilModel().SlideObjectCount(aSlideNum);
+
+    RArray<TMsvAttachmentId> *attachmentIdList = new (ELeave) RArray<
+            TMsvAttachmentId> ();
+    for (TInt i = 0; i < slideObjectCount; i++)
+    {
+        CUniObject *obj =
+                aUniDataModel->SmilModel().GetObjectByIndex(aSlideNum, i);
+        attachmentIdList->Append(obj->AttachmentId());
+    }
+    return attachmentIdList;
+}
+
+RArray<TMsvAttachmentId>*
+CCsPreviewPluginHandler::GetAttachmentIdList(CUniDataModel* aUniDataModel)
+{
+    TInt attcount = aUniDataModel->AttachmentList().Count();
+    RArray<TMsvAttachmentId> *attachmentIdList = new (ELeave) RArray<
+            TMsvAttachmentId> ();
+
+    for (TInt i = 0; i < attcount; i++)
+    {
+        CUniObject *obj = aUniDataModel->AttachmentList().GetByIndex(i);
+
+        attachmentIdList->AppendL(obj->AttachmentId());
+    }
+    return attachmentIdList;
+}
+
+TInt CCsPreviewPluginHandler::CheckModeForInsertL(RFile aFileHandle)
+{
+    CleanupClosePushL(aFileHandle);
+
+    CMmsConformance* mmsConformance = CMmsConformance::NewL();
+    mmsConformance->CheckCharacterSet(EFalse);
+
+    CleanupStack::PushL(mmsConformance);
+
+    CMsgMediaResolver* mediaResolver = CMsgMediaResolver::NewL();
+    mediaResolver->SetCharacterSetRecognition(EFalse);
+
+    CleanupStack::PushL(mediaResolver);
+
+    CMsgMediaInfo* info = mediaResolver->CreateMediaInfoL(aFileHandle);
+    mediaResolver->ParseInfoDetailsL(info, aFileHandle);
+
+    TMmsConformance conformance = mmsConformance->MediaConformance(*info);
+    iConfStatus = conformance.iConfStatus;
+
+    CleanupStack::PopAndDestroy(3);
+
+    // In "free" mode user can insert images that are larger by dimensions than allowed by conformance
+    if (iCreationMode != EMmsCreationModeRestricted)
+    {
+        TInt i = EMmsConfNokFreeModeOnly | EMmsConfNokScalingNeeded
+                | EMmsConfNokTooBig;
+        TInt j = ~ (EMmsConfNokFreeModeOnly | EMmsConfNokScalingNeeded
+                | EMmsConfNokTooBig);
+
+        // If user answers yes to Guided mode confirmation query he/she moves to free mode
+        if ( (iConfStatus & i) && ! (iConfStatus & j))
+        {
+            if (iCreationMode == EMmsCreationModeFree || info->Protection()
+                    & EFileProtSuperDistributable)
+            {
+                // SuperDistribution not checked here
+                // Mask "FreeModeOnly" and "ScalingNeeded" away in free mode
+                iConfStatus &= ~EMmsConfNokFreeModeOnly;
+                iConfStatus &= ~EMmsConfNokScalingNeeded;
+            }
+            else
+            {
+                delete info;
+                //query not accepted. Stop insertion.
+                return EInsertQueryAbort;
+            }
+        }
+    }
+    else if (iConfStatus & EMmsConfNokDRM || iConfStatus
+            & EMmsConfNokNotEnoughInfo || iConfStatus & EMmsConfNokNotSupported
+            || iConfStatus & EMmsConfNokFreeModeOnly || iConfStatus
+            & EMmsConfNokCorrupt)
+    {
+        delete info;
+        return EInsertNotSupported;
+    }
+
+    delete info;
+    return EInsertSuccess;
+}
+
+//-----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::CompareByRequestId
+// Compare to conversation entry object based on Entry Ids
+//----------------------------------------------------------------------------
+TBool CCsPreviewPluginHandler::CompareByRequestId(
+    const ThumbnailRequestData& aFirst, const ThumbnailRequestData& aSecond)
+{
+    if (aFirst.iRequestId == aSecond.iRequestId)
+        return ETrue;
+
+    return EFalse;
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::BindBodyText()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::BindBodyText(RSqlStatement& sqlStmt,
+    TMsvAttachmentId attachmentId)
+{
+    //get file handle from attachmnet manager.
+    CMsvStore * store = iMmsMtm->Entry().ReadStoreL();
+    CleanupStack::PushL(store);
+    MMsvAttachmentManager& attachMan = store->AttachmentManagerL();
+    RFile file = attachMan.GetAttachmentFileL(attachmentId);
+    CleanupClosePushL(file);
+
+    //read file contents to buffer
+    TInt length;
+    file.Size(length);
+    HBufC8* bodyText = HBufC8::NewLC(length);
+    TPtr8 textBuffer = bodyText->Des();
+    file.Read(textBuffer);
+
+    // convert from HBufC8 to HBufC16
+    HBufC16 *text16 = HBufC16::NewLC(textBuffer.Length());
+    TPtr16 textPtr16 = text16->Des();
+    CnvUtfConverter::ConvertToUnicodeFromUtf8(textPtr16, textBuffer);
+
+    //set bodytext in the sql statement
+    TInt bodyTextIndex = sqlStmt.ParameterIndex(_L(":body_text"));
+    sqlStmt.BindText(bodyTextIndex, textPtr16);
+
+    CleanupStack::PopAndDestroy(4, store); //store,file, bodyText, text16
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::GetThumbNailL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::GetThumbNailL(TMsvAttachmentId attachmentId,
+    TDesC8& mimeType, TMsvId msgId)
+{
+    //Scale the image
+    iThumbnailManager->SetFlagsL(CThumbnailManager::ECropToAspectRatio);
+
+    //TODO replace with hb-param-graphic-size-image-portrait * value of un in pixcels
+    iThumbnailManager->SetThumbnailSizeL(TSize(KWidth, KHeight)); 
+    
+    //optimize for performace
+    iThumbnailManager->SetQualityPreferenceL(
+        CThumbnailManager::EOptimizeForPerformance);
+
+    // Create Thumbnail object source representing a path to a file
+    HBufC* mimeInfo = HBufC::NewLC(mimeType.Length());
+    mimeInfo->Des().Copy(mimeType);
+
+    CMsvStore * store = iMmsMtm->Entry().ReadStoreL();
+    CleanupStack::PushL(store);
+
+    //get file handle from attachment manager.
+    MMsvAttachmentManager& attachMan = store->AttachmentManagerL();
+    RFile file = attachMan.GetAttachmentFileL(attachmentId);
+    CleanupClosePushL(file);
+
+    CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(
+        (RFile64&) file, mimeInfo->Des());
+
+    // Issue the request for thumbnail creation
+    ThumbnailRequestData reqObject;
+    reqObject.iMsgId = msgId;
+    reqObject.iRequestId = iThumbnailManager->GetThumbnailL(*source);
+    iThumbnailRequestArray.Append(reqObject);
+
+    CleanupStack::PopAndDestroy(4, mimeInfo);//mimeInfo,store,file,source
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::msgProcessingState
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CCsPreviewPluginHandler::msgProcessingState(TMsvId aMsgId)
+{
+    TInt retState = EPreviewMsgNotProcessed;
+
+    // sql-statement to check if msg's under processing flag is set or not
+    RSqlStatement sqlSelectStmt;
+    CleanupClosePushL(sqlSelectStmt);
+    sqlSelectStmt.PrepareL(iSqlDb,KSelectProcessingStateStmt);
+
+    TInt msgIdIndex = sqlSelectStmt.ParameterIndex(_L(":message_id"));
+    User::LeaveIfError(sqlSelectStmt.BindInt(msgIdIndex, aMsgId));
+
+    // read the flag
+    TInt msgProcessingStateIndex = sqlSelectStmt.ColumnIndex(_L("msg_processingstate"));
+    if (sqlSelectStmt.Next() == KSqlAtRow)
+    {
+         retState = static_cast<TInt>(sqlSelectStmt.ColumnInt(msgProcessingStateIndex));
+    }
+    else
+    {
+        // this is first event for this msgid, hence record doesn't exist
+        // create an empty record, so that we can set & use flags
+        RSqlStatement sqlBasicInsertStmt;
+        CleanupClosePushL(sqlBasicInsertStmt);
+        sqlBasicInsertStmt.PrepareL(iSqlDb, KSqlBasicInsertStmt);
+        TInt index_msgid = sqlBasicInsertStmt.ParameterIndex(_L(":message_id"));
+        User::LeaveIfError(sqlBasicInsertStmt.BindInt(index_msgid, aMsgId));
+        User::LeaveIfError(sqlBasicInsertStmt.Exec());
+        CleanupStack::PopAndDestroy(&sqlBasicInsertStmt);
+    }
+    // cleanup
+    CleanupStack::PopAndDestroy(&sqlSelectStmt);
+    return retState;
+}
+
+// -----------------------------------------------------------------------------
+// CCsPreviewPluginHandler::setMsgProcessingState
+// 
+// -----------------------------------------------------------------------------
+//
+void CCsPreviewPluginHandler::setMsgProcessingState(TMsvId aMsgId, TInt aState)
+{
+    // sql-statment to set/reset msg's under processing flag
+    RSqlStatement sqlUpdateStmt;
+    CleanupClosePushL(sqlUpdateStmt);
+    sqlUpdateStmt.PrepareL(iSqlDb, KSqlUpdateProcessingStateStmt);
+
+    TInt msgIdIndex = sqlUpdateStmt.ParameterIndex(_L(":message_id"));
+    User::LeaveIfError(sqlUpdateStmt.BindInt(msgIdIndex, aMsgId));
+
+    // bind data
+    TInt msgProcessingStateIndex = sqlUpdateStmt.ParameterIndex(_L(":msg_processingstate"));
+    User::LeaveIfError(sqlUpdateStmt.BindInt(msgProcessingStateIndex, aState));
+
+    // execute the statement
+    User::LeaveIfError(sqlUpdateStmt.Exec());
+    // cleanup
+    CleanupStack::PopAndDestroy(&sqlUpdateStmt);
+}
+
+// End of file
+