emailuis/nmailuiengine/src/nmmessagelistmodel.cpp
changeset 27 9ba4404ef423
parent 23 2dc6caa42ec3
child 30 759dc5235cdb
equal deleted inserted replaced
23:2dc6caa42ec3 27:9ba4404ef423
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 #include "nmuiengineheaders.h"
    18 #include "nmuiengineheaders.h"
    19 
    19 
       
    20 static const int NmFolderTypeRole = Qt::UserRole+1; 
    20 
    21 
    21 /*!
    22 /*!
    22     \class NmMessageListModel
    23     \class NmMessageListModel
    23     \brief The NmMessageListModel class represents data model for mailbox list.
    24     \brief The NmMessageListModel class represents data model for mailbox list.
    24     @alpha
    25     @alpha
    27     data method to get all information needed for one list row for a widget by calling the method
    28     data method to get all information needed for one list row for a widget by calling the method
    28     once.
    29     once.
    29 */
    30 */
    30 
    31 
    31 /*!
    32 /*!
    32 	Constructor
    33 	Class constructor.
    33  */
    34 */
    34 NmMessageListModel::NmMessageListModel(NmDataManager &dataManager, QObject *parent)
    35 NmMessageListModel::NmMessageListModel(NmDataManager &dataManager,
    35 :QStandardItemModel(parent),
    36                                        QObject *parent /* = 0 */)
    36 mDataManager(dataManager),
    37 : QStandardItemModel(parent),
    37 mDividersActive(false),
    38   mDataManager(dataManager),
    38 mParentPtr(NULL)
    39   mDividersActive(false),
       
    40   mParentPtr(NULL),
       
    41   mCurrentFolderType(NmFolderInbox),
       
    42   mIgnoreFolderIds(false)
    39 {
    43 {
    40     // Check for setting whether dividers are active
    44     // Check for setting whether dividers are active
    41     // mDividersActive = ...
    45     // mDividersActive = ...
    42     // update also the test cases
    46     // update also the test cases
    43 }
    47 }
    44 
    48 
    45 /*!
    49 
    46 	Destructor
    50 /*!
    47  */
    51 	Class destructor.
       
    52 */
    48 NmMessageListModel::~NmMessageListModel()
    53 NmMessageListModel::~NmMessageListModel()
    49 {
    54 {
    50     clear();
    55     clear();
    51 }
    56 }
       
    57 
    52 
    58 
    53 /*!
    59 /*!
    54     Returns data specified by \a index. Only Qt::DisplayRole is supported in \a role.
    60     Returns data specified by \a index. Only Qt::DisplayRole is supported in \a role.
    55     The refresh method must have been called before this method can return any real data.
    61     The refresh method must have been called before this method can return any real data.
    56  */
    62 */
    57 
       
    58 QVariant NmMessageListModel::data(const QModelIndex &index, int role) const
    63 QVariant NmMessageListModel::data(const QModelIndex &index, int role) const
    59 {
    64 {
    60     QVariant qVariant;
    65     QVariant qVariant;
    61     if (index.isValid() && Qt::DisplayRole == role) {
    66 
    62     	NmMessageListModelItem *item = static_cast<NmMessageListModelItem*>(itemFromIndex(index));
    67     if (index.isValid()){
    63         qVariant = QVariant::fromValue(item);
    68         if (role == Qt::DisplayRole) {
    64     }
    69             NmMessageListModelItem *item =
       
    70                 static_cast<NmMessageListModelItem*>(itemFromIndex(index));
       
    71             qVariant = QVariant::fromValue(item);
       
    72         }
       
    73         else if (role == NmFolderTypeRole) {
       
    74             qVariant = QVariant(mCurrentFolderType);
       
    75         }    
       
    76     }
       
    77 
    65     return qVariant;
    78     return qVariant;
    66 }
    79 }
    67 
    80 
       
    81 
    68 /*!
    82 /*!
    69     This refreshes the data of the model.
    83     This refreshes the data of the model.
    70  */
    84 
       
    85     \param mailboxId The ID of the mailbox.
       
    86     \param folderId The ID of the folder.
       
    87     \param messageEnvelopeList A list containing the message meta data.
       
    88 */
    71 void NmMessageListModel::refresh(
    89 void NmMessageListModel::refresh(
    72                     const NmId mailboxId, 
    90         const NmId mailboxId, 
    73                     const NmId folderId,
    91         const NmId folderId,
    74                     const QList<NmMessageEnvelope*> &messageEnvelopeList)
    92         const QList<NmMessageEnvelope*> &messageEnvelopeList)
    75 {
    93 {
    76     // Store current mailbox and folder id
    94     // Store the current mailbox and folder IDs.
    77     mCurrentMailboxId = mailboxId;
    95     mCurrentMailboxId = mailboxId;
    78     mCurrentFolderId = folderId;
    96     mCurrentFolderId = folderId;
    79     // clear the model
    97 
       
    98     // Store the type of the currently displayed folder.
       
    99     mCurrentFolderType = mDataManager.folderTypeById(mailboxId, folderId);
       
   100 
       
   101     // Clear the model.
    80     clear();
   102     clear();
    81     // Add items
   103 
       
   104     // Add the items from the given list.
    82     NmMessageEnvelope* insertedMessage(NULL);
   105     NmMessageEnvelope* insertedMessage(NULL);
    83     int parentCount(0);
   106     int parentCount(0);
    84     int childCount(0);
   107     int childCount(0);
       
   108 
    85     for (int i(0); i < messageEnvelopeList.count(); i++) {
   109     for (int i(0); i < messageEnvelopeList.count(); i++) {
    86         NmMessageEnvelope* nextMessage = messageEnvelopeList[i];
   110         NmMessageEnvelope* nextMessage = messageEnvelopeList[i];
    87         if (mDividersActive && !messagesBelongUnderSameDivider(
   111 
    88         		insertedMessage, nextMessage)) {
   112         if (mDividersActive &&
       
   113             !messagesBelongUnderSameDivider(insertedMessage, nextMessage)) {
    89             insertDividerIntoModel(nextMessage, parentCount);
   114             insertDividerIntoModel(nextMessage, parentCount);
    90             parentCount++;
   115             parentCount++;
    91             childCount = 0;
   116             childCount = 0;
    92         }
   117         }
       
   118 
    93         insertMessageIntoModel(nextMessage, childCount, false);
   119         insertMessageIntoModel(nextMessage, childCount, false);
    94         insertedMessage = nextMessage;
   120         insertedMessage = nextMessage;
    95         childCount++;
   121         childCount++;
    96     }
   122     }
    97     //NMLOG(QString("nmailuiengine: model row count = %1").arg(rowCount()));
   123 }
    98 }
   124 
    99 
   125 
   100 /*!
   126 /*!
   101     insertDividerIntoModel. Function inserts divider into model.
   127     insertDividerIntoModel. Function inserts divider into model.
   102  */
   128 */
   103 void NmMessageListModel::insertDividerIntoModel(
   129 void NmMessageListModel::insertDividerIntoModel(
   104     NmMessageEnvelope *messageForDivider,
   130     NmMessageEnvelope *messageForDivider,
   105     int parentRow)
   131     int parentRow)
   106 {
   132 {
   107     mParentPtr = createTitleDividerItem(messageForDivider);
   133     mParentPtr = createTitleDividerItem(messageForDivider);
   110 }
   136 }
   111 
   137 
   112 /*!
   138 /*!
   113     Function inserts message into model. Message can be inserted
   139     Function inserts message into model. Message can be inserted
   114     either to root or to parent. If parent is zero, item is added into root.
   140     either to root or to parent. If parent is zero, item is added into root.
   115  */
   141 */
   116 void NmMessageListModel::insertMessageIntoModel(
   142 void NmMessageListModel::insertMessageIntoModel(
   117 		NmMessageEnvelope *messageEnvelope, int childRow, bool emitSignal)
   143 		NmMessageEnvelope *messageEnvelope, int childRow, bool emitSignal)
   118 {
   144 {
   119     NmMessageListModelItem *mailItem = createMessageItem(messageEnvelope);
   145     NmMessageListModelItem *mailItem = createMessageItem(messageEnvelope);
   120     if (mParentPtr) {
   146     if (mParentPtr) {
   131 }
   157 }
   132 
   158 
   133 /*!
   159 /*!
   134     Function checks whether the messages can be drawn under same title divider
   160     Function checks whether the messages can be drawn under same title divider
   135     Check is done depending of the current sorting criteria
   161     Check is done depending of the current sorting criteria
   136  */
   162 */
   137 bool NmMessageListModel::messagesBelongUnderSameDivider(
   163 bool NmMessageListModel::messagesBelongUnderSameDivider(
   138     const NmMessageEnvelope *message1,
   164     const NmMessageEnvelope *message1,
   139     const NmMessageEnvelope *message2) const
   165     const NmMessageEnvelope *message2) const
   140 {
   166 {
   141     bool retVal(false);
   167     bool retVal(false);
   152     return retVal;
   178     return retVal;
   153 }
   179 }
   154 
   180 
   155 
   181 
   156 /*!
   182 /*!
   157     Function handles message events
   183     Handles the message events.
   158  */
   184 
   159 void NmMessageListModel::handleMessageEvent(
   185     \param event The type of the message event.
   160     NmMessageEvent event,
   186     \param folderId The folder containing the message.
   161     const NmId &folderId,
   187     \param messageIds A list of message IDs related to the event.
   162     const QList<NmId> &messageIds)
   188 */
   163 {
   189 void NmMessageListModel::handleMessageEvent(NmMessageEvent event,
       
   190                                             const NmId &folderId,
       
   191                                             const QList<NmId> &messageIds)
       
   192 {
       
   193     NMLOG(QString("nmmessagelistmodel::handleMessageEvent()"));
       
   194     
   164     NmId mailboxId = mCurrentMailboxId;
   195     NmId mailboxId = mCurrentMailboxId;
   165 
   196     const int idCount = messageIds.count();
   166     if (folderId == 0) {
   197 
   167         // const cast is used here because also the input parameter has to be changed
   198     // Folder ID does not concern us if this model instance is used for e.g.
   168         const_cast<NmId&>(folderId) = mDataManager.getStandardFolderId(mailboxId, NmFolderInbox);
   199     // searching messages.
   169         NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageList, mailboxId, folderId);
   200     if (!mIgnoreFolderIds) {
   170         emit setNewParam(startParam);
   201         if (folderId == 0) {
   171     }
   202             // Const cast is used here because also the input parameter has to
   172     if (mCurrentFolderId == 0) {
   203             // be changed.
   173         // Folder id was not known at time mailbox opened
   204             const_cast<NmId&>(folderId) =
   174         // and we know subscription is valid only for current 
   205                 mDataManager.getStandardFolderId(mailboxId, NmFolderInbox);
   175         // mailbox, because of events.
   206             NmUiStartParam *startParam =
   176         mCurrentFolderId = folderId; 
   207                 new NmUiStartParam(NmUiViewMessageList, mailboxId, folderId);
   177     }
   208             emit setNewParam(startParam);
   178     // Handle events if they concern currently displayed folder
   209         }
   179     if (mCurrentFolderId == folderId) {
   210 
   180         NMLOG(QString("nmailuiengine: handleMessageEvent"));
   211         if (mCurrentFolderId == 0) {
   181         if (NmMessageChanged == event) {
   212             // Folder ID was not known at time when the mailbox opened and we
   182             for (int a(0); a < messageIds.count(); a++) {
   213             // know that because of events the subscription is valid only for
   183                 updateMessageEnvelope(mailboxId, folderId,messageIds[a]);
   214             // the current mailbox.
   184             }
   215             mCurrentFolderId = folderId; 
   185         }
   216         }
   186         else if (NmMessageCreated == event) {
   217 
   187             for (int a(0); a < messageIds.count(); a++) {
   218         if (mCurrentFolderId != folderId) {
   188                 if(!itemFromModel(messageIds[a])) {
   219             // The event does not concern the folder currently being displayed.
   189                     insertNewMessageIntoModel(mailboxId, folderId, messageIds[a]);
   220             // Thus, ignore it.
       
   221             return;
       
   222         }
       
   223     }
       
   224 
       
   225     // Go through the given message IDs and do the appropriate operations
       
   226     // according to the type of the event.
       
   227     for (int i(0); i < idCount; ++i) {
       
   228         switch (event) {
       
   229             case NmMessageChanged: {
       
   230                 updateMessageEnvelope(mailboxId, folderId, messageIds[i]);
       
   231                 break;
       
   232             }
       
   233             case NmMessageCreated:
       
   234             case NmMessageFound: {
       
   235                 if (!itemFromModel(messageIds[i])) {
       
   236                     insertNewMessageIntoModel(mailboxId, folderId, messageIds[i]);
   190                 }
   237                 }
   191             }
   238 
   192         } else {
   239                 break;
   193             for (int a(0); a < messageIds.count(); a++) {
   240             }
   194                 removeMessageFromModel(messageIds[a]);
   241             case NmMessageDeleted: {
   195             }
   242                 removeMessageFromModel(messageIds[i]);
   196         }
   243                 break;
   197     }
   244             }
   198 }
   245         }
       
   246     }
       
   247 }
       
   248 
   199 
   249 
   200 /*!
   250 /*!
   201     Function inserts new message into correct position to model.
   251     Function inserts new message into correct position to model.
   202     A new title divider is created if it is needed.
   252     A new title divider is created if it is needed.
   203  */
   253 */
   204 void NmMessageListModel::insertNewMessageIntoModel(
   254 void NmMessageListModel::insertNewMessageIntoModel(
   205     const NmId &mailboxId,
   255     const NmId &mailboxId,
   206     const NmId &folderId,
   256     const NmId &folderId,
   207     const NmId &msgId)
   257     const NmId &msgId)
   208 {
   258 {
   264 }
   314 }
   265 
   315 
   266 /*!
   316 /*!
   267     Function check model index in which the new message should be inserted
   317     Function check model index in which the new message should be inserted
   268     with the currently active sort mode.
   318     with the currently active sort mode.
   269  */
   319 */
   270 int NmMessageListModel::getInsertionIndex(
   320 int NmMessageListModel::getInsertionIndex(
   271     const NmMessageEnvelope &envelope) const
   321     const NmMessageEnvelope &envelope) const
   272 {
   322 {
   273     // NMLOG(QString("nmailuiengine: getInsertionIndex"));
   323     // NMLOG(QString("nmailuiengine: getInsertionIndex"));
   274     int ret(NmNotFoundError);
   324     int ret(NmNotFoundError);
   298 }
   348 }
   299 
   349 
   300 /*!
   350 /*!
   301     Function finds preceding title divider index and sets the
   351     Function finds preceding title divider index and sets the
   302     mParentPtr variable.
   352     mParentPtr variable.
   303  */
   353 */
   304 int NmMessageListModel::dividerInsertionIndex(int messageIndex)
   354 int NmMessageListModel::dividerInsertionIndex(int messageIndex)
   305 {
   355 {
   306     bool found(false);
   356     bool found(false);
   307     int ret(NmNoError);
   357     int ret(NmNoError);
   308     QModelIndex index;
   358     QModelIndex index;
   320     return ret;
   370     return ret;
   321 }
   371 }
   322 
   372 
   323 /*!
   373 /*!
   324     Create title divider item
   374     Create title divider item
   325  */
   375 */
   326 NmMessageListModelItem *NmMessageListModel::createTitleDividerItem(
   376 NmMessageListModelItem *NmMessageListModel::createTitleDividerItem(
   327 		NmMessageEnvelope *messageForDivider)
   377 		NmMessageEnvelope *messageForDivider)
   328 {
   378 {
   329     NmMessageListModelItem *item = new NmMessageListModelItem();
   379     NmMessageListModelItem *item = new NmMessageListModelItem();
   330     item->setItemType(NmMessageListModelItem::NmMessageItemTitleDivider);
   380     item->setItemType(NmMessageListModelItem::NmMessageItemTitleDivider);
   349     return item;
   399     return item;
   350 }
   400 }
   351 
   401 
   352 /*!
   402 /*!
   353     Create message item
   403     Create message item
   354  */
   404 */
   355 NmMessageListModelItem *NmMessageListModel::createMessageItem(
   405 NmMessageListModelItem *NmMessageListModel::createMessageItem(
   356 		NmMessageEnvelope *envelope)
   406 		NmMessageEnvelope *envelope)
   357 {
   407 {
   358 
   408 
   359     NmMessageListModelItem *mailItem = new NmMessageListModelItem();
   409     NmMessageListModelItem *mailItem = new NmMessageListModelItem();
   363     return mailItem;
   413     return mailItem;
   364 }
   414 }
   365 
   415 
   366 /*!
   416 /*!
   367     Returns divider state
   417     Returns divider state
   368  */
   418 */
   369 bool NmMessageListModel::dividersActive()
   419 bool NmMessageListModel::dividersActive()
   370 {
   420 {
   371     return mDividersActive;
   421     return mDividersActive;
   372 }
   422 }
   373 
   423 
   374 /*!
   424 /*!
   375     Set divider state
   425     Set divider state
   376  */
   426 */
   377 void NmMessageListModel::setDividers(bool active)
   427 void NmMessageListModel::setDividers(bool active)
   378 {
   428 {
   379     mDividersActive = active;
   429     mDividersActive = active;
   380 }
   430 }
   381 
   431 
   382 /*!
   432 /*!
   383    Change item property if differs
   433    Change item property if differs
   384  */
   434 */
   385 void NmMessageListModel::setEnvelopeProperties(
   435 void NmMessageListModel::setEnvelopeProperties(
   386     NmEnvelopeProperties property,
   436     NmEnvelopeProperties property,
   387     const QList<NmId> &messageIds)
   437     const QList<NmId> &messageIds)
   388 {
   438 {
   389     for (int i(0); i < messageIds.count(); i++) {
   439     for (int i(0); i < messageIds.count(); i++) {
   390         updateEnvelope(property, messageIds[i]);
   440         updateEnvelope(property, messageIds[i]);
   391     }
   441     }
   392 }
   442 }
   393 
   443 
   394 /*!
   444 
   395    Returns the id of the current mailbox
   445 /*!
   396  */
   446     Returns the ID of the current mailbox.
       
   447 */
   397 NmId NmMessageListModel::currentMailboxId()
   448 NmId NmMessageListModel::currentMailboxId()
   398 {
   449 {
   399     return mCurrentMailboxId;
   450     return mCurrentMailboxId;
   400 }
   451 }
   401 
   452 
       
   453 
       
   454 /*!
       
   455     Sets whether the model should ignore the folder IDs or not. The folder IDs
       
   456     should be ignored e.g. when the model is used for searching messages
       
   457     (i.e. used by the search view).
       
   458 
       
   459     \param ignore If true, will ignore the folder IDs.
       
   460 */
       
   461 void NmMessageListModel::setIgnoreFolderIds(bool ignore)
       
   462 {
       
   463     mIgnoreFolderIds = ignore;
       
   464 }
       
   465 
       
   466 
   402 /*!
   467 /*!
   403    Remove message from model if message exists in model
   468    Remove message from model if message exists in model
   404  */
   469 */
   405 void NmMessageListModel::removeMessageFromModel(const NmId &msgId)
   470 void NmMessageListModel::removeMessageFromModel(const NmId &msgId)
   406 {
   471 {
   407     QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive);
   472     QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive);
   408     int count(items.count());
   473     int count(items.count());
   409     bool found(false);
   474     bool found(false);
   451     items.clear();
   516     items.clear();
   452 }
   517 }
   453 
   518 
   454 /*!
   519 /*!
   455    Helper function to remove row
   520    Helper function to remove row
   456  */
   521 */
   457 void NmMessageListModel::removeItem(int row, NmMessageListModelItem &item)
   522 void NmMessageListModel::removeItem(int row, NmMessageListModelItem &item)
   458 {
   523 {
   459     QStandardItem *parent = item.parent();
   524     QStandardItem *parent = item.parent();
   460     removeRow(row, indexFromItem(parent));
   525     removeRow(row, indexFromItem(parent));
   461 }
   526 }
   462 
   527 
   463 /*!
   528 /*!
   464    Search item from model
   529    Search item from model
   465  */
   530 */
   466 NmMessageListModelItem *NmMessageListModel::itemFromModel(const NmId &messageId)
   531 NmMessageListModelItem *NmMessageListModel::itemFromModel(const NmId &messageId)
   467 {
   532 {
   468     QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive);
   533     QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive);
   469     int count(items.count());
   534     int count(items.count());
   470     bool found(false);
   535     bool found(false);
   483     return ret;
   548     return ret;
   484 }
   549 }
   485 
   550 
   486 /*!
   551 /*!
   487    Helper function for envelope comparison
   552    Helper function for envelope comparison
   488  */
   553 */
   489 bool NmMessageListModel::changed(const NmMessageEnvelope &first, const NmMessageEnvelope &second)
   554 bool NmMessageListModel::changed(const NmMessageEnvelope &first, const NmMessageEnvelope &second)
   490 {
   555 {
   491     return first != second;
   556     return first != second;
   492 }
   557 }
   493 
   558 
   494 /*!
   559 /*!
   495    Updates envelope if something is changed
   560    Updates envelope if something is changed
   496  */
   561 */
   497 void NmMessageListModel::updateMessageEnvelope(const NmId &mailboxId,
   562 void NmMessageListModel::updateMessageEnvelope(const NmId &mailboxId,
   498         const NmId &folderId,
   563         const NmId &folderId,
   499         const NmId &msgId)
   564         const NmId &msgId)
   500 {
   565 {
   501     NmMessageListModelItem *item = itemFromModel(msgId);
   566     NmMessageListModelItem *item = itemFromModel(msgId);
   512     }
   577     }
   513 }
   578 }
   514 
   579 
   515 /*!
   580 /*!
   516    Update envelope property
   581    Update envelope property
   517  */
   582 */
   518 void NmMessageListModel::updateEnvelope(NmEnvelopeProperties property, const NmId &msgId)
   583 void NmMessageListModel::updateEnvelope(NmEnvelopeProperties property, const NmId &msgId)
   519 {
   584 {
   520     NmMessageListModelItem *item = itemFromModel(msgId);
   585     NmMessageListModelItem *item = itemFromModel(msgId);
   521     if (item) {
   586     if (item) {
   522         bool changed(false);
   587         bool changed(false);