phonebookui/cnthistorymodel/src/cnthistorymodel.cpp
changeset 31 2a11b5b00470
parent 27 de1630741fbe
child 37 fd64c38c277d
equal deleted inserted replaced
27:de1630741fbe 31:2a11b5b00470
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 #include <QStringList>
    18 #include <QStringList>
    19 #include <QtAlgorithms>
    19 #include <QtAlgorithms>
    20 #include <HbGlobal>
    20 #include <hbglobal.h>
    21 #include <msgitem.h>
    21 #include <hbicon.h>
       
    22 #include <hbframebackground.h>
    22 
    23 
    23 #include "cnthistorymodel_p.h"
    24 #include "cnthistorymodel_p.h"
    24 #include "cnthistorymodel.h"
    25 #include "cnthistorymodel.h"
    25 
    26 
    26 // Unnamed namespace for helper functions
    27 // Unnamed namespace for helper functions
    27 namespace
    28 namespace
    28 {
    29 {
    29     bool greaterThan(const HItemPointer& t1, const HItemPointer& t2)
    30     bool greaterThan(const HItemPointer& t1, const HItemPointer& t2)
    30     {
    31     {
    31         return t1.data()->timeStamp > t2.data()->timeStamp;
    32         return ((*t1).timeStamp > (*t2).timeStamp);
    32     }
    33     }
    33     
    34     
    34     bool lessThan(const HItemPointer& t1, const HItemPointer& t2)
    35     bool lessThan(const HItemPointer& t1, const HItemPointer& t2)
    35     {
    36     {
    36         return t1.data()->timeStamp < t2.data()->timeStamp;
    37         return ((*t1).timeStamp < (*t2).timeStamp);
    37     }
    38     }
    38 }
    39 }
    39 
    40 
    40 Q_DECLARE_METATYPE(LogsEvent *)
    41 Q_DECLARE_METATYPE(LogsEvent *)
    41 
    42 
    52                                  QObject *parent)
    53                                  QObject *parent)
    53     : QAbstractListModel(parent)
    54     : QAbstractListModel(parent)
    54 {
    55 {
    55     d = new CntHistoryModelData(contactId, manager);
    56     d = new CntHistoryModelData(contactId, manager);
    56     
    57     
    57     // Check if the contact is my card
       
    58     if (d->m_contactId == d->m_contactManager->selfContactId()) {
       
    59         d->m_isMyCard = true;
       
    60     }
       
    61     else {
       
    62         d->m_isMyCard = false;
       
    63     }
       
    64     // Create the model structure and cache history data from the databases
    58     // Create the model structure and cache history data from the databases
    65     initializeModel();
    59     initializeModel();
    66 
       
    67 }
    60 }
    68 
    61 
    69 CntHistoryModel::~CntHistoryModel()
    62 CntHistoryModel::~CntHistoryModel()
    70 {
    63 {
    71 }
    64 }
    93     switch( role )
    86     switch( role )
    94     {       
    87     {       
    95         case Qt::DisplayRole:
    88         case Qt::DisplayRole:
    96             return displayRoleData(*p);
    89             return displayRoleData(*p);
    97         case Qt::DecorationRole:
    90         case Qt::DecorationRole:
    98             return QVariant((*p).iconPath);
    91             return decorationRoleData(*p);
    99         case SeenStatusRole:
    92         case Qt::BackgroundRole:
   100             return QVariant((*p).seenStatus);
    93             return backgroundRoleData(*p);
   101         case DirectionRole:
    94         case FlagsRole:
   102             return QVariant((*p).direction);
    95             return QVariant((*p).flags);
   103         case ItemTypeRole:
       
   104             return QVariant((*p).msgType);
       
   105         case PhoneNumberRole:
    96         case PhoneNumberRole:
   106             return QVariant((*p).number);
    97             return QVariant((*p).number);
   107         default:
    98         default:
   108             return QVariant();
    99             return QVariant();
   109     }
   100     }
   110 }
   101 }
   111 
   102 
   112 /*!
   103 /*!
   113  * Return the data to be used by the view for a display role.
   104  * Return the data to be used by the view for a display role.
   114  *
   105  *
   115  * \param column The column of the item to return data about.
   106  * \param item The History item to return data about.
   116  *  return QVariant List of strings to be displayed on the view.
   107  *  return QVariant List of strings to be displayed on the view.
   117  *  The stings can also be NULL
   108  *  The stings can also be NULL
   118  *  index 0 Title of the conversation item.
   109  *  index 0 Title of the conversation item.
   119  *  index 1 Body text
   110  *  index 1 Body text
   120  *  index 2 Time stamp
   111  *  index 2 Time stamp
   121  */
   112  */
   122 QVariant CntHistoryModel::displayRoleData(const HistoryItem& item) const
   113 QVariant CntHistoryModel::displayRoleData(const HistoryItem& item) const
   123 {
   114 {
   124     QStringList list;
   115     QStringList list;
   125     
   116     
   126     list << item.title << item.message << item.timeStamp.toString();
   117     if (item.timeStamp.date() == QDateTime::currentDateTime().date())
       
   118     {
       
   119         list << item.title << item.message << item.timeStamp.toString(TIME_FORMAT);
       
   120     }
       
   121     else
       
   122     {
       
   123         list << item.title << item.message << item.timeStamp.toString(DATE_FORMAT);
       
   124     }
   127     
   125     
   128     return QVariant(list);
   126     return QVariant(list);
       
   127 }
       
   128 
       
   129 /*!
       
   130  * Return the data to be used by the view for a decoration role.
       
   131  *
       
   132  * \param item The History item to return data about.
       
   133  *  return QVariant String of the icon path.
       
   134  */
       
   135 QVariant CntHistoryModel::decorationRoleData(const HistoryItem& item) const
       
   136 {
       
   137     // Messages
       
   138     if (item.flags & Message)
       
   139         return QVariant(HbIcon(MESSAGE_ICON));
       
   140     
       
   141     // Call logs
       
   142     if (item.flags & CallLog) {
       
   143         if (item.flags & MissedCall)
       
   144             return QVariant(HbIcon(MISSED_CALL_ICON));
       
   145         if (item.flags & DialledCall)
       
   146             return QVariant(HbIcon(DAILED_CALL_ICON));
       
   147         if (item.flags & ReceivedCall)
       
   148             return QVariant(HbIcon(RECEIVED_CALL_ICON));
       
   149     }
       
   150     
       
   151     return QVariant();
       
   152 }
       
   153 
       
   154 /*!
       
   155  * Return the data to be used to draw the background of list items
       
   156  *
       
   157  * \param item The History item to return data about.
       
   158  *  return QVariant HbFrameBackground of the list item.
       
   159  */
       
   160 QVariant CntHistoryModel::backgroundRoleData(const HistoryItem& item) const
       
   161 {
       
   162     if (item.flags & Incoming)
       
   163         return QVariant(HbFrameBackground("qtg_fr_convlist_received_normal", HbFrameDrawer::NinePieces));
       
   164     else
       
   165         return QVariant(HbFrameBackground("qtg_fr_convlist_sent_normal", HbFrameDrawer::NinePieces));
   129 }
   166 }
   130 
   167 
   131 /*!
   168 /*!
   132  * Get the number of rows (conversations) in this model.
   169  * Get the number of rows (conversations) in this model.
   133  *
   170  *
   157  * Clear history from the database. If the history cached
   194  * Clear history from the database. If the history cached
   158  * is specific to one contact, only that history is cleared.
   195  * is specific to one contact, only that history is cleared.
   159  * 
   196  * 
   160  */
   197  */
   161 void CntHistoryModel::clearHistory()
   198 void CntHistoryModel::clearHistory()
   162 {
   199 {    
   163     if ( d->m_List.isEmpty() )
   200     if ( d->m_List.isEmpty() )
   164         return;
   201         return;
   165     
   202     
   166     // Call logs
   203     // Call logs
   167     if ( !d->m_isMyCard && d->m_logsFilter ) {
   204     if ( !d->m_isMyCard && d->m_logsFilter )
   168         if ( !d->m_logsFilter->clearEvents() ) {
   205         d->m_logsFilter->clearEvents();
   169             // Operation not async
   206     else if ( d->m_logsModel )
   170             clearedCallLogs( 0 );
   207         d->m_logsModel->clearList(LogsModel::TypeLogsClearAll);
   171         }
       
   172     } else if ( d->m_logsModel ) {
       
   173         if ( !d->m_logsModel->clearList(LogsModel::TypeLogsClearAll) ) {
       
   174             // Operation not async
       
   175             clearedCallLogs( 0 );
       
   176         }
       
   177     }
       
   178     
   208     
   179     // Messages
   209     // Messages
   180     d->m_msgHistory->clearMessages( (int)d->m_contactId );    
   210     if (d->m_msgHistory)
       
   211         d->m_msgHistory->clearMessages( (int)d->m_contactId );
       
   212     
       
   213     // Clear all data from the history model.
       
   214     int count = rowCount();
       
   215     d->m_List.clear();
       
   216     d->m_msgMap.clear();
       
   217     d->m_logsMap.clear();
       
   218     beginRemoveRows( QModelIndex(), 0, count );
       
   219     endRemoveRows();
   181 }
   220 }
   182 
   221 
   183 /*!
   222 /*!
   184  * Mark all the conversations in the view as seen.
   223  * Mark all the conversations in the view as seen.
   185  * 
   224  * 
   187 void CntHistoryModel::markAllAsSeen()
   226 void CntHistoryModel::markAllAsSeen()
   188 {
   227 {
   189     if ( d->m_isMarkedAsSeen )
   228     if ( d->m_isMarkedAsSeen )
   190         return;
   229         return;
   191     
   230     
   192     // Call logs
       
   193     if ( !d->m_isMyCard && d->m_logsFilter ) {
       
   194         d->m_logsFilter->markEventsSeen();
       
   195     } else if ( d->m_logsModel ) {
       
   196         d->m_logsModel->markEventsSeen(LogsModel::TypeLogsClearMissed);
       
   197     }
       
   198     
       
   199     // Messages
   231     // Messages
   200     d->m_msgHistory->markRead( (int)d->m_contactId );
   232     if (d->m_msgHistory->markRead( d->m_contactId ))
   201     
   233         d->m_isMarkedAsSeen = true;
   202     d->m_isMarkedAsSeen = true;
       
   203 }
   234 }
   204 
   235 
   205 /*!
   236 /*!
   206  * Sort items in the model and refresh the view
   237  * Sort items in the model and refresh the view
   207  * 
   238  * 
   208  */
   239  */
   209 void CntHistoryModel::sortAndRefresh(Qt::SortOrder order)
   240 void CntHistoryModel::sortAndRefresh(Qt::SortOrder order)
   210 {
   241 {
   211     sort(0, order);
   242     sort(0, order);
   212     emit layoutChanged();
   243     beginInsertRows(QModelIndex(), 0, rowCount());
       
   244     endInsertRows();
   213 }
   245 }
   214 
   246 
   215 /*!
   247 /*!
   216  * Create the model structure and cache history data from
   248  * Create the model structure and cache history data from
   217  * conversations and call logs databases.
   249  * conversations and call logs databases.
   223     initializeMsgModel();
   255     initializeMsgModel();
   224 }
   256 }
   225 
   257 
   226 void CntHistoryModel::initializeMsgModel()
   258 void CntHistoryModel::initializeMsgModel()
   227 {
   259 {
       
   260     if( d->m_isMyCard )
       
   261         return;
       
   262     
       
   263     // Contact centric
   228     MsgHistory* m = new MsgHistory();
   264     MsgHistory* m = new MsgHistory();
       
   265     
       
   266     d->m_msgHistory = m;
   229     
   267     
   230     // Connect to signals emitted by msg model
   268     // Connect to signals emitted by msg model
   231     connect(m, SIGNAL(messagesReady(QList<MsgItem>& )), this, SLOT(messagesReady(QList<MsgItem>& )));
   269     connect(m, SIGNAL(messagesReady(QList<MsgItem>& )), this, SLOT(messagesReady(QList<MsgItem>& )));
   232     connect(m, SIGNAL(messageAdded(MsgItem& )), this, SLOT(messageAdded(MsgItem& )));
   270     connect(m, SIGNAL(messageAdded(MsgItem& )), this, SLOT(messageAdded(MsgItem& )));
   233     connect(m, SIGNAL(messageChanged(MsgItem& )), this, SLOT(messageChanged(MsgItem& )));
   271     connect(m, SIGNAL(messageChanged(MsgItem& )), this, SLOT(messageChanged(MsgItem& )));
   234     connect(m, SIGNAL(messageDeleted(MsgItem& )), this, SLOT(messageDeleted(MsgItem& )));
   272     connect(m, SIGNAL(messageDeleted(MsgItem& )), this, SLOT(messageDeleted(MsgItem& )));
   235     
   273     
   236     // Contact centric
   274     // Subscribe to get new messages
   237     if( !d->m_isMyCard ) {
   275     // received from this contact
   238         // Subscribe to get new messages
   276     m->subscribe(d->m_contactId);
   239         // received from this contact
   277     
   240         m->subscribe(d->m_contactId);
   278     // Initial fetch of all messages
   241         
   279     m->getMessages(d->m_contactId);
   242         // Initial fetch of all messages
       
   243         m->getMessages(d->m_contactId);
       
   244     }
       
   245     
       
   246     d->m_msgHistory = m;
       
   247 }
   280 }
   248 
   281 
   249 void CntHistoryModel::initializeLogsModel()
   282 void CntHistoryModel::initializeLogsModel()
   250 {
   283 {
   251     //populate model with call events
   284     //populate model with call events
   257         d->m_logsFilter->setSourceModel(d->m_logsModel);
   290         d->m_logsFilter->setSourceModel(d->m_logsModel);
   258         d->m_AbstractLogsModel = d->m_logsFilter;
   291         d->m_AbstractLogsModel = d->m_logsFilter;
   259         
   292         
   260         connect(d->m_logsFilter, SIGNAL(clearingCompleted(int)), 
   293         connect(d->m_logsFilter, SIGNAL(clearingCompleted(int)), 
   261                     this, SLOT(clearedCallLogs(int)));
   294                     this, SLOT(clearedCallLogs(int)));
   262         connect(d->m_logsFilter, SIGNAL(markingCompleted(int)), 
       
   263                     this, SLOT(markingCompleted(int)));
       
   264     } else {
   295     } else {
   265         //get all call events
   296         //get all call events
   266         d->m_AbstractLogsModel = d->m_logsModel;
   297         d->m_AbstractLogsModel = d->m_logsModel;
   267         
   298         
   268         connect(d->m_logsModel, SIGNAL(clearingCompleted(int)), 
   299         connect(d->m_logsModel, SIGNAL(clearingCompleted(int)), 
   269                     this, SLOT(clearedCallLogs(int)));
   300                     this, SLOT(clearedCallLogs(int)));
   270         connect(d->m_logsModel, SIGNAL(markingCompleted(int)), 
   301     }
   271                     this, SLOT(markingCompleted(int)));
   302     
   272     }
   303     //read first call events if any and start listening for more 
   273     
       
   274     //read first call events and start listening for more 
       
   275     for ( int i = 0; i < d->m_AbstractLogsModel->rowCount(); ++i ) {
   304     for ( int i = 0; i < d->m_AbstractLogsModel->rowCount(); ++i ) {
   276         LogsEvent* event = qVariantValue<LogsEvent*>(
   305         LogsEvent* event = qVariantValue<LogsEvent*>(
   277                 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) );
   306                 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) );
   278         
   307         
   279         if ( event ) {
   308         if ( event ) {
   298  *
   327  *
   299  * \param event Call log event
   328  * \param event Call log event
   300  * \param item Conversation history item
   329  * \param item Conversation history item
   301  */
   330  */
   302 void CntHistoryModel::readLogEvent(LogsEvent* event, HistoryItem& item)
   331 void CntHistoryModel::readLogEvent(LogsEvent* event, HistoryItem& item)
   303 {
   332 {    
   304     QString bodyText;
   333     QString bodyText;
   305     QString icon;
       
   306     QString title;
   334     QString title;
   307     
   335     
   308     if ( d->m_isMyCard ) {
   336     if ( d->m_isMyCard ) {
   309         if ( event->remoteParty().length() > 0 ) {
   337         if ( event->remoteParty().length() > 0 ) {
   310             title = event->remoteParty();
   338             title = QString(event->remoteParty());
   311         }
   339         }
   312         else {
   340         else {
   313             title = event->number();
   341             title = QString(event->number());
   314         }
   342         }
   315     } else {
   343     } else {
   316         if ( event->direction() == LogsEvent::DirIn ) {
   344         if ( event->direction() == LogsEvent::DirIn ) {
   317             bodyText = hbTrId("txt_phob_list_received");
   345             bodyText = hbTrId("txt_phob_list_received");
   318             icon = QString("qtg_small_received");
   346             item.flags |= ReceivedCall;
   319         } else if ( event->direction() == LogsEvent::DirOut ) {
   347         } else if ( event->direction() == LogsEvent::DirOut ) {
   320             bodyText = hbTrId("txt_phob_list_dialled_call");
   348             bodyText = hbTrId("txt_phob_list_dialled_call");
   321             icon = QString("qtg_small_sent");
   349             item.flags |= DialledCall;
   322         } else if ( event->direction() == LogsEvent::DirMissed ) {
   350         } else if ( event->direction() == LogsEvent::DirMissed ) {
   323             bodyText = hbTrId("txt_phob_list_missed_call");
   351             bodyText = hbTrId("txt_phob_list_missed_call");
   324             icon = QString("qtg_small_missed_call");
   352             item.flags |= MissedCall;
   325             if ( !event->isRead() )
       
   326                 item.seenStatus = Unseen;
       
   327         }
   353         }
   328     }
   354     }
   329 
   355 
   330     if ( event->direction() == LogsEvent::DirOut )
   356     if ( event->direction() == LogsEvent::DirOut )
   331         item.direction = Outgoing;
   357         item.flags |= Outgoing;
   332     else
   358     else
   333         item.direction = Incoming;
   359         item.flags |= Incoming;
   334     
   360     
   335     item.message = bodyText;
   361     item.message = bodyText;
   336     item.iconPath = icon;
       
   337     item.title = title;
   362     item.title = title;
   338     item.timeStamp = event->time();
   363     item.timeStamp = event->time().toLocalTime();
   339     item.msgType = CallLog;
   364     item.flags |= CallLog;
   340     item.number = event->number();
   365     item.number = QString(event->number());
   341 }
   366 }
   342 
   367 
   343 /*!
   368 /*!
   344  * Slot used for receiving new rows from the LogsModel.
   369  * Slot used for receiving new rows from the LogsModel.
   345  *
   370  *
   348  * \param last The last row item to be received from the model.
   373  * \param last The last row item to be received from the model.
   349  */
   374  */
   350 void CntHistoryModel::logsRowsInserted(const QModelIndex& /*parent*/, int first, int last)
   375 void CntHistoryModel::logsRowsInserted(const QModelIndex& /*parent*/, int first, int last)
   351 {
   376 {
   352     int oldRowCount = rowCount();
   377     int oldRowCount = rowCount();
       
   378     QList<HItemPointer> l;
   353     
   379     
   354     for ( int i = first; i < d->m_AbstractLogsModel->rowCount() && i <= last; ++i ) {
   380     for ( int i = first; i < d->m_AbstractLogsModel->rowCount() && i <= last; ++i ) {
   355         LogsEvent* event = qVariantValue<LogsEvent*>(
   381         LogsEvent* event = qVariantValue<LogsEvent*>(
   356                 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) );
   382                 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) );
   357         
   383         
   361             d->m_logsMap.insert(i, item);
   387             d->m_logsMap.insert(i, item);
   362             d->m_List.append( item );
   388             d->m_List.append( item );
   363         }
   389         }
   364     }
   390     }
   365     
   391     
       
   392     // Check if this is the first time to receive events
       
   393     // and sort the entire list.
       
   394     if ( !d->m_initLogs ) {
       
   395         sort();
       
   396         oldRowCount = 0;
       
   397         d->m_initLogs = true;
       
   398     }
       
   399     
   366     beginInsertRows(QModelIndex(), oldRowCount, rowCount());
   400     beginInsertRows(QModelIndex(), oldRowCount, rowCount());
   367     endInsertRows();
   401     endInsertRows();
   368 }
   402 }
   369 
   403 
   370 /*!
   404 /*!
   379     QList< int > indices;
   413     QList< int > indices;
   380     
   414     
   381     for ( int i = first; i <= last; ++i ) {
   415     for ( int i = first; i <= last; ++i ) {
   382         HItemPointer item = d->m_logsMap.value( i );
   416         HItemPointer item = d->m_logsMap.value( i );
   383         int index = d->m_List.indexOf( item );
   417         int index = d->m_List.indexOf( item );
   384         d->m_List.removeOne( item );
   418         if ( index > -1 ) {
   385         d->m_logsMap.remove( i );        
   419             d->m_List.removeAt( index );
   386         indices.append( index );
   420             d->m_logsMap.remove( i );        
       
   421             indices.append( index );
       
   422         }
   387     }
   423     }
   388     
   424     
   389     // Remove list items in batches
   425     // Remove list items in batches
   390     if ( !indices.isEmpty() ) {
   426     if ( !indices.isEmpty() ) {
   391         QList< QList<int> > batches = findIndices(indices);
   427         QList< QList<int> > batches = findIndices(indices);
   432             emit dataChanged( index(l.first(), 0), index(l.last(), 0) );
   468             emit dataChanged( index(l.first(), 0), index(l.last(), 0) );
   433     }
   469     }
   434 }
   470 }
   435 
   471 
   436 /*!
   472 /*!
   437  * Clear logs event slot received from logs model
       
   438  *
       
   439  * \param err Error of the clear logs request
       
   440  */
       
   441 void CntHistoryModel::clearedCallLogs(int err)
       
   442 {
       
   443     if ( err != 0 ) {
       
   444         return;
       
   445     }
       
   446     
       
   447     QList< int > indices;
       
   448     foreach( HItemPointer p, d->m_logsMap.values() ) {
       
   449         d->m_List.removeOne( p );
       
   450     }
       
   451     d->m_logsMap.clear();
       
   452     
       
   453     // Remove list items in batches
       
   454     if ( !indices.isEmpty() ) {
       
   455         QList< QList<int> > batches = findIndices(indices);
       
   456         foreach( QList<int> l, batches ) {
       
   457             beginRemoveRows( QModelIndex(), l.first(), l.last() );
       
   458             endRemoveRows();
       
   459         }
       
   460     }
       
   461 }
       
   462 
       
   463 /*!
       
   464  * Mark events as seen slot received from logs model
       
   465  *
       
   466  * \param err Error of the marking logs request
       
   467  */
       
   468 void CntHistoryModel::markingCompleted(int err)
       
   469 {
       
   470     if ( err == 0 ) {
       
   471         d->m_isMarkedAsSeen = true;
       
   472     }
       
   473 }
       
   474 
       
   475 /*!
       
   476  * Check whether an idex is out of bound of our list
   473  * Check whether an idex is out of bound of our list
   477  *
   474  *
   478  * \param index Index to be validated
   475  * \param index Index to be validated
   479  */
   476  */
   480 
   477 
   493 {
   490 {
   494     QList< QList<int> > sequences;
   491     QList< QList<int> > sequences;
   495     QList<int> currSequence;
   492     QList<int> currSequence;
   496     int prevIndex = indices.at(0) - 1;
   493     int prevIndex = indices.at(0) - 1;
   497     
   494     
   498     for (int i = 0; i < indices.count(); i++)
   495     foreach( int currIndex, indices )
   499     {
   496     {
   500         int currIndex = indices.at(i);
   497         if ( currIndex >= 0 )
   501         
       
   502         if (currIndex >= 0)
       
   503         {
   498         {
   504             if ( prevIndex+1 != currIndex && !currSequence.isEmpty() )
   499             if ( prevIndex+1 != currIndex && !currSequence.isEmpty() )
   505             {
   500             {
   506                 sequences.append( currSequence );
   501                 sequences.append( currSequence );
   507                 currSequence.clear();
   502                 currSequence.clear();
   509             currSequence.append( currIndex );
   504             currSequence.append( currIndex );
   510             prevIndex = currIndex;
   505             prevIndex = currIndex;
   511         }
   506         }
   512     }
   507     }
   513     
   508     
   514     if (!currSequence.isEmpty())
   509     if ( !currSequence.isEmpty() )
   515     {
   510     {
   516         // Add last sequence if such exist
   511         // Add last sequence if such exist
   517         sequences.append( currSequence );
   512         sequences.append( currSequence );
   518     }
   513     }
   519     
   514     
   527  * \param item Conversation history item
   522  * \param item Conversation history item
   528  */
   523  */
   529 void CntHistoryModel::readMsgEvent(MsgItem& event, HistoryItem& item)
   524 void CntHistoryModel::readMsgEvent(MsgItem& event, HistoryItem& item)
   530 {
   525 {
   531     // Msg direction
   526     // Msg direction
   532     if ( event.direction() == MsgItem::MsgDirectionIncoming )
   527     if ( event.direction() == MsgItem::MsgDirectionIncoming ) {
   533         item.direction = CntHistoryModel::Incoming;
   528         item.flags |= Incoming;
   534     if ( event.direction() == MsgItem::MsgDirectionOutgoing )
   529         // Read status
   535         item.direction = CntHistoryModel::Outgoing;
   530         if ( event.isAttributeSet(MsgItem::MsgAttributeUnread) )
   536     
   531             item.flags |= Unseen;
   537     // Read status
   532         else
   538     /* TODO: This API available in the next release
   533             item.flags &= ~Unseen;
   539 	 *if ( event.isAttributeSet(MsgItem::MsgAttributeUnread) )
   534     } else if ( event.direction() == MsgItem::MsgDirectionOutgoing )
   540         item.seenStatus = CntHistoryModel::Unseen;
   535         item.flags |= Outgoing;
   541     else
   536     
   542         item.seenStatus = CntHistoryModel::Seen;*/
   537     // Attachment
   543     
   538     if (event.isAttributeSet(MsgItem::MsgAttributeAttachment))
   544     item.msgType = CntHistoryModel::Message;
   539         item.flags |= Attachment;
   545     item.number = event.phoneNumber(); 
   540     
   546     item.iconPath = QString("qtg_small_message");
   541     item.flags |= Message;
       
   542     item.number = event.phoneNumber();
   547     item.message = event.body();
   543     item.message = event.body();
   548     item.timeStamp = event.timeStamp();
   544     item.timeStamp = event.timeStamp().toLocalTime();
   549 }
   545 }
   550 
   546 
   551 /*!
   547 /*!
   552  * Slot to receive new messages for the first time
   548  * Slot to receive new messages for the first time
   553  * from the messages model
   549  * from the messages model
   555  * \param event Message event
   551  * \param event Message event
   556  * \param item Conversation history item
   552  * \param item Conversation history item
   557  */
   553  */
   558 void CntHistoryModel::messagesReady(QList<MsgItem>& msgs)
   554 void CntHistoryModel::messagesReady(QList<MsgItem>& msgs)
   559 {
   555 {
   560     int oldRowCount = rowCount();
       
   561     
       
   562     foreach( MsgItem m, msgs ) {
   556     foreach( MsgItem m, msgs ) {
   563         // Create a new hst item
   557         // Create a new hst item
   564         HItemPointer item(new HistoryItem());
   558         HItemPointer item(new HistoryItem());
   565         
   559         
   566         // Parse the MsgItem and add data into hst item
   560         // Parse the MsgItem and add data into hst item
   567         readMsgEvent( m, *item );
   561         readMsgEvent( m, *item );
   568         
   562         
   569         // Map the hst item to a MsgItem in the msgModel
   563         // Map the hist item to a MsgItem in the msgModel
   570         d->m_msgMap.insert( m.id(), item );
   564         d->m_msgMap.insert( m.id(), item );
   571         
   565         
   572         // Append the hst item to our list
   566         // Append the hst item to our list
   573         d->m_List.append( item );
   567         d->m_List.append( item );
   574     }
   568     }
   575     
   569     
   576     beginInsertRows(QModelIndex(), oldRowCount, rowCount());
   570     sort();
       
   571     
       
   572     beginInsertRows(QModelIndex(), 0, rowCount());
   577     endInsertRows();
   573     endInsertRows();
   578     
       
   579     // After all messagas are fetched sort them and
       
   580     // refresh the UI.
       
   581     sortAndRefresh();
       
   582 }
   574 }
   583 
   575 
   584 /*!
   576 /*!
   585  * Slot to receive new messages from the messages model
   577  * Slot to receive new messages from the messages model
   586  *
   578  *
   595     HItemPointer item(new HistoryItem());
   587     HItemPointer item(new HistoryItem());
   596     
   588     
   597     // Parse the MsgItem and add data into hst item
   589     // Parse the MsgItem and add data into hst item
   598     readMsgEvent( msg, *item );
   590     readMsgEvent( msg, *item );
   599     
   591     
   600     // Map the hst item to a MsgItem in the msgModel
   592     // Map the hist item to a MsgItem in the msgModel
   601     d->m_msgMap.insert( msg.id(), item );
   593     d->m_msgMap.insert( msg.id(), item );
   602     
   594     
   603     // Append the hst item to our list
   595     // Append the hst item to our list
   604     d->m_List.append( item );
   596     d->m_List.append( item );
   605     
   597     
   645     // No item was found.
   637     // No item was found.
   646     if ( p.isNull() )
   638     if ( p.isNull() )
   647         return;
   639         return;
   648     
   640     
   649     // Remove the item in stored containers
   641     // Remove the item in stored containers
   650     int count = d->m_msgMap.remove( msg.id() );
   642     d->m_msgMap.remove( msg.id() );
   651     int index = d->m_List.indexOf( p );
   643     int index = d->m_List.indexOf( p );
   652     bool removed = d->m_List.removeOne( p );
   644     if ( index > -1 ) {
   653     
   645         d->m_List.removeAt( index );
   654     if ( removed && count > 0 ) {
       
   655         beginRemoveRows(QModelIndex(), index, index);
   646         beginRemoveRows(QModelIndex(), index, index);
   656         endRemoveRows();
   647         endRemoveRows();
   657     }
   648     }
   658 }
   649 }