|
1 /* |
|
2 * Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "nmuiengineheaders.h" |
|
19 |
|
20 static const int NmFolderTypeRole = Qt::UserRole+1; |
|
21 |
|
22 /*! |
|
23 \class NmMessageListModel |
|
24 \brief The NmMessageListModel class represents data model for mailbox list. |
|
25 @alpha |
|
26 |
|
27 The NmMessageListModel class uses NmMessageEnvelope class to represent data returned in its' |
|
28 data method to get all information needed for one list row for a widget by calling the method |
|
29 once. |
|
30 */ |
|
31 |
|
32 /*! |
|
33 Class constructor. |
|
34 */ |
|
35 NmMessageListModel::NmMessageListModel(NmDataManager &dataManager, |
|
36 QObject *parent /* = 0 */) |
|
37 : QStandardItemModel(parent), |
|
38 mDataManager(dataManager), |
|
39 mDividersActive(false), |
|
40 mParentPtr(NULL), |
|
41 mCurrentFolderType(NmFolderInbox), |
|
42 mIgnoreFolderIds(false) |
|
43 { |
|
44 NM_FUNCTION; |
|
45 |
|
46 // Check for setting whether dividers are active |
|
47 // mDividersActive = ... |
|
48 // update also the test cases |
|
49 } |
|
50 |
|
51 |
|
52 /*! |
|
53 Class destructor. |
|
54 */ |
|
55 NmMessageListModel::~NmMessageListModel() |
|
56 { |
|
57 NM_FUNCTION; |
|
58 |
|
59 clear(); |
|
60 } |
|
61 |
|
62 |
|
63 /*! |
|
64 Returns data specified by \a index. Only Qt::DisplayRole is supported in \a role. |
|
65 The refresh method must have been called before this method can return any real data. |
|
66 */ |
|
67 QVariant NmMessageListModel::data(const QModelIndex &index, int role) const |
|
68 { |
|
69 NM_FUNCTION; |
|
70 |
|
71 QVariant qVariant; |
|
72 |
|
73 if (index.isValid()){ |
|
74 if (role == Qt::DisplayRole) { |
|
75 NmMessageListModelItem *item = |
|
76 static_cast<NmMessageListModelItem*>(itemFromIndex(index)); |
|
77 qVariant = QVariant::fromValue(item); |
|
78 } |
|
79 else if (role == NmFolderTypeRole) { |
|
80 qVariant = QVariant(mCurrentFolderType); |
|
81 } |
|
82 } |
|
83 |
|
84 return qVariant; |
|
85 } |
|
86 |
|
87 |
|
88 /*! |
|
89 This refreshes the data of the model. |
|
90 |
|
91 \param mailboxId The ID of the mailbox. |
|
92 \param folderId The ID of the folder. |
|
93 \param messageEnvelopeList A list containing the message meta data. |
|
94 */ |
|
95 void NmMessageListModel::refresh( |
|
96 const NmId mailboxId, |
|
97 const NmId folderId, |
|
98 const QList<NmMessageEnvelope*> &messageEnvelopeList) |
|
99 { |
|
100 NM_FUNCTION; |
|
101 |
|
102 // Store the current mailbox and folder IDs. |
|
103 mCurrentMailboxId = mailboxId; |
|
104 mCurrentFolderId = folderId; |
|
105 |
|
106 // Store the type of the currently displayed folder. |
|
107 mCurrentFolderType = mDataManager.folderTypeById(mailboxId, folderId); |
|
108 |
|
109 // Clear the model. |
|
110 clear(); |
|
111 |
|
112 // Add the items from the given list. |
|
113 NmMessageEnvelope* insertedMessage(NULL); |
|
114 int parentCount(0); |
|
115 int childCount(0); |
|
116 |
|
117 for (int i(0); i < messageEnvelopeList.count(); i++) { |
|
118 NmMessageEnvelope *nextMessage = messageEnvelopeList[i]; |
|
119 // imap and pop is using common sent, outbox or draft folder |
|
120 // for all mailboxes, here we want to filter out messages that |
|
121 // are not under this mailbox |
|
122 bool insert(true); |
|
123 if (nextMessage |
|
124 && (NmFolderSent == mCurrentFolderType |
|
125 || NmFolderOutbox == mCurrentFolderType |
|
126 || NmFolderDrafts == mCurrentFolderType)) { |
|
127 insert = (mCurrentMailboxId == nextMessage->mailboxId()); |
|
128 } |
|
129 if (insert) { |
|
130 if (mDividersActive && |
|
131 !messagesBelongUnderSameDivider(insertedMessage, nextMessage)) { |
|
132 insertDividerIntoModel(nextMessage, parentCount); |
|
133 parentCount++; |
|
134 childCount = 0; |
|
135 } |
|
136 |
|
137 insertMessageIntoModel(nextMessage, childCount, false); |
|
138 insertedMessage = nextMessage; |
|
139 childCount++; |
|
140 } |
|
141 } |
|
142 } |
|
143 |
|
144 |
|
145 /*! |
|
146 insertDividerIntoModel. Function inserts divider into model. |
|
147 */ |
|
148 void NmMessageListModel::insertDividerIntoModel( |
|
149 NmMessageEnvelope *messageForDivider, |
|
150 int parentRow) |
|
151 { |
|
152 NM_FUNCTION; |
|
153 |
|
154 mParentPtr = createTitleDividerItem(messageForDivider); |
|
155 insertRow(parentRow,mParentPtr); |
|
156 mParentPtr->callEmitDataChanged(); |
|
157 } |
|
158 |
|
159 /*! |
|
160 Function inserts message into model. Message can be inserted |
|
161 either to root or to parent. If parent is zero, item is added into root. |
|
162 */ |
|
163 void NmMessageListModel::insertMessageIntoModel( |
|
164 NmMessageEnvelope *messageEnvelope, int childRow, bool emitSignal) |
|
165 { |
|
166 NM_FUNCTION; |
|
167 |
|
168 NmMessageListModelItem *mailItem = createMessageItem(messageEnvelope); |
|
169 if (mParentPtr) { |
|
170 // Add under parent divider |
|
171 mParentPtr->insertRow(childRow, mailItem); |
|
172 } |
|
173 else { |
|
174 // No dividers, add under root item |
|
175 insertRow(childRow,mailItem); |
|
176 } |
|
177 if (emitSignal) { |
|
178 mailItem->callEmitDataChanged(); |
|
179 } |
|
180 } |
|
181 |
|
182 /*! |
|
183 Function checks whether the messages can be drawn under same title divider |
|
184 Check is done depending of the current sorting criteria |
|
185 */ |
|
186 bool NmMessageListModel::messagesBelongUnderSameDivider( |
|
187 const NmMessageEnvelope *message1, |
|
188 const NmMessageEnvelope *message2) const |
|
189 { |
|
190 NM_FUNCTION; |
|
191 |
|
192 bool retVal(false); |
|
193 // First check pointer validity |
|
194 if (message1 && message2) { |
|
195 // Switch here for other sort modes |
|
196 // Date based comparison |
|
197 QDateTime sentTime1 = message1->sentTime().toLocalTime(); |
|
198 QDateTime sentTime2 = message2->sentTime().toLocalTime(); |
|
199 if ( sentTime1.date() == sentTime2.date()) { |
|
200 retVal = true; |
|
201 } |
|
202 } |
|
203 return retVal; |
|
204 } |
|
205 |
|
206 |
|
207 /*! |
|
208 Handles the message events. |
|
209 |
|
210 \param event The type of the message event. |
|
211 \param folderId The folder containing the message. |
|
212 \param messageIds A list of message IDs related to the event. |
|
213 */ |
|
214 void NmMessageListModel::handleMessageEvent(NmMessageEvent event, |
|
215 const NmId &folderId, |
|
216 const QList<NmId> &messageIds, |
|
217 const NmId &mailboxId) |
|
218 { |
|
219 NM_FUNCTION; |
|
220 const int idCount = messageIds.count(); |
|
221 |
|
222 // Folder ID does not concern us if this model instance is used for e.g. |
|
223 // searching messages. |
|
224 if (!mIgnoreFolderIds) { |
|
225 if (folderId == 0) { |
|
226 // Const cast is used here because also the input parameter has to |
|
227 // be changed. |
|
228 const_cast<NmId&>(folderId) = |
|
229 mDataManager.getStandardFolderId(mailboxId, NmFolderInbox); |
|
230 NmUiStartParam *startParam = |
|
231 new NmUiStartParam(NmUiViewMessageList, mailboxId, folderId); |
|
232 emit setNewParam(startParam); |
|
233 } |
|
234 |
|
235 if (mCurrentFolderId == 0) { |
|
236 // Folder ID was not known at time when the mailbox opened and we |
|
237 // know that because of events the subscription is valid only for |
|
238 // the current mailbox. |
|
239 mCurrentFolderId = folderId; |
|
240 } |
|
241 // MailboxId checking here is done because we want to filter out messages |
|
242 // that belongs to other mailboxes in case of imap/pop sent, outbox or draft folder |
|
243 if (mCurrentFolderId != folderId || mCurrentMailboxId != mailboxId) { |
|
244 // The event does not concern the folder currently being displayed. |
|
245 // Thus, ignore it. |
|
246 return; |
|
247 } |
|
248 } |
|
249 |
|
250 // Go through the given message IDs and do the appropriate operations |
|
251 // according to the type of the event. |
|
252 for (int i(0); i < idCount; ++i) { |
|
253 switch (event) { |
|
254 case NmMessageChanged: { |
|
255 updateMessageEnvelope(mailboxId, folderId, messageIds[i]); |
|
256 break; |
|
257 } |
|
258 case NmMessageCreated: { |
|
259 // mIgnoreFolderIds is true if (and only if) this model is used |
|
260 // for mail search purposes and thus, we do not want the model |
|
261 // to handle "message created" events. Issue to consider: |
|
262 // renaming mIgonreFolderIds => mModelUsedForSearch or something |
|
263 // similar. |
|
264 if (!mIgnoreFolderIds && !itemFromModel(messageIds[i])) { |
|
265 insertNewMessageIntoModel(mailboxId, folderId, messageIds[i]); |
|
266 } |
|
267 |
|
268 break; |
|
269 } |
|
270 case NmMessageFound: { |
|
271 if (!itemFromModel(messageIds[i])) { |
|
272 insertNewMessageIntoModel(mailboxId, folderId, messageIds[i]); |
|
273 } |
|
274 |
|
275 break; |
|
276 } |
|
277 case NmMessageDeleted: { |
|
278 removeMessageFromModel(messageIds[i]); |
|
279 break; |
|
280 } |
|
281 } |
|
282 } |
|
283 } |
|
284 |
|
285 |
|
286 /*! |
|
287 Function inserts new message into correct position to model. |
|
288 A new title divider is created if it is needed. |
|
289 */ |
|
290 void NmMessageListModel::insertNewMessageIntoModel( |
|
291 const NmId &mailboxId, |
|
292 const NmId &folderId, |
|
293 const NmId &msgId) |
|
294 { |
|
295 NM_FUNCTION; |
|
296 |
|
297 // envelope ownership is here |
|
298 NmMessageEnvelope *newMsgEnve = mDataManager.envelopeById(mailboxId, folderId, msgId); |
|
299 if (newMsgEnve) { |
|
300 int rowIndex(getInsertionIndex(*newMsgEnve)); |
|
301 if (!mDividersActive) { |
|
302 if (rowIndex > -1){ |
|
303 insertMessageIntoModel(newMsgEnve, rowIndex, true); |
|
304 } else { |
|
305 NmMessageListModelItem *mailItem = createMessageItem(newMsgEnve); |
|
306 appendRow(mailItem); |
|
307 mailItem->callEmitDataChanged(); |
|
308 } |
|
309 } else { |
|
310 // model contain items, message goes to the middle of the list |
|
311 if (rowIndex > 0) { |
|
312 int dividerIndex(0); |
|
313 QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive); |
|
314 QModelIndex index = items[rowIndex]->index(); |
|
315 NmMessageListModelItem *item = static_cast<NmMessageListModelItem*>(itemFromIndex(index)); |
|
316 NmMessageEnvelope *replacedEnve = item->envelopePtr(); |
|
317 if (messagesBelongUnderSameDivider(newMsgEnve,replacedEnve)) { |
|
318 // find the index of the divider and insert message as child object |
|
319 // dividerIndex is not actually used here but function sets |
|
320 // the correct parent pointer |
|
321 dividerIndex = dividerInsertionIndex(rowIndex); |
|
322 insertMessageIntoModel(newMsgEnve, 0, true); |
|
323 } else { |
|
324 // create new divider and find the correct index for it |
|
325 dividerIndex = dividerInsertionIndex(rowIndex); |
|
326 insertDividerIntoModel(newMsgEnve, dividerIndex); |
|
327 // Insert message as a first child under new divider |
|
328 insertMessageIntoModel(newMsgEnve, 0, true); |
|
329 } |
|
330 items.clear(); |
|
331 } |
|
332 // first mail item in the model, |
|
333 // insert new divider to index 0 and new message as a child. |
|
334 else if (0 == rowIndex) { |
|
335 insertDividerIntoModel(newMsgEnve, rowIndex); |
|
336 insertMessageIntoModel(newMsgEnve, 0, true); |
|
337 } |
|
338 // this will go to the last item of the list and create new title divider |
|
339 else { |
|
340 mParentPtr = createTitleDividerItem(newMsgEnve); |
|
341 appendRow(mParentPtr); |
|
342 mParentPtr->callEmitDataChanged(); |
|
343 NmMessageListModelItem *mailItem = createMessageItem(newMsgEnve); |
|
344 // Add under parent divider |
|
345 mParentPtr->appendRow(mailItem); |
|
346 mailItem->callEmitDataChanged(); |
|
347 } |
|
348 } |
|
349 } |
|
350 delete newMsgEnve; |
|
351 } |
|
352 |
|
353 /*! |
|
354 Function check model index in which the new message should be inserted |
|
355 with the currently active sort mode. |
|
356 */ |
|
357 int NmMessageListModel::getInsertionIndex( |
|
358 const NmMessageEnvelope &envelope) const |
|
359 { |
|
360 NM_FUNCTION; |
|
361 |
|
362 int ret(NmNotFoundError); |
|
363 |
|
364 // Date+descending sort mode based comparison. |
|
365 // Go through model and compare sent times with QDateTime >= comparison operation. |
|
366 QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive); |
|
367 int count(items.count()); |
|
368 bool found(false); |
|
369 int i(0); |
|
370 while (i < count && !found) { |
|
371 QModelIndex index = items[i]->index(); |
|
372 NmMessageListModelItem *item = static_cast<NmMessageListModelItem*>(itemFromIndex(index)); |
|
373 if (NmMessageListModelItem::NmMessageItemMessage == item->itemType()) { |
|
374 found = envelope.sentTime() >= item->envelope().sentTime(); |
|
375 if (found) { |
|
376 ret = i; |
|
377 } |
|
378 } |
|
379 i++; |
|
380 } |
|
381 if (0 == count) { |
|
382 ret = NmNoError; |
|
383 } |
|
384 items.clear(); |
|
385 return ret; |
|
386 } |
|
387 |
|
388 /*! |
|
389 Function finds preceding title divider index and sets the |
|
390 mParentPtr variable. |
|
391 */ |
|
392 int NmMessageListModel::dividerInsertionIndex(int messageIndex) |
|
393 { |
|
394 NM_FUNCTION; |
|
395 |
|
396 bool found(false); |
|
397 int ret(NmNoError); |
|
398 QModelIndex index; |
|
399 QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive); |
|
400 for (int i = messageIndex-1; i >= 0 && !found; i--) { |
|
401 index = items[i]->index(); |
|
402 NmMessageListModelItem *item = static_cast<NmMessageListModelItem*>(itemFromIndex(index)); |
|
403 if(item->itemType() == NmMessageListModelItem::NmMessageItemTitleDivider) { |
|
404 found = true; |
|
405 mParentPtr = static_cast<NmMessageListModelItem*>(itemFromIndex(index)); |
|
406 ret = index.row(); |
|
407 } |
|
408 } |
|
409 items.clear(); |
|
410 return ret; |
|
411 } |
|
412 |
|
413 /*! |
|
414 Create title divider item |
|
415 */ |
|
416 NmMessageListModelItem *NmMessageListModel::createTitleDividerItem( |
|
417 NmMessageEnvelope *messageForDivider) |
|
418 { |
|
419 NM_FUNCTION; |
|
420 |
|
421 NmMessageListModelItem *item = new NmMessageListModelItem(); |
|
422 item->setItemType(NmMessageListModelItem::NmMessageItemTitleDivider); |
|
423 |
|
424 QDate sentLocalDate = messageForDivider->sentTime().toLocalTime().date(); |
|
425 QDate currentdate = QDate::currentDate(); |
|
426 |
|
427 if (sentLocalDate == currentdate) { |
|
428 // NOTE: when dividers are taken in to use hbTrId macro should used here, |
|
429 // to be clarified how to access ts-file (located under ui component) |
|
430 item->setTitleDivider(tr("Today", "txt_nmailuiengine_divider_today")); |
|
431 item->setText(tr("Today", "txt_nmailuiengine_divider_today")); |
|
432 } |
|
433 else { |
|
434 QLocale locale; |
|
435 QString divider = locale.toString(sentLocalDate, QLocale::LongFormat); |
|
436 item->setTitleDivider(divider); |
|
437 item->setText(divider); |
|
438 } |
|
439 item->setEnvelope(*messageForDivider); |
|
440 item->setData(Hb::ParentItem, Hb::ItemTypeRole); |
|
441 return item; |
|
442 } |
|
443 |
|
444 /*! |
|
445 Create message item |
|
446 */ |
|
447 NmMessageListModelItem *NmMessageListModel::createMessageItem( |
|
448 NmMessageEnvelope *envelope) |
|
449 { |
|
450 NM_FUNCTION; |
|
451 |
|
452 NmMessageListModelItem *mailItem = new NmMessageListModelItem(); |
|
453 mailItem->setEnvelope(*envelope); |
|
454 mailItem->setItemType(NmMessageListModelItem::NmMessageItemMessage); |
|
455 mailItem->setData(Hb::StandardItem, Hb::ItemTypeRole); |
|
456 return mailItem; |
|
457 } |
|
458 |
|
459 /*! |
|
460 Returns divider state |
|
461 */ |
|
462 bool NmMessageListModel::dividersActive() |
|
463 { |
|
464 NM_FUNCTION; |
|
465 |
|
466 return mDividersActive; |
|
467 } |
|
468 |
|
469 /*! |
|
470 Set divider state |
|
471 */ |
|
472 void NmMessageListModel::setDividers(bool active) |
|
473 { |
|
474 NM_FUNCTION; |
|
475 |
|
476 mDividersActive = active; |
|
477 } |
|
478 |
|
479 /*! |
|
480 Change item property if differs |
|
481 */ |
|
482 void NmMessageListModel::setEnvelopeProperties( |
|
483 NmEnvelopeProperties property, |
|
484 const QList<NmId> &messageIds) |
|
485 { |
|
486 NM_FUNCTION; |
|
487 |
|
488 for (int i(0); i < messageIds.count(); i++) { |
|
489 updateEnvelope(property, messageIds[i]); |
|
490 } |
|
491 } |
|
492 |
|
493 |
|
494 /*! |
|
495 Returns the ID of the current mailbox. |
|
496 */ |
|
497 NmId NmMessageListModel::currentMailboxId() |
|
498 { |
|
499 NM_FUNCTION; |
|
500 |
|
501 return mCurrentMailboxId; |
|
502 } |
|
503 |
|
504 |
|
505 /*! |
|
506 Sets whether the model should ignore the folder IDs or not. The folder IDs |
|
507 should be ignored e.g. when the model is used for searching messages |
|
508 (i.e. used by the search view). |
|
509 |
|
510 \param ignore If true, will ignore the folder IDs. |
|
511 */ |
|
512 void NmMessageListModel::setIgnoreFolderIds(bool ignore) |
|
513 { |
|
514 NM_FUNCTION; |
|
515 |
|
516 mIgnoreFolderIds = ignore; |
|
517 } |
|
518 |
|
519 |
|
520 /*! |
|
521 Remove message from model if message exists in model |
|
522 */ |
|
523 void NmMessageListModel::removeMessageFromModel(const NmId &msgId) |
|
524 { |
|
525 NM_FUNCTION; |
|
526 |
|
527 QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive); |
|
528 int count(items.count()); |
|
529 bool found(false); |
|
530 int i(0); |
|
531 while (!found && i < count) { |
|
532 QModelIndex index = items[i]->index(); |
|
533 NmMessageListModelItem *item = static_cast<NmMessageListModelItem*>(itemFromIndex(index)); |
|
534 if (NmMessageListModelItem::NmMessageItemMessage == item->itemType() |
|
535 && msgId == item->envelope().messageId()) { |
|
536 found = true; |
|
537 // dividers are not active, just remove message |
|
538 if (!mDividersActive) { |
|
539 removeItem(index.row(), *item); |
|
540 } else { |
|
541 // check the type from previous item |
|
542 QModelIndex prevIndex = items[i-1]->index(); |
|
543 NmMessageListModelItem* previous = static_cast<NmMessageListModelItem*>(itemFromIndex(prevIndex)); |
|
544 if (NmMessageListModelItem::NmMessageItemTitleDivider == previous->itemType()) { |
|
545 // previous item is title divider |
|
546 if (i < (count-1)) { |
|
547 // if this is not last item in the list, check next item |
|
548 QModelIndex nextIndex = items[i+1]->index(); |
|
549 NmMessageListModelItem* next = static_cast<NmMessageListModelItem*>(itemFromIndex(nextIndex)); |
|
550 if (NmMessageListModelItem::NmMessageItemMessage == next->itemType()) { |
|
551 // next item is message, divider should not be removed |
|
552 removeItem(index.row(), *item); |
|
553 } else { |
|
554 // next item is another divider, remove also divider |
|
555 removeItem(index.row(), *item); |
|
556 removeItem(prevIndex.row(), *previous); |
|
557 } |
|
558 } else { |
|
559 // this is the last message in list, remove also divider |
|
560 removeItem(index.row(), *item); |
|
561 removeItem(prevIndex.row(), *previous); |
|
562 } |
|
563 } else { |
|
564 // previous item is message, title divider should not be deleted |
|
565 removeItem(index.row(), *item); |
|
566 } |
|
567 } |
|
568 } |
|
569 i++; |
|
570 } |
|
571 items.clear(); |
|
572 } |
|
573 |
|
574 /*! |
|
575 Helper function to remove row |
|
576 */ |
|
577 void NmMessageListModel::removeItem(int row, NmMessageListModelItem &item) |
|
578 { |
|
579 NM_FUNCTION; |
|
580 |
|
581 QStandardItem *parent = item.parent(); |
|
582 removeRow(row, indexFromItem(parent)); |
|
583 } |
|
584 |
|
585 /*! |
|
586 Search item from model |
|
587 */ |
|
588 NmMessageListModelItem *NmMessageListModel::itemFromModel(const NmId &messageId) |
|
589 { |
|
590 NM_FUNCTION; |
|
591 |
|
592 QList<QStandardItem*> items = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive); |
|
593 int count(items.count()); |
|
594 bool found(false); |
|
595 int i(0); |
|
596 NmMessageListModelItem *ret(NULL); |
|
597 while (i < count && !found) { |
|
598 NmMessageListModelItem *item = |
|
599 static_cast<NmMessageListModelItem*>(itemFromIndex(items[i]->index())); |
|
600 if (NmMessageListModelItem::NmMessageItemMessage == item->itemType() |
|
601 && messageId == item->envelope().messageId()) { |
|
602 found = true; |
|
603 ret = item; |
|
604 } |
|
605 i++; |
|
606 } |
|
607 return ret; |
|
608 } |
|
609 |
|
610 /*! |
|
611 Helper function for envelope comparison |
|
612 */ |
|
613 bool NmMessageListModel::changed(const NmMessageEnvelope &first, const NmMessageEnvelope &second) |
|
614 { |
|
615 NM_FUNCTION; |
|
616 |
|
617 return first != second; |
|
618 } |
|
619 |
|
620 /*! |
|
621 Updates envelope if something is changed |
|
622 */ |
|
623 void NmMessageListModel::updateMessageEnvelope(const NmId &mailboxId, |
|
624 const NmId &folderId, |
|
625 const NmId &msgId) |
|
626 { |
|
627 NM_FUNCTION; |
|
628 |
|
629 NmMessageListModelItem *item = itemFromModel(msgId); |
|
630 // envelope ownership is here |
|
631 NmMessageEnvelope *newEnvelope = mDataManager.envelopeById(mailboxId, folderId, msgId); |
|
632 if (item && newEnvelope) { |
|
633 if (changed(*item->envelopePtr(), *newEnvelope)) { |
|
634 // function takes envelope ownership |
|
635 item->setEnvelope(newEnvelope); |
|
636 } else { |
|
637 delete newEnvelope; |
|
638 newEnvelope = NULL; |
|
639 } |
|
640 } |
|
641 } |
|
642 |
|
643 /*! |
|
644 Update envelope property |
|
645 */ |
|
646 void NmMessageListModel::updateEnvelope(NmEnvelopeProperties property, const NmId &msgId) |
|
647 { |
|
648 NM_FUNCTION; |
|
649 |
|
650 NmMessageListModelItem *item = itemFromModel(msgId); |
|
651 if (item) { |
|
652 bool changed(false); |
|
653 NmMessageEnvelope *envelope = item->envelopePtr(); |
|
654 switch (property) |
|
655 { |
|
656 case MarkAsRead: |
|
657 { |
|
658 if (!envelope->isRead()) { |
|
659 envelope->setRead(true); |
|
660 changed = true; |
|
661 } |
|
662 break; |
|
663 } |
|
664 case MarkAsUnread: |
|
665 { |
|
666 if (envelope->isRead()) { |
|
667 envelope->setRead(false); |
|
668 changed = true; |
|
669 } |
|
670 break; |
|
671 } |
|
672 default: |
|
673 break; |
|
674 } |
|
675 if (changed) { |
|
676 item->callEmitDataChanged(); |
|
677 } |
|
678 } |
|
679 } |