997 //in rare case that file has disappeared while sending |
997 //in rare case that file has disappeared while sending |
998 //we just won't get the size for it |
998 //we just won't get the size for it |
999 file.Size( fileSize ); |
999 file.Size( fileSize ); |
1000 file.Close(); |
1000 file.Close(); |
1001 |
1001 |
1002 // Initialize CMsvAttachment instance for the attachment creation |
1002 // Take ownership of message entry objects since thanks to |
1003 CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
1003 // "clever" use of active scheduler waits we can re-enter |
1004 CleanupStack::PushL( info ); |
1004 // this function leading to crashes if somebody clears the cache |
1005 |
1005 // while this iteration still needs them |
1006 info->SetAttachmentNameL( aFilePath ); |
1006 TakeMessageEntryLC( aMessageId.Id(), cEntry, message ); |
1007 info->SetSize( fileSize ); |
1007 |
1008 |
|
1009 // Create/acquire Symbian message entry objects |
|
1010 GetMessageEntryL( aMessageId.Id(), cEntry, message ); |
|
1011 |
|
1012 // Operation waiter needed to implement synchronous operation |
1008 // Operation waiter needed to implement synchronous operation |
1013 // on the top of async API |
1009 // on the top of async API |
1014 CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL(); |
1010 CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL(); |
1015 CleanupStack::PushL( waiter ); |
1011 CleanupStack::PushL( waiter ); |
1016 |
1012 |
|
1013 // Initialize CMsvAttachment instance for the attachment creation |
|
1014 CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
1015 CleanupStack::PushL( info ); |
|
1016 info->SetAttachmentNameL( aFilePath ); |
|
1017 info->SetSize( fileSize ); |
|
1018 |
1017 // Start attachment creation |
1019 // Start attachment creation |
1018 message->AttachmentManager().AddAttachmentL( |
1020 message->AttachmentManager().AddAttachmentL( |
1019 aFilePath, info, waiter->iStatus ); |
1021 aFilePath, info, waiter->iStatus ); |
|
1022 CleanupStack::Pop( info ); // attachment manager takes ownership |
1020 |
1023 |
1021 waiter->Start(); |
1024 waiter->Start(); |
1022 CleanupStack::PopAndDestroy( waiter ); |
1025 CleanupStack::PopAndDestroy( waiter ); |
1023 CleanupStack::Pop( info ); // attachment manager takes ownership |
1026 |
|
1027 // Return message entry objects back to cache |
|
1028 CleanupStack::Pop( 2 ); // cEntry, message |
|
1029 ReturnMessageEntry( cEntry, message ); |
1024 |
1030 |
1025 // Dig out the entry ID of the new attachment (unbelievable that |
1031 // Dig out the entry ID of the new attachment (unbelievable that |
1026 // there seems to be no better way to do this) |
1032 // there seems to be no better way to do this) |
1027 message->GetAttachmentsListL( cEntry->Entry().Id( ), |
1033 message->GetAttachmentsListL( cEntry->Entry().Id( ), |
1028 CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly ); |
1034 CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly ); |
1124 CMsvEntry* cEntry( NULL ); |
1130 CMsvEntry* cEntry( NULL ); |
1125 CImEmailMessage* message( NULL ); |
1131 CImEmailMessage* message( NULL ); |
1126 TInt fileSize( 0 ); |
1132 TInt fileSize( 0 ); |
1127 TBuf<KMaxFileName> fileName; |
1133 TBuf<KMaxFileName> fileName; |
1128 |
1134 |
1129 // Create/acquire Symbian message entry objects |
1135 // Take ownership of message entry objects since thanks to |
1130 CleanCachedMessageEntries(); |
1136 // "clever" use of active scheduler waits we can re-enter |
1131 GetMessageEntryL( aMessageId.Id(), cEntry, message ); |
1137 // this function leading to crashes if somebody clears the cache |
1132 |
1138 // while this iteration still needs them |
1133 // Initialize CMsvAttachment instance for the attachment creation |
1139 TakeMessageEntryLC( aMessageId.Id(), cEntry, message ); |
1134 CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
1135 CleanupStack::PushL( info ); |
|
1136 |
|
1137 // Read attachment size |
|
1138 User::LeaveIfError( aFile.Size( fileSize ) ); |
|
1139 info->SetSize( fileSize ); |
|
1140 |
|
1141 // Read attachment filename |
|
1142 User::LeaveIfError( aFile.FullName( fileName ) ); |
|
1143 info->SetAttachmentNameL( fileName ); |
|
1144 |
1140 |
1145 // Operation waiter needed to implement synchronous operation |
1141 // Operation waiter needed to implement synchronous operation |
1146 // on the top of async API |
1142 // on the top of async API |
1147 CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL(); |
1143 CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL(); |
1148 CleanupStack::PushL( waiter ); |
1144 CleanupStack::PushL( waiter ); |
|
1145 |
|
1146 // Initialize CMsvAttachment instance for the attachment creation |
|
1147 CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
1148 CleanupStack::PushL( info ); |
|
1149 |
|
1150 // Read attachment size |
|
1151 User::LeaveIfError( aFile.Size( fileSize ) ); |
|
1152 info->SetSize( fileSize ); |
|
1153 |
|
1154 // Read attachment filename |
|
1155 User::LeaveIfError( aFile.FullName( fileName ) ); |
|
1156 info->SetAttachmentNameL( fileName ); |
|
1157 |
1149 message->AttachmentManager().AddAttachmentL( aFile, info, waiter->iStatus ); |
1158 message->AttachmentManager().AddAttachmentL( aFile, info, waiter->iStatus ); |
|
1159 CleanupStack::Pop( info ); // attachment manager takes ownership |
|
1160 |
1150 waiter->Start(); |
1161 waiter->Start(); |
1151 CleanupStack::PopAndDestroy( waiter ); |
1162 CleanupStack::PopAndDestroy( waiter ); |
1152 CleanupStack::Pop( info ); // attachment manager takes ownership |
1163 |
|
1164 // Return message entry objects back to cache |
|
1165 CleanupStack::Pop( 2 ); // cEntry, message |
|
1166 ReturnMessageEntry( cEntry, message ); |
1153 |
1167 |
1154 // Dig out the entry ID of the new attachment |
1168 // Dig out the entry ID of the new attachment |
1155 message->GetAttachmentsListL( cEntry->Entry().Id( ), |
1169 message->GetAttachmentsListL( cEntry->Entry().Id( ), |
1156 CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly ); |
1170 CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly ); |
1157 TKeyArrayFix key( 0, ECmpTInt32 ); |
1171 TKeyArrayFix key( 0, ECmpTInt32 ); |
1267 |
1281 |
1268 if ( ( status == KErrNone ) && |
1282 if ( ( status == KErrNone ) && |
1269 ( tEntry.iType == KUidMsvAttachmentEntry ) ) |
1283 ( tEntry.iType == KUidMsvAttachmentEntry ) ) |
1270 { |
1284 { |
1271 CImEmailMessage* message( NULL ); |
1285 CImEmailMessage* message( NULL ); |
|
1286 |
1272 // We trust that the message ID really refers to a message |
1287 // We trust that the message ID really refers to a message |
1273 GetMessageEntryL( aMessageId.Id(), cEntry, message ); |
1288 |
|
1289 // Take ownership of message entry objects since thanks to |
|
1290 // "clever" use of active scheduler waits we can re-enter |
|
1291 // this function leading to crashes if somebody clears the cache |
|
1292 // while this iteration still needs them |
|
1293 TakeMessageEntryLC( aMessageId.Id(), cEntry, message ); |
1274 |
1294 |
1275 MMsvAttachmentManager& attachmentMgr( message->AttachmentManager() ); |
1295 MMsvAttachmentManager& attachmentMgr( message->AttachmentManager() ); |
1276 |
1296 |
1277 CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL(); |
1297 CIpsPlgOperationWait* waiter = CIpsPlgOperationWait::NewL(); |
1278 CleanupStack::PushL( waiter ); |
1298 CleanupStack::PushL( waiter ); |
1280 attachmentMgr.RemoveAttachmentL( |
1300 attachmentMgr.RemoveAttachmentL( |
1281 (TMsvAttachmentId) aPartId.Id(), waiter->iStatus ); |
1301 (TMsvAttachmentId) aPartId.Id(), waiter->iStatus ); |
1282 |
1302 |
1283 waiter->Start(); |
1303 waiter->Start(); |
1284 CleanupStack::PopAndDestroy( waiter ); |
1304 CleanupStack::PopAndDestroy( waiter ); |
|
1305 |
|
1306 // Return message entry objects to cache |
|
1307 CleanupStack::Pop( 2 ); // cEntry, message |
|
1308 ReturnMessageEntry( cEntry, message ); |
1285 } |
1309 } |
1286 else if ( ( status == KErrNone ) && |
1310 else if ( ( status == KErrNone ) && |
1287 ( tEntry.iType == KUidMsvFolderEntry ) ) |
1311 ( tEntry.iType == KUidMsvFolderEntry ) ) |
1288 { |
1312 { |
1289 cEntry = iSession->GetEntryL( tEntry.Parent() ); |
1313 cEntry = iSession->GetEntryL( tEntry.Parent() ); |
1460 { |
1484 { |
1461 FUNC_LOG; |
1485 FUNC_LOG; |
1462 CMsvEntry* cEntry( NULL ); |
1486 CMsvEntry* cEntry( NULL ); |
1463 CImEmailMessage* message( NULL ); |
1487 CImEmailMessage* message( NULL ); |
1464 |
1488 |
1465 // We trust that the message ID really refers to a message |
1489 // Take ownership of message entry objects since thanks to |
1466 GetMessageEntryL( aMessageId.Id(), cEntry, message ); |
1490 // "clever" use of active scheduler waits we can re-enter |
|
1491 // this function leading to crashes if somebody clears the cache |
|
1492 // while this iteration still needs them |
|
1493 TakeMessageEntryLC( aMessageId.Id(), cEntry, message ); |
|
1494 |
1467 if ( message ) |
1495 if ( message ) |
1468 { |
1496 { |
1469 |
1497 |
1470 message->GetBodyTextEntryIdL( |
1498 message->GetBodyTextEntryIdL( |
1471 cEntry->Entry().Id(), CImEmailMessage::EThisMessageOnly ); |
1499 cEntry->Entry().Id(), CImEmailMessage::EThisMessageOnly ); |
1494 wait->Start(); |
1522 wait->Start(); |
1495 CleanupStack::PopAndDestroy( 4, wait ); |
1523 CleanupStack::PopAndDestroy( 4, wait ); |
1496 } |
1524 } |
1497 } |
1525 } |
1498 } |
1526 } |
|
1527 |
|
1528 // Return message entry objects to cache |
|
1529 CleanupStack::Pop( 2 ); // cEntry, message |
|
1530 ReturnMessageEntry( cEntry, message ); |
1499 } |
1531 } |
1500 |
1532 |
1501 // ---------------------------------------------------------------------------- |
1533 // ---------------------------------------------------------------------------- |
1502 // ---------------------------------------------------------------------------- |
1534 // ---------------------------------------------------------------------------- |
1503 void CIpsPlgSosBasePlugin::RemovePartContentL( |
1535 void CIpsPlgSosBasePlugin::RemovePartContentL( |
1913 } |
1945 } |
1914 aMessageEntry = iCachedEntry; |
1946 aMessageEntry = iCachedEntry; |
1915 aImEmailMessage = iCachedEmailMessage; |
1947 aImEmailMessage = iCachedEmailMessage; |
1916 } |
1948 } |
1917 |
1949 |
|
1950 |
|
1951 // ---------------------------------------------------------------------------- |
|
1952 // CIpsPlgSosBasePlugin::TakeMessageEntryL( ) |
|
1953 // Takes ownership of the cached objects or creates new ones |
|
1954 // ---------------------------------------------------------------------------- |
|
1955 |
|
1956 void CIpsPlgSosBasePlugin::TakeMessageEntryLC( |
|
1957 TMsvId aId, |
|
1958 CMsvEntry*& aMessageEntry, |
|
1959 CImEmailMessage*& aImEmailMessage ) |
|
1960 { |
|
1961 FUNC_LOG; |
|
1962 if ( !iCachedEntry || ( aId != iCachedEntry->Entry().Id() ) || |
|
1963 iCachedEmailMessage->IsActive() ) |
|
1964 { |
|
1965 // Can't use the ones that are in cache, create new ones and don't replace the ones in cache |
|
1966 aMessageEntry = iSession->GetEntryL( aId ); |
|
1967 aImEmailMessage = 0; |
|
1968 |
|
1969 if ( aMessageEntry->Entry().iType == KUidMsvMessageEntry ) |
|
1970 { |
|
1971 CleanupStack::PushL( aMessageEntry ); |
|
1972 aImEmailMessage = CImEmailMessage::NewL( *aMessageEntry ); |
|
1973 CleanupStack::Pop(); |
|
1974 } |
|
1975 } |
|
1976 else |
|
1977 { |
|
1978 // Take ownership of the cached objects |
|
1979 aMessageEntry = iCachedEntry; |
|
1980 aImEmailMessage = iCachedEmailMessage; |
|
1981 iCachedEntry = 0; |
|
1982 iCachedEmailMessage = 0; |
|
1983 } |
|
1984 |
|
1985 // Ownership is transferred to the caller |
|
1986 CleanupStack::PushL( aMessageEntry ); |
|
1987 CleanupStack::PushL( aImEmailMessage ); |
|
1988 } |
|
1989 |
|
1990 // ---------------------------------------------------------------------------- |
|
1991 // ---------------------------------------------------------------------------- |
|
1992 void CIpsPlgSosBasePlugin::ReturnMessageEntry( |
|
1993 CMsvEntry* aMessageEntry, |
|
1994 CImEmailMessage* aImEmailMessage ) |
|
1995 { |
|
1996 // Clean old ones from the cache |
|
1997 CleanCachedMessageEntries(); |
|
1998 |
|
1999 // Always save the latest ones in the cache |
|
2000 iCachedEntry = aMessageEntry; |
|
2001 iCachedEmailMessage = aImEmailMessage; |
|
2002 } |
|
2003 |
1918 // ---------------------------------------------------------------------------- |
2004 // ---------------------------------------------------------------------------- |
1919 // ---------------------------------------------------------------------------- |
2005 // ---------------------------------------------------------------------------- |
1920 // |
2006 // |
1921 void CIpsPlgSosBasePlugin::CleanCachedMessageEntries() |
2007 void CIpsPlgSosBasePlugin::CleanCachedMessageEntries() |
1922 { |
2008 { |