|
1 /* |
|
2 * Copyright (c) 2009 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 <QStringList> |
|
19 #include <QtAlgorithms> |
|
20 #include <HbGlobal> |
|
21 #include <msgitem.h> |
|
22 |
|
23 #include "cnthistorymodel_p.h" |
|
24 #include "cnthistorymodel.h" |
|
25 |
|
26 // Unnamed namespace for helper functions |
|
27 namespace |
|
28 { |
|
29 bool greaterThan(const HItemPointer& t1, const HItemPointer& t2) |
|
30 { |
|
31 return t1.data()->timeStamp > t2.data()->timeStamp; |
|
32 } |
|
33 |
|
34 bool lessThan(const HItemPointer& t1, const HItemPointer& t2) |
|
35 { |
|
36 return t1.data()->timeStamp < t2.data()->timeStamp; |
|
37 } |
|
38 } |
|
39 |
|
40 Q_DECLARE_METATYPE(LogsEvent *) |
|
41 |
|
42 /*! |
|
43 * Construct a new CntHistoryModel object to communicate |
|
44 * with the conversations and logs databases. |
|
45 * |
|
46 * \param contactId History specific to this contact is cached. |
|
47 * If no contact is specified all the call logs and conversation |
|
48 * history from all contacts will be cached. |
|
49 */ |
|
50 CntHistoryModel::CntHistoryModel(QContactLocalId contactId, |
|
51 QContactManager* manager, |
|
52 QObject *parent) |
|
53 : QAbstractListModel(parent) |
|
54 { |
|
55 d = new CntHistoryModelData(contactId, manager); |
|
56 |
|
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 |
|
65 initializeModel(); |
|
66 |
|
67 } |
|
68 |
|
69 CntHistoryModel::~CntHistoryModel() |
|
70 { |
|
71 } |
|
72 |
|
73 /*! |
|
74 * Return the data to be used by the view or delegates for a particular |
|
75 * item and role. |
|
76 * |
|
77 * \param index The index of the item to return data about. |
|
78 * \param role The data should be relevant to this particular purpose. |
|
79 * \return QVariant The data for the specified index and role. |
|
80 */ |
|
81 QVariant CntHistoryModel::data(const QModelIndex& index, int role) const |
|
82 { |
|
83 // Invalid index |
|
84 int row = index.row(); |
|
85 |
|
86 if ( !validateRowIndex(row) ) |
|
87 return QVariant(); |
|
88 |
|
89 HItemPointer p = d->m_List.at(row); |
|
90 if ( p.isNull() ) |
|
91 return QVariant(); |
|
92 |
|
93 switch( role ) |
|
94 { |
|
95 case Qt::DisplayRole: |
|
96 return displayRoleData(*p); |
|
97 case Qt::DecorationRole: |
|
98 return QVariant((*p).iconPath); |
|
99 case SeenStatusRole: |
|
100 return QVariant((*p).seenStatus); |
|
101 case DirectionRole: |
|
102 return QVariant((*p).direction); |
|
103 case ItemTypeRole: |
|
104 return QVariant((*p).msgType); |
|
105 case PhoneNumberRole: |
|
106 return QVariant((*p).number); |
|
107 default: |
|
108 return QVariant(); |
|
109 } |
|
110 } |
|
111 |
|
112 /*! |
|
113 * Return the data to be used by the view for a display role. |
|
114 * |
|
115 * \param column The column of the item to return data about. |
|
116 * return QVariant List of strings to be displayed on the view. |
|
117 * The stings can also be NULL |
|
118 * index 0 Title of the conversation item. |
|
119 * index 1 Body text |
|
120 * index 2 Time stamp |
|
121 */ |
|
122 QVariant CntHistoryModel::displayRoleData(const HistoryItem& item) const |
|
123 { |
|
124 QStringList list; |
|
125 |
|
126 list << item.title << item.message << item.timeStamp.toString(); |
|
127 |
|
128 return QVariant(list); |
|
129 } |
|
130 |
|
131 /*! |
|
132 * Get the number of rows (conversations) in this model. |
|
133 * |
|
134 * \param parent Optional parent index value. |
|
135 * \return Number of rows in this model. |
|
136 */ |
|
137 int CntHistoryModel::rowCount(const QModelIndex& /*parent*/) const |
|
138 { |
|
139 return d->m_List.size(); |
|
140 } |
|
141 |
|
142 /*! |
|
143 * Sort list items on the model. |
|
144 * |
|
145 * \param column Column to be sorted. It is not used. |
|
146 * \param order Order to sort the list items. |
|
147 */ |
|
148 void CntHistoryModel::sort(int /*column*/, Qt::SortOrder order) |
|
149 { |
|
150 if ( order == Qt::AscendingOrder ) |
|
151 qStableSort(d->m_List.begin(), d->m_List.end(), lessThan); |
|
152 else |
|
153 qStableSort(d->m_List.begin(), d->m_List.end(), greaterThan); |
|
154 } |
|
155 |
|
156 /*! |
|
157 * Clear history from the database. If the history cached |
|
158 * is specific to one contact, only that history is cleared. |
|
159 * |
|
160 */ |
|
161 void CntHistoryModel::clearHistory() |
|
162 { |
|
163 if ( d->m_List.isEmpty() ) |
|
164 return; |
|
165 |
|
166 // Call logs |
|
167 if ( !d->m_isMyCard && d->m_logsFilter ) { |
|
168 if ( !d->m_logsFilter->clearEvents() ) { |
|
169 // Operation not async |
|
170 clearedCallLogs( 0 ); |
|
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 |
|
179 // Messages |
|
180 d->m_msgHistory->clearMessages( (int)d->m_contactId ); |
|
181 } |
|
182 |
|
183 /*! |
|
184 * Mark all the conversations in the view as seen. |
|
185 * |
|
186 */ |
|
187 void CntHistoryModel::markAllAsSeen() |
|
188 { |
|
189 if ( d->m_isMarkedAsSeen ) |
|
190 return; |
|
191 |
|
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 |
|
200 d->m_msgHistory->markRead( (int)d->m_contactId ); |
|
201 |
|
202 d->m_isMarkedAsSeen = true; |
|
203 } |
|
204 |
|
205 /*! |
|
206 * Sort items in the model and refresh the view |
|
207 * |
|
208 */ |
|
209 void CntHistoryModel::sortAndRefresh(Qt::SortOrder order) |
|
210 { |
|
211 sort(0, order); |
|
212 emit layoutChanged(); |
|
213 } |
|
214 |
|
215 /*! |
|
216 * Create the model structure and cache history data from |
|
217 * conversations and call logs databases. |
|
218 * |
|
219 */ |
|
220 void CntHistoryModel::initializeModel() |
|
221 { |
|
222 initializeLogsModel(); |
|
223 initializeMsgModel(); |
|
224 } |
|
225 |
|
226 void CntHistoryModel::initializeMsgModel() |
|
227 { |
|
228 MsgHistory* m = new MsgHistory(); |
|
229 |
|
230 // Connect to signals emitted by msg model |
|
231 connect(m, SIGNAL(messagesReady(QList<MsgItem>& )), this, SLOT(messagesReady(QList<MsgItem>& ))); |
|
232 connect(m, SIGNAL(messageAdded(MsgItem& )), this, SLOT(messageAdded(MsgItem& ))); |
|
233 connect(m, SIGNAL(messageChanged(MsgItem& )), this, SLOT(messageChanged(MsgItem& ))); |
|
234 connect(m, SIGNAL(messageDeleted(MsgItem& )), this, SLOT(messageDeleted(MsgItem& ))); |
|
235 |
|
236 // Contact centric |
|
237 if( !d->m_isMyCard ) { |
|
238 // Subscribe to get new messages |
|
239 // received from this contact |
|
240 m->subscribe(d->m_contactId); |
|
241 |
|
242 // Initial fetch of all messages |
|
243 m->getMessages(d->m_contactId); |
|
244 } |
|
245 |
|
246 d->m_msgHistory = m; |
|
247 } |
|
248 |
|
249 void CntHistoryModel::initializeLogsModel() |
|
250 { |
|
251 //populate model with call events |
|
252 d->m_logsModel = new LogsModel(LogsModel::LogsFullModel); |
|
253 if (!d->m_isMyCard) { |
|
254 //do the filtering to get call events for the target contact |
|
255 d->m_logsFilter = new LogsCustomFilter; |
|
256 d->m_logsFilter->setContactId(d->m_contactId); |
|
257 d->m_logsFilter->setSourceModel(d->m_logsModel); |
|
258 d->m_AbstractLogsModel = d->m_logsFilter; |
|
259 |
|
260 connect(d->m_logsFilter, SIGNAL(clearingCompleted(int)), |
|
261 this, SLOT(clearedCallLogs(int))); |
|
262 connect(d->m_logsFilter, SIGNAL(markingCompleted(int)), |
|
263 this, SLOT(markingCompleted(int))); |
|
264 } else { |
|
265 //get all call events |
|
266 d->m_AbstractLogsModel = d->m_logsModel; |
|
267 |
|
268 connect(d->m_logsModel, SIGNAL(clearingCompleted(int)), |
|
269 this, SLOT(clearedCallLogs(int))); |
|
270 connect(d->m_logsModel, SIGNAL(markingCompleted(int)), |
|
271 this, SLOT(markingCompleted(int))); |
|
272 } |
|
273 |
|
274 //read first call events and start listening for more |
|
275 for ( int i = 0; i < d->m_AbstractLogsModel->rowCount(); ++i ) { |
|
276 LogsEvent* event = qVariantValue<LogsEvent*>( |
|
277 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) ); |
|
278 |
|
279 if ( event ) { |
|
280 HItemPointer item = HItemPointer(new HistoryItem()); |
|
281 readLogEvent(event, *item); |
|
282 d->m_logsMap.insert(i, item); |
|
283 d->m_List.append( item ); |
|
284 } |
|
285 } |
|
286 |
|
287 connect(d->m_AbstractLogsModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), |
|
288 this, SLOT(logsRowsInserted(const QModelIndex &, int, int))); |
|
289 connect(d->m_AbstractLogsModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), |
|
290 this, SLOT(logsRowsRemoved(const QModelIndex &, int, int))); |
|
291 connect(d->m_AbstractLogsModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), |
|
292 this, SLOT(logsDataChanged(const QModelIndex &, const QModelIndex &))); |
|
293 |
|
294 } |
|
295 |
|
296 /*! |
|
297 * Read call event into a history item |
|
298 * |
|
299 * \param event Call log event |
|
300 * \param item Conversation history item |
|
301 */ |
|
302 void CntHistoryModel::readLogEvent(LogsEvent* event, HistoryItem& item) |
|
303 { |
|
304 QString bodyText; |
|
305 QString icon; |
|
306 QString title; |
|
307 |
|
308 if ( d->m_isMyCard ) { |
|
309 if ( event->remoteParty().length() > 0 ) { |
|
310 title = event->remoteParty(); |
|
311 } |
|
312 else { |
|
313 title = event->number(); |
|
314 } |
|
315 } else { |
|
316 if ( event->direction() == LogsEvent::DirIn ) { |
|
317 bodyText = hbTrId("txt_phob_list_received"); |
|
318 icon = QString("qtg_small_received"); |
|
319 } else if ( event->direction() == LogsEvent::DirOut ) { |
|
320 bodyText = hbTrId("txt_phob_list_dialled_call"); |
|
321 icon = QString("qtg_small_sent"); |
|
322 } else if ( event->direction() == LogsEvent::DirMissed ) { |
|
323 bodyText = hbTrId("txt_phob_list_missed_call"); |
|
324 icon = QString("qtg_small_missed_call"); |
|
325 if ( !event->isRead() ) |
|
326 item.seenStatus = Unseen; |
|
327 } |
|
328 } |
|
329 |
|
330 if ( event->direction() == LogsEvent::DirOut ) |
|
331 item.direction = Outgoing; |
|
332 else |
|
333 item.direction = Incoming; |
|
334 |
|
335 item.message = bodyText; |
|
336 item.iconPath = icon; |
|
337 item.title = title; |
|
338 item.timeStamp = event->time(); |
|
339 item.msgType = CallLog; |
|
340 item.number = event->number(); |
|
341 } |
|
342 |
|
343 /*! |
|
344 * Slot used for receiving new rows from the LogsModel. |
|
345 * |
|
346 * \param parent Optional parent index value. |
|
347 * \param first The first row item to be received from the model. |
|
348 * \param last The last row item to be received from the model. |
|
349 */ |
|
350 void CntHistoryModel::logsRowsInserted(const QModelIndex& /*parent*/, int first, int last) |
|
351 { |
|
352 int oldRowCount = rowCount(); |
|
353 |
|
354 for ( int i = first; i < d->m_AbstractLogsModel->rowCount() && i <= last; ++i ) { |
|
355 LogsEvent* event = qVariantValue<LogsEvent*>( |
|
356 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) ); |
|
357 |
|
358 if ( event ) { |
|
359 HItemPointer item(new HistoryItem()); |
|
360 readLogEvent(event, *item); |
|
361 d->m_logsMap.insert(i, item); |
|
362 d->m_List.append( item ); |
|
363 } |
|
364 } |
|
365 |
|
366 beginInsertRows(QModelIndex(), oldRowCount, rowCount()); |
|
367 endInsertRows(); |
|
368 } |
|
369 |
|
370 /*! |
|
371 * Slot used for receiving new rows from the LogsModel. |
|
372 * |
|
373 * \param parent Optional parent index value. |
|
374 * \param first The first row item to be received from the model. |
|
375 * \param last The last row item to be received from the model. |
|
376 */ |
|
377 void CntHistoryModel::logsRowsRemoved(const QModelIndex& /*parent*/, int first, int last) |
|
378 { |
|
379 QList< int > indices; |
|
380 |
|
381 for ( int i = first; i <= last; ++i ) { |
|
382 HItemPointer item = d->m_logsMap.value( i ); |
|
383 int index = d->m_List.indexOf( item ); |
|
384 d->m_List.removeOne( item ); |
|
385 d->m_logsMap.remove( i ); |
|
386 indices.append( index ); |
|
387 } |
|
388 |
|
389 // Remove list items in batches |
|
390 if ( !indices.isEmpty() ) { |
|
391 QList< QList<int> > batches = findIndices(indices); |
|
392 foreach( QList<int> l, batches ) { |
|
393 beginRemoveRows(QModelIndex(), l.first(), l.last()); |
|
394 endRemoveRows(); |
|
395 } |
|
396 } |
|
397 } |
|
398 |
|
399 /*! |
|
400 * Update events from logs model. Events are |
|
401 * received as a batch |
|
402 * |
|
403 * \param first First updated model index |
|
404 * \param last Last updated model index |
|
405 */ |
|
406 void CntHistoryModel::logsDataChanged(const QModelIndex& first, const QModelIndex& last) |
|
407 { |
|
408 int f = first.row(); |
|
409 int l = last.row(); |
|
410 QList< int > indices; |
|
411 |
|
412 for ( int i = f; i < d->m_AbstractLogsModel->rowCount() && i <= l; ++i ) { |
|
413 |
|
414 LogsEvent* event = qVariantValue<LogsEvent*>( |
|
415 d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) ); |
|
416 |
|
417 // Fetch item from the mapped logs model items |
|
418 HItemPointer item = d->m_logsMap.value( i ); |
|
419 |
|
420 // Found item in the logs map |
|
421 if ( !item.isNull() ) { |
|
422 int index = d->m_List.indexOf( item ); |
|
423 readLogEvent( event, *item ); |
|
424 indices.append( index ); |
|
425 } |
|
426 } |
|
427 |
|
428 // Emit dataChanged signal only if there were updates |
|
429 if ( !indices.isEmpty() ) { |
|
430 QList< QList<int> > batches = findIndices( indices ); |
|
431 foreach( QList<int> l, batches ) |
|
432 emit dataChanged( index(l.first(), 0), index(l.last(), 0) ); |
|
433 } |
|
434 } |
|
435 |
|
436 /*! |
|
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 |
|
477 * |
|
478 * \param index Index to be validated |
|
479 */ |
|
480 |
|
481 bool CntHistoryModel::validateRowIndex( const int index) const |
|
482 { |
|
483 return( index < rowCount() && index >= 0 ); |
|
484 } |
|
485 |
|
486 /*! |
|
487 * Find the sequences of indices for the given indices from the private list |
|
488 * |
|
489 * \param indices List of indices |
|
490 * \return sequences of indices |
|
491 */ |
|
492 QList< QList<int> > CntHistoryModel::findIndices( const QList< int >& indices ) |
|
493 { |
|
494 QList< QList<int> > sequences; |
|
495 QList<int> currSequence; |
|
496 int prevIndex = indices.at(0) - 1; |
|
497 |
|
498 for (int i = 0; i < indices.count(); i++) |
|
499 { |
|
500 int currIndex = indices.at(i); |
|
501 |
|
502 if (currIndex >= 0) |
|
503 { |
|
504 if ( prevIndex+1 != currIndex && !currSequence.isEmpty() ) |
|
505 { |
|
506 sequences.append( currSequence ); |
|
507 currSequence.clear(); |
|
508 } |
|
509 currSequence.append( currIndex ); |
|
510 prevIndex = currIndex; |
|
511 } |
|
512 } |
|
513 |
|
514 if (!currSequence.isEmpty()) |
|
515 { |
|
516 // Add last sequence if such exist |
|
517 sequences.append( currSequence ); |
|
518 } |
|
519 |
|
520 return sequences; |
|
521 } |
|
522 |
|
523 /*! |
|
524 * Read message event into a history item |
|
525 * |
|
526 * \param event Message event |
|
527 * \param item Conversation history item |
|
528 */ |
|
529 void CntHistoryModel::readMsgEvent(MsgItem& event, HistoryItem& item) |
|
530 { |
|
531 // Msg direction |
|
532 if ( event.direction() == MsgItem::MsgDirectionIncoming ) |
|
533 item.direction = CntHistoryModel::Incoming; |
|
534 if ( event.direction() == MsgItem::MsgDirectionOutgoing ) |
|
535 item.direction = CntHistoryModel::Outgoing; |
|
536 |
|
537 // Read status |
|
538 /* TODO: This API available in the next release |
|
539 *if ( event.isAttributeSet(MsgItem::MsgAttributeUnread) ) |
|
540 item.seenStatus = CntHistoryModel::Unseen; |
|
541 else |
|
542 item.seenStatus = CntHistoryModel::Seen;*/ |
|
543 |
|
544 item.msgType = CntHistoryModel::Message; |
|
545 item.number = event.phoneNumber(); |
|
546 item.iconPath = QString("qtg_small_message"); |
|
547 item.message = event.body(); |
|
548 item.timeStamp = event.timeStamp(); |
|
549 } |
|
550 |
|
551 /*! |
|
552 * Slot to receive new messages for the first time |
|
553 * from the messages model |
|
554 * |
|
555 * \param event Message event |
|
556 * \param item Conversation history item |
|
557 */ |
|
558 void CntHistoryModel::messagesReady(QList<MsgItem>& msgs) |
|
559 { |
|
560 int oldRowCount = rowCount(); |
|
561 |
|
562 foreach( MsgItem m, msgs ) { |
|
563 // Create a new hst item |
|
564 HItemPointer item(new HistoryItem()); |
|
565 |
|
566 // Parse the MsgItem and add data into hst item |
|
567 readMsgEvent( m, *item ); |
|
568 |
|
569 // Map the hst item to a MsgItem in the msgModel |
|
570 d->m_msgMap.insert( m.id(), item ); |
|
571 |
|
572 // Append the hst item to our list |
|
573 d->m_List.append( item ); |
|
574 } |
|
575 |
|
576 beginInsertRows(QModelIndex(), oldRowCount, rowCount()); |
|
577 endInsertRows(); |
|
578 |
|
579 // After all messagas are fetched sort them and |
|
580 // refresh the UI. |
|
581 sortAndRefresh(); |
|
582 } |
|
583 |
|
584 /*! |
|
585 * Slot to receive new messages from the messages model |
|
586 * |
|
587 * \param event Message event |
|
588 * \param item Conversation history item |
|
589 */ |
|
590 void CntHistoryModel::messageAdded(MsgItem& msg) |
|
591 { |
|
592 int oldRowCount = rowCount(); |
|
593 |
|
594 // Create a new hst item |
|
595 HItemPointer item(new HistoryItem()); |
|
596 |
|
597 // Parse the MsgItem and add data into hst item |
|
598 readMsgEvent( msg, *item ); |
|
599 |
|
600 // Map the hst item to a MsgItem in the msgModel |
|
601 d->m_msgMap.insert( msg.id(), item ); |
|
602 |
|
603 // Append the hst item to our list |
|
604 d->m_List.append( item ); |
|
605 |
|
606 beginInsertRows( QModelIndex(), oldRowCount, rowCount() ); |
|
607 endInsertRows(); |
|
608 } |
|
609 |
|
610 /*! |
|
611 * Slot to update a message from the messages model |
|
612 * |
|
613 * \param event Message event |
|
614 * \param item Conversation history item |
|
615 */ |
|
616 void CntHistoryModel::messageChanged(MsgItem& msg) |
|
617 { |
|
618 // Fetch the hst item that maps to this MsgItem |
|
619 HItemPointer p = d->m_msgMap.value( msg.id() ); |
|
620 |
|
621 // No item was found. |
|
622 if ( p.isNull() ) |
|
623 return; |
|
624 |
|
625 // Parse the MsgItem and add data into hst item |
|
626 readMsgEvent(msg, *p); |
|
627 |
|
628 // Get the index of the the hst item in the list |
|
629 int pIndex = d->m_List.indexOf( p ); |
|
630 |
|
631 emit dataChanged(index(pIndex, 0), index(pIndex, 0)); |
|
632 } |
|
633 |
|
634 /*! |
|
635 * Slot to delete a message from the messages model |
|
636 * |
|
637 * \param event Message event |
|
638 * \param item Conversation history item |
|
639 */ |
|
640 void CntHistoryModel::messageDeleted(MsgItem& msg) |
|
641 { |
|
642 // Fetch the hst item that maps to this MsgItem |
|
643 HItemPointer p = d->m_msgMap.value( msg.id() ); |
|
644 |
|
645 // No item was found. |
|
646 if ( p.isNull() ) |
|
647 return; |
|
648 |
|
649 // Remove the item in stored containers |
|
650 int count = d->m_msgMap.remove( msg.id() ); |
|
651 int index = d->m_List.indexOf( p ); |
|
652 bool removed = d->m_List.removeOne( p ); |
|
653 |
|
654 if ( removed && count > 0 ) { |
|
655 beginRemoveRows(QModelIndex(), index, index); |
|
656 endRemoveRows(); |
|
657 } |
|
658 } |