14 * Description: This file implements class CFSNotificationHandlerBase. |
14 * Description: This file implements class CFSNotificationHandlerBase. |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 #include <centralrepository.h> |
18 #include <centralrepository.h> |
19 //<cmail> |
|
20 #include "emailtrace.h" |
19 #include "emailtrace.h" |
21 #include "cfsmailclient.h" |
20 #include "cfsmailclient.h" |
22 //</cmail> |
|
23 |
21 |
24 #include "fsnotificationhandlermgr.h" |
22 #include "fsnotificationhandlermgr.h" |
25 #include "fsnotificationhandlerbase.h" |
23 #include "fsnotificationhandlerbase.h" |
26 #include "cmailhandlerpluginpanic.h" |
24 #include "cmailhandlerpluginpanic.h" |
27 #include "commonemailcrkeys.h" |
25 #include "commonemailcrkeys.h" |
28 #include "freestyleemailcenrepkeys.h" |
26 #include "freestyleemailcenrepkeys.h" |
29 #include "FreestyleEmailUiConstants.h" |
27 #include "FreestyleEmailUiConstants.h" |
30 |
28 |
31 |
29 |
|
30 const TInt KTimerDelay = 20; |
|
31 |
32 // ======== MEMBER FUNCTIONS ======== |
32 // ======== MEMBER FUNCTIONS ======== |
33 |
33 |
34 CFSNotificationHandlerBase::CFSNotificationHandlerBase( |
34 CFSNotificationHandlerBase::CFSNotificationHandlerBase( |
35 MFSNotificationHandlerMgr& aOwner ) : |
35 MFSNotificationHandlerMgr& aOwner ) : |
36 iOwner( aOwner ), |
36 iOwner( aOwner ), |
100 return EFalse; |
95 return EFalse; |
101 } |
96 } |
102 } |
97 } |
103 |
98 |
104 TBool CFSNotificationHandlerBase::MessagesCauseNotificationL( TFSMailMsgId aMailboxId, |
99 TBool CFSNotificationHandlerBase::MessagesCauseNotificationL( TFSMailMsgId aMailboxId, |
105 CFSMailFolder& aParentFolder, |
100 TFSMailMsgId aParentFolderId, |
106 const RArray<TFSMailMsgId>& aMsgIdList ) |
101 const RArray<TFSMailMsgId>& aMsgIdList ) |
107 { |
102 { |
108 FUNC_LOG; |
103 FUNC_LOG; |
|
104 |
|
105 CFSMailFolder* parentFolder( |
|
106 MailClient().GetFolderByUidL( aMailboxId, aParentFolderId ) ); |
|
107 User::LeaveIfNull( parentFolder ); |
|
108 CleanupStack::PushL( parentFolder ); |
|
109 |
109 CFSMailMessage* newestMsg( NULL ); |
110 CFSMailMessage* newestMsg( NULL ); |
110 TRAPD( notFoundError, |
111 TRAPD( notFoundError, |
111 newestMsg = |
112 newestMsg = |
112 NewestMsgInFolderL( aParentFolder ) ); |
113 NewestMsgInFolderL( *parentFolder ) ); |
113 if ( notFoundError == KErrNotFound ) |
114 if ( notFoundError == KErrNotFound ) |
114 { |
115 { |
115 // For some odd reason we are not able to get the newest |
116 // For some odd reason we are not able to get the newest |
116 // message from the folder. This should not be possible |
117 // message from the folder. This should not be possible |
117 // as we just received notification of a new message. |
118 // as we just received notification of a new message. |
123 TTime dateOfNewest( newestMsg->GetDate() ); |
124 TTime dateOfNewest( newestMsg->GetDate() ); |
124 |
125 |
125 delete newestMsg; |
126 delete newestMsg; |
126 newestMsg = NULL; |
127 newestMsg = NULL; |
127 |
128 |
128 TFSMailMsgId parentFolderId( aParentFolder.GetFolderId() ); |
129 CleanupStack::PopAndDestroy( parentFolder ); |
129 |
130 |
130 TInt index( 0 ); |
|
131 const TInt entriesCount( aMsgIdList.Count() ); |
131 const TInt entriesCount( aMsgIdList.Count() ); |
132 while ( index < entriesCount ) |
132 TInt index( entriesCount-1 ); |
|
133 // go from back of list, as messages are coming from earliest to latest.. |
|
134 while ( index >= 0 ) |
133 { |
135 { |
134 // Let's get the message. We need to check from it that |
136 // Let's get the message. We need to check from it that |
135 // it is really unread. This info is stored in the |
137 // it is really unread. This info is stored in the |
136 // flags. Also check that the message is newest. |
138 // flags. Also check that the message is newest. |
137 // EFSMsgDataEnvelope is used as TFSMailDetails |
139 // EFSMsgDataEnvelope is used as TFSMailDetails |
138 // so that we get enough data. |
140 // so that we get enough data. |
139 CFSMailMessage* |
141 CFSMailMessage* |
140 currentMessage( MailClient().GetMessageByUidL( |
142 currentMessage( MailClient().GetMessageByUidL( |
141 aMailboxId, |
143 aMailboxId, |
142 parentFolderId, |
144 aParentFolderId, |
143 aMsgIdList[index], |
145 aMsgIdList[index], |
144 EFSMsgDataEnvelope ) ); |
146 EFSMsgDataEnvelope ) ); |
145 User::LeaveIfNull( currentMessage ); |
147 User::LeaveIfNull( currentMessage ); |
146 const TTime dateOfCurrentMsg( currentMessage->GetDate() ); |
148 const TTime dateOfCurrentMsg( currentMessage->GetDate() ); |
147 |
149 |
219 parentFolderId = static_cast< TFSMailMsgId* >( aParam2 ); |
221 parentFolderId = static_cast< TFSMailMsgId* >( aParam2 ); |
220 if ( parentFolderId == NULL ) |
222 if ( parentFolderId == NULL ) |
221 { |
223 { |
222 User::Leave( KErrArgument ); |
224 User::Leave( KErrArgument ); |
223 } |
225 } |
224 CFSMailFolder* parentFolder( |
226 |
225 MailClient().GetFolderByUidL( aMailbox, *parentFolderId ) ); |
|
226 User::LeaveIfNull( parentFolder ); |
|
227 CleanupStack::PushL( parentFolder ); |
|
228 |
|
229 // Set the notification on only in cases that the new mail is |
227 // Set the notification on only in cases that the new mail is |
230 // in folder of type EFSInbox |
228 // in folder of type EFSInbox |
231 if ( parentFolder->GetFolderType() == EFSInbox ) |
229 if ( iOwner.GetFolderTypeL( aMailbox, parentFolderId ) == EFSInbox ) |
232 { |
230 { |
233 |
|
234 RArray<TFSMailMsgId>* newEntries( |
231 RArray<TFSMailMsgId>* newEntries( |
235 static_cast< RArray<TFSMailMsgId>* >( aParam1 ) ); |
232 static_cast< RArray<TFSMailMsgId>* >( aParam1 ) ); |
236 |
233 |
237 if ( MessagesCauseNotificationL( |
234 TInt count = newEntries->Count(); |
238 aMailbox, |
235 for ( TInt i = 0; i<count;i++ ) |
239 *parentFolder, |
236 { |
240 *newEntries ) ) |
237 TFSMailMsgId msgId = newEntries->operator []( i ); |
|
238 TNewMailInfo info( msgId, aMailbox, *parentFolderId ); |
|
239 iNewInboxEntries.AppendL( info ); |
|
240 } |
|
241 |
|
242 if (iTimer->IsActive() ) |
|
243 { |
|
244 iTimer->Cancel(); |
|
245 } |
|
246 iTimer->After( KTimerDelay ); |
|
247 } |
|
248 else |
|
249 { |
|
250 // If messages are in some other folder than in inbox |
|
251 // they have no effect on the notification |
|
252 } |
|
253 } |
|
254 else |
|
255 { |
|
256 // No other events than new mail are handled. For example |
|
257 // moving of messages and changing message status has no |
|
258 // effect on the notification. |
|
259 } |
|
260 } |
|
261 |
|
262 void CFSNotificationHandlerBase::TimerExpiredL() |
|
263 { |
|
264 // process collected insert requests |
|
265 RArray<TFSMailMsgId> msgIds; |
|
266 TFSMailMsgId mailBoxId; |
|
267 TFSMailMsgId parentFolderId; |
|
268 for ( TInt i = 0; i< iNewInboxEntries.Count(); i++ ) |
|
269 { |
|
270 TNewMailInfo& info = iNewInboxEntries[ i ]; |
|
271 if ( mailBoxId.IsNullId() && parentFolderId.IsNullId() ) |
|
272 { |
|
273 // starting new group is starting to collect |
|
274 mailBoxId = info.iMailBox; |
|
275 parentFolderId = info.iParentFolderId; |
|
276 } |
|
277 if ( mailBoxId == info.iMailBox && parentFolderId == info.iParentFolderId ) |
|
278 { |
|
279 // collect message ids for the same mailbox and parent folder |
|
280 msgIds.Append( info.iMsgId ); |
|
281 } |
|
282 else |
|
283 { |
|
284 // process collected message ids for the same mailbox and parent folder |
|
285 if ( msgIds.Count()&& MessagesCauseNotificationL( mailBoxId, parentFolderId, msgIds ) ) |
241 { |
286 { |
242 TurnNotificationOn(); |
287 TurnNotificationOn(); |
243 } |
288 } |
244 } |
289 // clear data and start collecting again |
245 else |
290 msgIds.Reset(); |
246 { |
291 mailBoxId = TFSMailMsgId(); |
247 // If messages are in some other folder than in inbox |
292 parentFolderId = TFSMailMsgId(); |
248 // they have no effect on the notification |
293 } |
249 } |
294 } |
250 CleanupStack::PopAndDestroy( parentFolder ); |
295 // process collected message ids for the same mailbox and parent folder |
251 } |
296 if ( msgIds.Count() && MessagesCauseNotificationL( mailBoxId, parentFolderId, msgIds ) ) |
252 else |
297 { |
253 { |
298 TurnNotificationOn(); |
254 // No other events than new mail are handled. For example |
299 } |
255 // moving of messages and changing message status has no |
300 // clear processed entries |
256 // effect on the notification. |
301 msgIds.Reset(); |
257 } |
302 iNewInboxEntries.Reset(); |
258 } |
303 } |
259 |
|
260 |
304 |
261 CFSMailMessage* CFSNotificationHandlerBase::NewestMsgInFolderL( |
305 CFSMailMessage* CFSNotificationHandlerBase::NewestMsgInFolderL( |
262 /*const*/ CFSMailFolder& aFolder ) const |
306 CFSMailFolder& aFolder ) const |
263 { |
307 { |
264 FUNC_LOG; |
308 FUNC_LOG; |
265 // Load info only necessary for sorting by date into the messages. |
309 // Load info only necessary for sorting by date into the messages. |
266 TFSMailDetails details( EFSMsgDataDate ); |
310 TFSMailDetails details( EFSMsgDataDate ); |
267 |
311 |
271 criteriaDate.iOrder = EFSMailDescending; |
315 criteriaDate.iOrder = EFSMailDescending; |
272 |
316 |
273 RArray<TFSMailSortCriteria> sorting; |
317 RArray<TFSMailSortCriteria> sorting; |
274 CleanupClosePushL( sorting ); |
318 CleanupClosePushL( sorting ); |
275 // First criteria appended would be the primary criteria |
319 // First criteria appended would be the primary criteria |
276 // but here we don't have any other criterias |
320 // but here we don't have any other criteria |
277 sorting.Append( criteriaDate ); |
321 sorting.Append( criteriaDate ); |
278 MFSMailIterator* iterator = aFolder.ListMessagesL( details, sorting ); |
322 MFSMailIterator* iterator = aFolder.ListMessagesL( details, sorting ); |
279 |
323 |
280 // Resetting array of sort criterias already here because |
324 // Resetting array of sort criteria already here because |
281 // the iterator does not need it anymore. |
325 // the iterator does not need it anymore. |
282 CleanupStack::PopAndDestroy(); // sorting |
326 CleanupStack::PopAndDestroy(); // sorting |
283 |
327 |
284 // CleanupStack::PushL doesn't work for M-class |
328 // CleanupStack::PushL doesn't work for M-class |
285 CleanupDeletePushL( iterator ); |
329 CleanupDeletePushL( iterator ); |
301 CleanupStack::PopAndDestroy(); // messages |
345 CleanupStack::PopAndDestroy(); // messages |
302 CleanupStack::PopAndDestroy( iterator ); |
346 CleanupStack::PopAndDestroy( iterator ); |
303 return outcome; |
347 return outcome; |
304 } |
348 } |
305 |
349 |
|
350 CNewMailNotificationTimer::CNewMailNotificationTimer( MFSTimerObserver& aObserver ) : |
|
351 CTimer( EPriorityIdle ), iObserver( aObserver ) |
|
352 { |
|
353 FUNC_LOG; |
|
354 } |
|
355 |
|
356 void CNewMailNotificationTimer::ConstructL() |
|
357 { |
|
358 FUNC_LOG; |
|
359 CTimer::ConstructL(); |
|
360 CActiveScheduler::Add( this ); |
|
361 } |
|
362 |
|
363 CNewMailNotificationTimer* CNewMailNotificationTimer::NewL( |
|
364 MFSTimerObserver& aObserver ) |
|
365 { |
|
366 FUNC_LOG; |
|
367 CNewMailNotificationTimer* self = |
|
368 new( ELeave ) CNewMailNotificationTimer( aObserver ); |
|
369 CleanupStack::PushL( self ); |
|
370 self->ConstructL(); |
|
371 CleanupStack::Pop( self ); |
|
372 return self; |
|
373 } |
|
374 |
|
375 |
|
376 CNewMailNotificationTimer::~CNewMailNotificationTimer() |
|
377 { |
|
378 FUNC_LOG; |
|
379 Cancel(); |
|
380 } |
|
381 |
|
382 void CNewMailNotificationTimer::DoCancel() |
|
383 { |
|
384 FUNC_LOG; |
|
385 // Cancel Base class |
|
386 CTimer::DoCancel(); |
|
387 } |
|
388 |
|
389 void CNewMailNotificationTimer::RunL() |
|
390 { |
|
391 FUNC_LOG; |
|
392 iObserver.TimerExpiredL(); |
|
393 } |
|
394 |
|
395 |
306 void Panic( TCmailhandlerPanic aPanic ) |
396 void Panic( TCmailhandlerPanic aPanic ) |
307 { |
397 { |
308 _LIT( KPanicText, "emailhandlerplugin" ); |
398 _LIT( KPanicText, "emailhandlerplugin" ); |
309 User::Panic( KPanicText, aPanic ); |
399 User::Panic( KPanicText, aPanic ); |
310 } |
400 } |