messagingapp/msgui/appengine/src/conversationsmodel.cpp
changeset 37 518b245aa84c
parent 25 84d9eb65b26f
child 38 4e4b6adb1024
--- a/messagingapp/msgui/appengine/src/conversationsmodel.cpp	Mon May 03 12:29:07 2010 +0300
+++ b/messagingapp/msgui/appengine/src/conversationsmodel.cpp	Fri Jun 25 15:47:40 2010 +0530
@@ -19,24 +19,57 @@
 #include "conversationsenginedefines.h"
 #include "conversationmsgstorehandler.h"
 #include "convergedmessage.h"
-#include "s60qconversions.h"
+#include <xqconversions.h>
 #include "conversationsengineutility.h"
 #include "unidatamodelloader.h"
 #include "unidatamodelplugininterface.h"
+#include "ringbc.h"
+#include "msgcontacthandler.h"
+#include "mmsconformancecheck.h"
 #include <ccsconversationentry.h>
+#include <fileprotectionresolver.h>
+
+#include "debugtraces.h"
+
 #include <QFile>
 #include <QFileInfo>
+#include <s32mem.h>
+#include <s32strm.h>
+#include <fbs.h>
+#include <ccsdefs.h>
 
-// LOCAL CONSTANTS
+//CONSTANTS
+_LIT(KDbFileName, "c:[2002A542]conversations.db");
+
+// preview sql query
+_LIT(KSelectConvMsgsStmt, "SELECT message_id, msg_processingstate, subject, body_text, preview_path, msg_property, preview_icon FROM conversation_messages WHERE message_id=:message_id ");
 
+//selecet preview-icon query
+_LIT(KSelectPreviewIconStmt,"SELECT  message_id, preview_icon FROM conversation_messages WHERE message_id = :message_id ");
+
+// preview-cache max cost (items)
+const int CACHE_COST =  50;
+//Preview thumbnail size
+const int KWidth = 9.5 * 6.7;
+const int KHeight = 9.5 * 6.7;
 //---------------------------------------------------------------
 // ConversationsModel::ConversationsModel
 // Constructor
 //---------------------------------------------------------------
 ConversationsModel::ConversationsModel(ConversationMsgStoreHandler* msgStoreHandler,
     QObject* parent) :
-    QStandardItemModel(parent), mMsgStoreHandler(msgStoreHandler)
+    QStandardItemModel(parent), mMsgStoreHandler(msgStoreHandler), iSqlDbOpen(EFalse)
 {
+    //Open SQL DB
+    if (KErrNone == iSqlDb.Open(KDbFileName))
+    {
+        iSqlDbOpen = ETrue;
+    }
+    previewIconCache.setMaxCost(CACHE_COST);
+
+    int err = connect(this, SIGNAL(retrievePreviewIcon(int, QString&)), this,
+        SLOT(updatePreviewIcon(int, QString&)));
+    QCRITICAL_WRITE_FORMAT("Error from connect()", err)
     iDataModelPluginLoader = new UniDataModelLoader;
     iMmsDataPlugin = iDataModelPluginLoader->getDataModelPlugin(ConvergedMessage::Mms);
     iBioMsgPlugin = iDataModelPluginLoader->getDataModelPlugin(ConvergedMessage::BioMsg);
@@ -48,6 +81,12 @@
 //---------------------------------------------------------------
 ConversationsModel::~ConversationsModel()
 {
+    //Close SQL-DB
+    iSqlDb.Close();
+
+	//clear preview-cache
+    previewIconCache.clear();
+
     if (iDataModelPluginLoader) {
         delete iDataModelPluginLoader;
         iDataModelPluginLoader = NULL;
@@ -128,6 +167,13 @@
         value = item->data(SendingState);
         break;
     }
+    case PreviewIcon:
+    {
+        QString filepath(item->data(Attachments).toString());
+        int msgId = item->data(ConvergedMsgId).toInt();
+        HbIcon *icon = getPreviewIconItem(msgId, filepath);
+        return *icon;
+    }
     case MessagePriority:
     {
         value = item->data(MessagePriority);
@@ -160,7 +206,7 @@
     }
     case DisplayName: // Fall through start
         value = item->data(DisplayName);
-        break;    
+        break;
     case Avatar: // Fall througn end
         value = item->data(Avatar);
         break;
@@ -244,6 +290,8 @@
 //---------------------------------------------------------------
 void ConversationsModel::populateItem(QStandardItem& item, const CCsConversationEntry& entry)
 {
+    QCRITICAL_WRITE("ConversationsModel::populateItem start.");
+
     int msgId = entry.EntryId();
     // id
     item.setData(msgId, ConvergedMsgId);
@@ -252,10 +300,10 @@
     HBufC* description = entry.Description();
     QString subject("");
     if (description && description->Length()) {
-        subject = (S60QConversions::s60DescToQString(*description));     
+        subject = (XQConversions::s60DescToQString(*description));     
     }
 
-    // time stamp 
+    // time stamp
     TTime unixEpoch(KUnixEpoch);
     TTimeIntervalSeconds seconds;
     TTime timeStamp(entry.TimeStamp());
@@ -265,7 +313,7 @@
     //contact details
     HBufC* contact = entry.Contact();
     if (contact && contact->Length()) {
-        item.setData(S60QConversions::s60DescToQString(*contact), ConversationAddress);
+        item.setData(XQConversions::s60DescToQString(*contact), ConversationAddress);
     }
 
     // message type.
@@ -302,9 +350,11 @@
         item.setData(ConvergedMessage::Outbox, MessageLocation);
     }
 
-    //message specific handling    
+    //message specific handling
     if (msgType == ConvergedMessage::Mms) {
+        QCRITICAL_WRITE("ConversationsModel::populateItem  MMS start.")
         handleMMS(item, entry);
+        QCRITICAL_WRITE("ConversationsModel::populateItem MMS end.")
     }
     else if(msgType == ConvergedMessage::MmsNotification) {
         item.setData(subject, Subject);
@@ -320,54 +370,282 @@
         // sms bodytext
         item.setData(subject, BodyText);
     }
+
+    QCRITICAL_WRITE("ConversationsModel::populateItem end.");
 }
 
 //---------------------------------------------------------------
+// ConversationsModel::validateMsgForForward
+// @see header file
+//---------------------------------------------------------------
+bool ConversationsModel::validateMsgForForward(qint32 messageId)
+{
+    bool retValue = true;
+    //Validate if the mms msg can be forwarded or not
+    MmsConformanceCheck* mmsConformanceCheck = new MmsConformanceCheck;
+    retValue = mmsConformanceCheck->validateMsgForForward(messageId);
+
+    delete mmsConformanceCheck;
+    return retValue;
+}
+
+
+//---------------------------------------------------------------
 // ConversationsModel::handleMMS
 // @see header
 //---------------------------------------------------------------
 void ConversationsModel::handleMMS(QStandardItem& item, const CCsConversationEntry& entry)
 {
-    iMmsDataPlugin->setMessageId(entry.EntryId());
-    if (iMmsDataPlugin->attachmentCount() > 0) {
-        item.setData(ConvergedMessage::Attachment, MessageProperty);
-    }
+    //msg_id
+    int msgId = entry.EntryId();
+
+    bool isEntryInDb = false;
+    TInt err = KErrNone;
+
+    //check if db is open and query db
+    if (iSqlDbOpen)
+    {
+        RSqlStatement sqlSelectStmt;
+        err = sqlSelectStmt.Prepare(iSqlDb, KSelectConvMsgsStmt);
+
+        // move to fallback option
+        if (KErrNone == err)
+            {
+            TInt msgIdIndex = sqlSelectStmt.ParameterIndex(_L(":message_id"));
+            TInt msgProcessingStateIndex = sqlSelectStmt.ColumnIndex(_L("msg_processingstate"));
+            TInt subjectIndex = sqlSelectStmt.ColumnIndex(_L("subject"));
+            TInt bodyIndex = sqlSelectStmt.ColumnIndex(_L("body_text"));
+            TInt previewPathIndex = sqlSelectStmt.ColumnIndex(
+                    _L("preview_path"));
+            TInt msgpropertyIndex = sqlSelectStmt.ColumnIndex(
+                _L("msg_property"));
+            TInt previewIconIndex = sqlSelectStmt.ColumnIndex(
+                _L("preview_icon"));
+
+            err = sqlSelectStmt.BindInt(msgIdIndex, msgId);
+
+            // populate item
+            if ((KErrNone == err) && (sqlSelectStmt.Next() == KSqlAtRow))
+                {
+                int msgProcessingState = 0;
+                msgProcessingState = sqlSelectStmt.ColumnInt(
+                        msgProcessingStateIndex);
+                if (msgProcessingState == EPreviewMsgProcessed)
+                    {
+                    // use entry to populate model only when,
+                    // entry is present in DB and its processing is over.
+                    RBuf subjectBuffer;
+                    subjectBuffer.Create(sqlSelectStmt.ColumnSize(
+                            subjectIndex));
+                    sqlSelectStmt.ColumnText(subjectIndex, subjectBuffer);
+
+                    item.setData(XQConversions::s60DescToQString(
+                            subjectBuffer), Subject);
+                    subjectBuffer.Close();
+
+                    RBuf bodyBuffer;
+                    bodyBuffer.Create(sqlSelectStmt.ColumnSize(bodyIndex));
+                    sqlSelectStmt.ColumnText(bodyIndex, bodyBuffer);
+
+                    item.setData(
+                            XQConversions::s60DescToQString(bodyBuffer),
+                            BodyText);
+                    bodyBuffer.Close();
+
+                    RBuf previewPathBuffer;
+                    previewPathBuffer.Create(sqlSelectStmt.ColumnSize(
+                            previewPathIndex));
+                    sqlSelectStmt.ColumnText(previewPathIndex,
+                            previewPathBuffer);
+
+                    //Rightnow set inside attachments
+                    QString attachmentPath(XQConversions::s60DescToQString(
+                            previewPathBuffer));
+
+                    item.setData(attachmentPath, Attachments);
+                    previewPathBuffer.Close();
+
+                    int msgProperty = 0;
+                    msgProperty = sqlSelectStmt.ColumnInt(msgpropertyIndex);
+                    item.setData(msgProperty, MessageProperty);
+
+                    RSqlColumnReadStream stream;
+                    //Get data from binary column BLOB
+                    TInt err = stream.ColumnBinary(sqlSelectStmt,
+                            previewIconIndex);
+
+                    QCRITICAL_WRITE_FORMAT("Error from ColumnBinary()", err)
 
-    int slideCount = iMmsDataPlugin->slideCount();
-    bool isBodyTextSet = false;
-    QString textContent;
-    QStringList attachmentPaths;
+                    if (err == KErrNone)
+                        {
+                        CFbsBitmap *bitmap = new CFbsBitmap;
+                        TRAPD(err,bitmap->InternalizeL(stream));
+                        QCRITICAL_WRITE_FORMAT("Error from bitmap InternalizeL()", err)
+
+                        //convert bitmap to pixmap
+                        if (err == KErrNone)
+                            {
+                            TSize size = bitmap->SizeInPixels();
+                            int bytesPerLine = bitmap->ScanLineLength(
+                                    size.iWidth, bitmap->DisplayMode());
+                            const uchar* dataPtr =
+                                    (const uchar*) bitmap->DataAddress();
+
+                            QPixmap pixmap = QPixmap::fromImage(QImage(
+                                    dataPtr, size.iWidth, size.iHeight,
+                                    bytesPerLine, QImage::Format_RGB16));
+
+                            setPreviewIcon(pixmap, attachmentPath, msgId,
+                                    true);
+
+                            }
+                        //remove bitmap
+                        delete bitmap;
+                        }
+
+                    //set flag to disable fallback option
+                    isEntryInDb = true;
+                    }
+                }
+            }
+        sqlSelectStmt.Close();
+        }
 
-    for (int i = 0; i < slideCount; ++i) {
-        UniMessageInfoList objectList = iMmsDataPlugin->slideContent(i);
-        for (int index = 0; index < objectList.count(); ++index) {
-            attachmentPaths.append(objectList[index]->path());
-            if (!isBodyTextSet && objectList[index]->mimetype().contains("text")) {
-                QFile file(objectList[index]->path());
-                if(file.open(QIODevice::ReadOnly))
+    //fallback option incase of db operation failure or enry not found in DB
+    //populate from data plugins
+    if (!isEntryInDb || err != KErrNone)
+    {
+        int id = iMmsDataPlugin->setMessageId(entry.EntryId());
+        if(id <= 0)
+        {
+            // skip all
+            return;
+        }
+        int msgProperty = 0;
+
+        if (iMmsDataPlugin->attachmentCount() > 0)
+        {
+            msgProperty |= EPreviewAttachment;
+        }
+
+        if(validateMsgForForward(entry.EntryId()))
+        {
+            msgProperty |= EPreviewForward;
+        }
+
+        //subject
+        item.setData(iMmsDataPlugin->subject(), Subject);
+
+        int slideCount = iMmsDataPlugin->slideCount();
+        bool isBodyTextSet = false;
+        bool isAudioSet = false;
+        bool isImageSet = false;
+        bool isVideoSet = false;
+        QString textContent;
+        QString videoPath;
+        QString imagePath;
+
+        for (int i = 0; i < slideCount; ++i)
+        {
+            UniMessageInfoList objectList = iMmsDataPlugin->slideContent(i);
+            for (int index = 0; index < objectList.count(); ++index)
+            {
+                if (!isBodyTextSet && objectList[index]->mimetype().contains(
+                    "text"))
                 {
+                    QFile file(objectList[index]->path());
+                    file.open(QIODevice::ReadOnly);
                     textContent = file.readAll();
                     item.setData(textContent, BodyText);
                     isBodyTextSet = true;
                     file.close();
                 }
+                if (!isVideoSet && !isImageSet && objectList[index]->mimetype().contains(
+                    "image"))
+                {
+                    isImageSet = true;
+                    msgProperty |= EPreviewImage;
+                    if (objectList[index]->isProtected())
+                    {
+                        msgProperty |= EPreviewProtectedImage;
+                    }
+                    if (objectList[index]->isCorrupted())
+                    {
+                        msgProperty |= EPreviewCorruptedImage;
+                    }
+                    imagePath = objectList[index]->path();
+                }
+                if (!isVideoSet && !isAudioSet && objectList[index]->mimetype().contains(
+                    "audio"))
+                {
+                    msgProperty |= EPreviewAudio;
+                    if (objectList[index]->isProtected())
+                    {
+                        msgProperty |= EPreviewProtectedAudio;
+                    }
+                    if (objectList[index]->isCorrupted())
+                    {
+                        msgProperty |= EPreviewCorruptedAudio;
+                    }
+                    isAudioSet = true;
+                }
+                if (!( isImageSet || isAudioSet) && !isVideoSet && objectList[index]->mimetype().contains(
+                    "video"))
+                {
+                    isVideoSet = true;
+                    msgProperty |= EPreviewVideo;
+                    if (objectList[index]->isProtected())
+                    {
+                        msgProperty |= EPreviewProtectedVideo;
+                    }
+                    if (objectList[index]->isCorrupted())
+                    {
+                        msgProperty |= EPreviewCorruptedVideo;
+                    }
+                    videoPath = objectList[index]->path();
+                }
+            }
+            foreach(UniMessageInfo* slide,objectList)
+                {
+                    delete slide;
+                }
+        }
+        QPixmap pixmap;
+        //populate item  with the attachment list
+        //TODO: This code is not required bcoz video icon is show and not preview  
+        if (isVideoSet)
+        {
+            item.setData(videoPath, Attachments);
+            // Store thumbnail only for non protected, non corrupted content.
+            if (!(EPreviewProtectedVideo & msgProperty) &&
+                !(EPreviewCorruptedVideo & msgProperty))
+            {
+                setPreviewIcon(pixmap, videoPath, msgId, false);
             }
         }
-        foreach(UniMessageInfo* slide,objectList)
+        else if (isImageSet)
+        {
+            item.setData(imagePath, Attachments);
+            // Store thumbnail only for non protected, non corrupted content.
+            if (!(EPreviewProtectedImage & msgProperty) &&
+                !(EPreviewCorruptedImage & msgProperty))
             {
-                delete slide;
+                setPreviewIcon(pixmap, imagePath, msgId, false);
             }
+        }
+        //populate msgProperty
+        item.setData(msgProperty, MessageProperty);
     }
-    //populate item  with the attachment list
-    item.setData(attachmentPaths.join("|"), Attachments);
-    if (entry.IsAttributeSet(ECsAttributeHighPriority)) {
+
+    // fill other attributes
+    if (entry.IsAttributeSet(ECsAttributeHighPriority))
+    {
         item.setData(ConvergedMessage::High, MessagePriority);
     }
-    else if (entry.IsAttributeSet(ECsAttributeLowPriority)) {
+    else if (entry.IsAttributeSet(ECsAttributeLowPriority))
+    {
         item.setData(ConvergedMessage::Low, MessagePriority);
     }
-    //subject
-    item.setData(iMmsDataPlugin->subject(), Subject);
 }
 
 //---------------------------------------------------------------
@@ -378,27 +656,33 @@
     const CCsConversationEntry& entry)
 {
     // set context to current entry
-    mMsgStoreHandler->setNotificationMessageId(entry.EntryId());
-    
+    TRAPD(err, mMsgStoreHandler->setNotificationMessageIdL(entry.EntryId()));
+    if(err != KErrNone)
+    {
+        return;
+    }
+
     // fetch relevent info to show in CV
     // msg size
-    QString estimatedMsgSizeStr = 
-            mMsgStoreHandler->NotificationMsgSize();
-    
+    QString estimatedMsgSizeStr = QString("%1").arg(0);
+    estimatedMsgSizeStr.append(" Kb");
+    TRAP_IGNORE(estimatedMsgSizeStr =
+            mMsgStoreHandler->NotificationMsgSizeL());
+
     // msg class type
     QString classInfoStr = mMsgStoreHandler->NotificationClass();
-    
+
     // notification expiry date
     //TODO: Need to do localization of digits used to show expiry time
     TTime expiryTime;
     QString expiryTimeStr;
     mMsgStoreHandler->NotificationExpiryDate(expiryTime, expiryTimeStr);
-    
+
     // notification state e.g. waiting, retrieving etc
     QString statusStr;
     int status;
     mMsgStoreHandler->NotificationStatus(status, statusStr);
-    
+
     // create data for bodytext role
     QString dataText;
     dataText.append("Size: "); // TODO: use logical str name
@@ -437,7 +721,7 @@
 {
     //TODO, needs to be revisited again, once BT team provides the solution for
     //BT received as Biomsg issue.
-    QString description = S60QConversions::s60DescToQString(*(entry.Description()));
+    QString description = XQConversions::s60DescToQString(*(entry.Description()));
 
     if (description.contains(".vcf") || description.contains(".ics")) // "vCard"
     {
@@ -445,10 +729,11 @@
         item.setData(ConvergedMessage::VCard, MessageSubType);
 
         //parse vcf file to get the details
-        QString displayName = ConversationsEngineUtility::getVcardDisplayName(description);
+        QString displayName = MsgContactHandler::getVCardDisplayName(
+                description);
         item.setData(displayName, BodyText);
-    }    
-    else 
+    }
+    else
     {
         if (description.contains(".vcs")) // "vCalendar"
         {
@@ -482,8 +767,11 @@
             QString attachmentPath = attList[0]->path();
 
             //get display-name and set as bodytext
-            QString displayName = ConversationsEngineUtility::getVcardDisplayName(attachmentPath);
+            QString displayName =
+                    MsgContactHandler::getVCardDisplayName(
+                            attachmentPath);
             item.setData(displayName, BodyText);
+            item.setData(attachmentPath, Attachments);
 
             // clear attachement list : its allocated at data model
             while (!attList.isEmpty()) {
@@ -494,15 +782,198 @@
     else if (ConvergedMessage::VCal == msgSubType) {
         //not supported
     }
+    else if (ConvergedMessage::RingingTone == msgSubType) {
+        if (iBioMsgPlugin->attachmentCount() > 0) {
+            UniMessageInfoList attList = iBioMsgPlugin->attachmentList();
+            QString attachmentPath = attList[0]->path();
+
+            //get tone title, and set as bodytext
+            RingBc ringBc;
+            item.setData(ringBc.toneTitle(attachmentPath), BodyText);
+            while (!attList.isEmpty()) {
+                delete attList.takeFirst();
+            }
+        }
+
+    }
     else {
         // description
         HBufC* description = entry.Description();
         QString subject("");
         if (description && description->Length()) {
-            subject = (S60QConversions::s60DescToQString(*description));
+            subject = (XQConversions::s60DescToQString(*description));
             item.setData(subject, BodyText);
         }
     }
 }
 
+//---------------------------------------------------------------
+// ConversationsModel::getDBHandle()
+// @see header
+//---------------------------------------------------------------
+RSqlDatabase& ConversationsModel::getDBHandle(TBool& isOpen)
+{
+    isOpen = iSqlDbOpen;
+    return iSqlDb;
+}
+
+//---------------------------------------------------------------
+// ConversationsModel::setPreviewIcon()
+// @see header
+//---------------------------------------------------------------
+void ConversationsModel::setPreviewIcon(QPixmap& pixmap, QString& filePath,
+    int msgId, bool inDb)
+{
+
+    //Since the population happens in reverse this check is needed so that
+    //most recent items have their icons present in cache
+    if (previewIconCache.totalCost() >= previewIconCache.maxCost())
+        return;
+
+    // if not found in db, set from file path
+    if (!inDb)
+    {
+        QPixmap pixmap(filePath);
+        QPixmap scaledPixmap = pixmap.scaled(KWidth, KHeight, Qt::IgnoreAspectRatio);
+        HbIcon *previewIcon = new HbIcon(scaledPixmap);
+
+        previewIconCache.insert(msgId, previewIcon);
+
+    }
+    else
+    {
+        HbIcon *previewIcon = new HbIcon(pixmap);
+        previewIconCache.insert(msgId, previewIcon);
+    }
+}
+
+//---------------------------------------------------------------
+// ConversationsModel::getPreviewIconItem()
+// @see header
+//---------------------------------------------------------------
+HbIcon* ConversationsModel::getPreviewIconItem(int msgId,
+    QString& filepath) const
+{
+    QCRITICAL_WRITE("ConversationsModel::getPreviewIconItem start.")
+
+    //Initialize icon from the Cache will be NULL if Item not present
+    HbIcon* previewIcon = previewIconCache[msgId];
+    if (!previewIcon)
+    {
+        //This is done in this way as non-const function call cant be done here
+        emit retrievePreviewIcon(msgId, filepath);
+
+        previewIcon = previewIconCache[msgId];
+    }
+
+    QCRITICAL_WRITE("ConversationsModel::getPreviewIconItem start.")
+
+    return previewIcon;
+}
+
+//---------------------------------------------------------------
+// ConversationsModel::updatePreviewIcon()
+// @see header
+//---------------------------------------------------------------
+void ConversationsModel::updatePreviewIcon(int msgId, QString& filePath)
+{
+    QCRITICAL_WRITE("ConversationsModel::updatePreviewIcon start.")
+
+    //sql query to get preview-icon from DB
+    bool imagePreviewed = false;
+    QPixmap pixmap;
+
+    if (iSqlDbOpen)
+    {
+        RSqlStatement sqlSelectPreviewIconStmt;
+        TInt err = sqlSelectPreviewIconStmt.Prepare(iSqlDb,
+            KSelectPreviewIconStmt);
+
+        QCRITICAL_WRITE_FORMAT("Error from Prepare()", err)
+
+        if (err == KErrNone)
+        {
+            //msg_id
+            TInt msgIdIndex = sqlSelectPreviewIconStmt.ParameterIndex(
+                _L(":message_id"));
+            sqlSelectPreviewIconStmt.BindInt(msgIdIndex, msgId);
+
+            // get preview-icon from DB
+            err = sqlSelectPreviewIconStmt.Next();
+            QCRITICAL_WRITE_FORMAT("Error from Next()", err)
+
+            if (err == KSqlAtRow)
+            {
+                TInt previewIconIndex = sqlSelectPreviewIconStmt.ColumnIndex(
+                    _L("preview_icon"));
+
+                RSqlColumnReadStream stream;
+
+                //Get data from binary column BLOB
+                err = stream.ColumnBinary(sqlSelectPreviewIconStmt,
+                    previewIconIndex);
+
+                QCRITICAL_WRITE_FORMAT("Error from ColumnBinary()", err)
+
+                if (err == KErrNone)
+                {
+                    CFbsBitmap *bitmap = new CFbsBitmap;
+                    TRAPD(err,bitmap->InternalizeL(stream));
+                    QCRITICAL_WRITE_FORMAT("Error from bitmap InternalizeL()", err)
+
+                    //convert bitmap to pixmap
+                    if (err == KErrNone)
+                    {
+                        TSize size = bitmap->SizeInPixels();
+                        int bytesPerLine = bitmap->ScanLineLength(size.iWidth,
+                            bitmap->DisplayMode());
+                        const uchar* dataPtr =
+                                (const uchar*) bitmap->DataAddress();
+
+                        pixmap = QPixmap::fromImage(QImage(dataPtr,
+                            size.iWidth, size.iHeight, bytesPerLine,
+                            QImage::Format_RGB16));
+
+                        imagePreviewed = true;
+
+                        QCRITICAL_WRITE("Bitmap Conversion completed")
+                    }
+                    //remove bitmap
+                    delete bitmap;
+                }
+                //close stream
+                stream.Close();
+            }
+        }
+        sqlSelectPreviewIconStmt.Close();
+    }
+
+    // if not found in db, set from file path
+    if (!imagePreviewed)
+    {
+        QPixmap orgPixmap(filePath);
+        pixmap = orgPixmap.scaled(63.65, 63.65, Qt::IgnoreAspectRatio);
+    }
+    HbIcon * previewIcon = new HbIcon(pixmap);
+
+    previewIconCache.insert(msgId, previewIcon);
+
+    QCRITICAL_WRITE("ConversationsModel::updatePreviewIcon end.")
+
+}
+
+//---------------------------------------------------------------
+// ConversationsModel::clearModel()
+// @see header
+//---------------------------------------------------------------
+void ConversationsModel::clearModel()
+{
+    clear();
+    previewIconCache.clear();
+}
+
+void ConversationsModel:: emitConversationViewEmpty()
+{
+    emit conversationViewEmpty();
+}
 //EOF