emailuis/emailui/src/FreestyleEmailUiHtmlViewerContainer.cpp
branchRCL_3
changeset 12 4ce476e64c59
parent 11 0396474f30f5
child 13 8592a65ad3fb
equal deleted inserted replaced
11:0396474f30f5 12:4ce476e64c59
    71 _LIT( KCharsetTag, "charset");
    71 _LIT( KCharsetTag, "charset");
    72 _LIT8( KHTMLEmptyContent, "<HTML><BODY></BODY></HTML>");
    72 _LIT8( KHTMLEmptyContent, "<HTML><BODY></BODY></HTML>");
    73 _LIT( KHTMLDataScheme, "data:0");
    73 _LIT( KHTMLDataScheme, "data:0");
    74 
    74 
    75 
    75 
    76 _LIT8( KHtmlLineBreak, "<br>" );
    76 _LIT( KHtmlLineBreak, "<br>" );
    77 _LIT8( KHtmlLineBreakCRLF, "<br>\xD\xA" );
    77 _LIT( KHtmlLineBreakCRLF, "<br>\xD\xA" );
    78 _LIT8( KHtmlLessThan, "&lt;" );
    78 _LIT( KHtmlLessThan, "&lt;" );
    79 _LIT8( KHtmlGreaterThan, "&gt;" );
    79 _LIT( KHtmlGreaterThan, "&gt;" );
    80 _LIT8( KHtmlAmpersand, "&amp;" );
    80 _LIT( KHtmlAmpersand, "&amp;" );
    81 _LIT8( KHtmlQuotation, "&quot;" );
    81 _LIT( KHtmlQuotation, "&quot;" );
    82 _LIT8( KHtmlLinkTag, "<a href=\"%S\">" );
    82 _LIT( KHtmlLinkTag, "<a href=\"%S\">" );
    83 _LIT8( KHtmlLinkTagWWW, "<a href=\"%S%S\">" );
    83 _LIT( KHtmlLinkTagWWW, "<a href=\"%S%S\">" );
    84 _LIT8( KHtmlLinkEndTag, "</a>" );
    84 _LIT( KHtmlLinkEndTag, "</a>" );
    85 _LIT( KURLTypeBody, "body");
    85 _LIT( KURLTypeBody, "body");
    86 
    86 
    87 _LIT( KURLDisplayImages, "cmail://displayImages/" );
    87 _LIT( KURLDisplayImages, "cmail://displayImages/" );
    88 _LIT( KURLLoadImages, "cmail://loadImages/" );
    88 _LIT( KURLLoadImages, "cmail://loadImages/" );
    89 _LIT( KURLCollapseHeader, "cmail://collapseHeader/" );
    89 _LIT( KURLCollapseHeader, "cmail://collapseHeader/" );
    90 _LIT( KURLExpandHeader, "cmail://expandHeader/" );
    90 _LIT( KURLExpandHeader, "cmail://expandHeader/" );
    91 
    91 
    92 const TText8 KGreaterThan = 0x3e;
    92 const TText KGreaterThan = 0x3e;
    93 const TText8 KLessThan = 0x3c;
    93 const TText KLessThan = 0x3c;
    94 const TText8 KAmpersand = 0x26;
    94 const TText KAmpersand = 0x26;
    95 const TText8 KQuotation = 0x22;
    95 const TText KQuotation = 0x22;
    96 const TText8 KCharacterSpace = 0x20;
    96 const TText KCharacterSpace = 0x20;
    97 const TText8 KSOH = 0x01; // Start Of Heading
    97 const TText KSOH = 0x01; // Start Of Heading
    98 const TText8 KCR = 0x0d; // Carriage Return
    98 const TText KCR = 0x0d; // Carriage Return
    99 const TText8 KLF = 0x0a; // Line Feed
    99 const TText KLF = 0x0a; // Line Feed
   100 const TText8 KHT = 0x09; // Horizontal Tab
   100 const TText KHT = 0x09; // Horizontal Tab
       
   101 const TText KUnicodeNewLineCharacter = 0x2028;
       
   102 const TText KUnicodeParagraphCharacter = 0x2029;        
   101 const TReal KOverlayButtonMarginX = 0.01; // 1%
   103 const TReal KOverlayButtonMarginX = 0.01; // 1%
   102 const TReal KOverlayButtonMarginY = 0.01; // 1%
   104 const TReal KOverlayButtonMarginY = 0.01; // 1%
   103 const TReal KOverlayButtonSizeP = 0.15; // 15%
   105 const TReal KOverlayButtonSizeP = 0.15; // 15%
   104 const TReal KOverlayButtonSizeLs = 0.20; // 25%
   106 const TReal KOverlayButtonSizeLs = 0.20; // 25%
   105 
   107 
  1016     HBufC* content = HBufC::NewLC( aTextBodyPart.FetchedContentSize() );
  1018     HBufC* content = HBufC::NewLC( aTextBodyPart.FetchedContentSize() );
  1017     TPtr contentPtr( content->Des() );
  1019     TPtr contentPtr( content->Des() );
  1018     
  1020     
  1019     aTextBodyPart.GetContentToBufferL( contentPtr, 0 );
  1021     aTextBodyPart.GetContentToBufferL( contentPtr, 0 );
  1020     
  1022     
  1021     HBufC8* content8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *content );
  1023     ConvertToHTML( *content, targetFileName, aTextBodyPart );
  1022     
  1024     
  1023     CleanupStack::PopAndDestroy( content );
  1025     CleanupStack::PopAndDestroy( content );
  1024     CleanupStack::PushL( content8 );
  1026 
  1025         
       
  1026     ConvertToHTML( *content8, targetFileName, aTextBodyPart );
       
  1027 
       
  1028     CleanupStack::PopAndDestroy( content8 );
       
  1029     
       
  1030     }
  1027     }
  1031 
  1028 
  1032 // ---------------------------------------------------------------------------
  1029 // ---------------------------------------------------------------------------
  1033 // Reads given file content to buffer and return pointer to it
  1030 // Reads given file content to buffer and return pointer to it
  1034 // ---------------------------------------------------------------------------
  1031 // ---------------------------------------------------------------------------
  1240         CleanupStack::PopAndDestroy( &attachmentFile );
  1237         CleanupStack::PopAndDestroy( &attachmentFile );
  1241         }
  1238         }
  1242     else
  1239     else
  1243         {
  1240         {
  1244         TPartData partData;
  1241         TPartData partData;
  1245         partData.iMailBoxId = iMessage->GetMailBoxId();
  1242         if( iMessage )
  1246         partData.iFolderId = iMessage->GetFolderId();
  1243             {
  1247         partData.iMessageId = iMessage->GetMessageId();
  1244             partData.iMailBoxId = iMessage->GetMailBoxId();
  1248         partData.iMessagePartId = aAttachment.GetPartId();
  1245             partData.iFolderId = iMessage->GetFolderId();
  1249 
  1246             partData.iMessageId = iMessage->GetMessageId();
  1250         if ( iAppUi.DownloadInfoMediator() &&
  1247             
  1251              iAppUi.DownloadInfoMediator()->IsDownloadableL( partData ) )
  1248             partData.iMessagePartId = aAttachment.GetPartId();
  1252             {
  1249 
  1253             ASSERT( iLinkContents.Count() == iMessageParts.Count() );
  1250             if ( iAppUi.DownloadInfoMediator() &&
  1254 
  1251                  iAppUi.DownloadInfoMediator()->IsDownloadableL( partData ) )
  1255             // Append message part details and embedded link content interface
       
  1256             // to corresponding arrays so that the content can be returned
       
  1257             // when the download is completed.
       
  1258             iLinkContents.AppendL( &aEmbeddedLinkContent );
       
  1259             if ( iMessageParts.Append( partData ) != KErrNone )
       
  1260                 {
  1252                 {
  1261                 iLinkContents.Remove( iLinkContents.Count() - 1 );
  1253                 ASSERT( iLinkContents.Count() == iMessageParts.Count() );
  1262                 }
  1254     
  1263 
  1255                 // Append message part details and embedded link content interface
  1264             ASSERT( iLinkContents.Count() == iMessageParts.Count() );
  1256                 // to corresponding arrays so that the content can be returned
  1265             if(!iView.GetAsyncFetchStatus())
  1257                 // when the download is completed.
  1266                 {
  1258                 iLinkContents.AppendL( &aEmbeddedLinkContent );
  1267                 iAppUi.DownloadInfoMediator()->AddObserver( this, aAttachment.GetMessageId() );
  1259                 if ( iMessageParts.Append( partData ) != KErrNone )
  1268                 iObservingDownload=ETrue;
  1260                     {
  1269                 iAppUi.DownloadInfoMediator()->DownloadL( partData, EFalse );
  1261                     iLinkContents.Remove( iLinkContents.Count() - 1 );
       
  1262                     }
       
  1263     
       
  1264                 ASSERT( iLinkContents.Count() == iMessageParts.Count() );
       
  1265                 if(!iView.GetAsyncFetchStatus())
       
  1266                     {
       
  1267                     iAppUi.DownloadInfoMediator()->AddObserver( this, aAttachment.GetMessageId() );
       
  1268                     iObservingDownload=ETrue;
       
  1269                     iAppUi.DownloadInfoMediator()->DownloadL( partData, EFalse );
       
  1270                     }
  1270                 }
  1271                 }
  1271             }
  1272             }
  1272         }
  1273         }
  1273     }
  1274     }
  1274 
  1275 
  1350 // ---------------------------------------------------------------------------
  1351 // ---------------------------------------------------------------------------
  1351 // Writes buffer content to given file after adding tags
  1352 // Writes buffer content to given file after adding tags
  1352 // ---------------------------------------------------------------------------
  1353 // ---------------------------------------------------------------------------
  1353 //
  1354 //
  1354 // <cmail>
  1355 // <cmail>
  1355 void CFsEmailUiHtmlViewerContainer::ConvertToHTML( const TDesC8& aContent,
  1356 void CFsEmailUiHtmlViewerContainer::ConvertToHTML( const TDesC& aContent,
  1356     const TDesC& aFileName, CFSMailMessagePart& /*aTextBodyPart*/ )
  1357     const TDesC& aFileName, CFSMailMessagePart& /*aTextBodyPart*/ )
  1357     {
  1358     {
  1358     FUNC_LOG;
  1359     FUNC_LOG;
  1359     const TInt KBodyTextChunkSizeBytes = 1024;
  1360     const TInt KBodyTextChunkSize = 2048;
  1360     
  1361     
  1361     if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aContent.Size(), EDriveC ) )
  1362     if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aContent.Size(), EDriveC ) )
  1362          {
  1363          {
  1363          // Can not write the data, there's not enough free space on disk.
  1364          // Can not write the data, there's not enough free space on disk.
  1364          User::Leave( KErrDiskFull );
  1365          User::Leave( KErrDiskFull );
  1365         }
  1366         }
  1366     else
  1367     else
  1367         {
  1368         {
  1368         CBufBase* bodyBuf = CBufSeg::NewL( KBodyTextChunkSizeBytes );
  1369         RBuf bodyBuf;
  1369         CleanupStack::PushL( bodyBuf );
  1370         bodyBuf.CreateL( aContent.Size() + KBodyTextChunkSize );
  1370         
  1371         bodyBuf.CleanupClosePushL();
  1371         bodyBuf->InsertL( 0, aContent );
  1372         bodyBuf.Insert( 0, aContent);
       
  1373         TInt maxlength = bodyBuf.MaxSize();
  1372         
  1374         
  1373         TInt position( 0 );
  1375         TInt position( 0 );
  1374         TText8 previous = 0;
  1376         TText previous = 0;
  1375         TBool EndOfString( EFalse );
  1377         TBool EndOfString( EFalse );
  1376         
  1378         
  1377         while ( !EndOfString )
  1379         while ( !EndOfString )
  1378             {
  1380             {
  1379             TInt startPosition = position;
  1381             TInt startPosition = position;
  1380             TPtr8 segment( bodyBuf->Ptr( startPosition ) );
  1382             TPtr segment( bodyBuf.MidTPtr( startPosition ) );
  1381             int i = 0;
  1383             TInt i = 0;
  1382             
  1384             
  1383             while(i < segment.Length())
  1385             while(i < segment.Length())
  1384                 {
  1386                 {
  1385                 TInt currentPos = position + i;
  1387                 TInt currentPos = position + i;
  1386                 TText8 ch = segment[i];
  1388                 TText ch = segment[i];
  1387                 
  1389                 
  1388                 switch( ch )
  1390                 switch( ch )
  1389                     {
  1391                     {
  1390                     case KSOH:  // end of line for IMAP and POP
  1392                     case KSOH:  // end of line for IMAP and POP
  1391                         bodyBuf->Delete( currentPos, 1 );
  1393                         bodyBuf.Delete( currentPos, 1 );
  1392                         bodyBuf->InsertL( currentPos, KHtmlLineBreakCRLF );
  1394                         maxlength = maxlength + KHtmlLineBreakCRLF().Length();
       
  1395                         bodyBuf.ReAlloc( maxlength );
       
  1396                         bodyBuf.Insert( currentPos, KHtmlLineBreakCRLF );
  1393                         i += KHtmlLineBreakCRLF().Length();
  1397                         i += KHtmlLineBreakCRLF().Length();
  1394                         segment.Set( bodyBuf->Ptr( startPosition ) );
  1398                         segment.Set( bodyBuf.MidTPtr( startPosition ) );
  1395                         break;
  1399                         break;
  1396                     case KLF: // line feed
  1400                     case KLF: // line feed
  1397                         if ( previous == KCR )
  1401                     case KUnicodeNewLineCharacter:
  1398                             {
  1402                     case KUnicodeParagraphCharacter:
  1399                             bodyBuf->InsertL( currentPos, KHtmlLineBreak );
  1403                             maxlength = maxlength + KHtmlLineBreak().Length();
  1400                             i += KHtmlLineBreak().Length();
  1404                             bodyBuf.ReAlloc( maxlength );
  1401                             segment.Set( bodyBuf->Ptr( startPosition ) );
  1405                             bodyBuf.Insert( currentPos, KHtmlLineBreak );
  1402                             }
  1406                             i += KHtmlLineBreak().Length() + 1;
  1403                         else
  1407                             segment.Set( bodyBuf.MidTPtr( startPosition ) );
  1404                             {
       
  1405                             i++;
       
  1406                             }
       
  1407                         break;  
  1408                         break;  
  1408                     case KQuotation:
  1409                     case KQuotation:
  1409                         bodyBuf->Delete( currentPos, 1 );
  1410                         bodyBuf.Delete( currentPos, 1 );
  1410                         bodyBuf->InsertL( currentPos, KHtmlQuotation );
  1411                         maxlength = maxlength + KHtmlQuotation().Length();
       
  1412                         bodyBuf.ReAlloc( maxlength );
       
  1413                         bodyBuf.Insert( currentPos, KHtmlQuotation );
  1411                         i += KHtmlQuotation().Length();
  1414                         i += KHtmlQuotation().Length();
  1412                         segment.Set( bodyBuf->Ptr( startPosition ) );
  1415                         segment.Set( bodyBuf.MidTPtr( startPosition ) );
  1413                         break;
  1416                         break;
  1414                     case KAmpersand:
  1417                     case KAmpersand:
  1415                         bodyBuf->Delete( currentPos, 1 );
  1418                         bodyBuf.Delete( currentPos, 1 );
  1416                         bodyBuf->InsertL( currentPos, KHtmlAmpersand );
  1419                         maxlength = maxlength + KHtmlAmpersand().Length();
       
  1420                         bodyBuf.ReAlloc( maxlength  );
       
  1421                         bodyBuf.Insert( currentPos, KHtmlAmpersand );
  1417                         i += KHtmlAmpersand().Length();
  1422                         i += KHtmlAmpersand().Length();
  1418                         segment.Set( bodyBuf->Ptr( startPosition ) );
  1423                         segment.Set( bodyBuf.MidTPtr( startPosition ) );
  1419                         break;
  1424                         break;
  1420                     case KGreaterThan:
  1425                     case KGreaterThan:
  1421                         bodyBuf->Delete( currentPos, 1 );
  1426                         bodyBuf.Delete( currentPos, 1 );
  1422                         bodyBuf->InsertL( currentPos, KHtmlGreaterThan );
  1427                         maxlength = maxlength + KHtmlGreaterThan().Length();
       
  1428                         bodyBuf.ReAlloc( maxlength );
       
  1429                         bodyBuf.Insert( currentPos, KHtmlGreaterThan );
  1423                         i += KHtmlGreaterThan().Length();
  1430                         i += KHtmlGreaterThan().Length();
  1424                         segment.Set( bodyBuf->Ptr( startPosition ) );
  1431                         segment.Set( bodyBuf.MidTPtr( startPosition ) );
  1425                         break;
  1432                         break;
  1426                     case KLessThan:
  1433                     case KLessThan:
  1427                         bodyBuf->Delete( currentPos, 1 );
  1434                         bodyBuf.Delete( currentPos, 1 );
  1428                         bodyBuf->InsertL( currentPos, KHtmlLessThan );
  1435                         maxlength =  maxlength + KHtmlLessThan().Length();
       
  1436                         bodyBuf.ReAlloc( maxlength );
       
  1437                         bodyBuf.Insert( currentPos, KHtmlLessThan );
  1429                         i += KHtmlLessThan().Length();
  1438                         i += KHtmlLessThan().Length();
  1430                         segment.Set( bodyBuf->Ptr( startPosition ) );
  1439                         segment.Set( bodyBuf.MidTPtr( startPosition ) );
  1431                         break;
  1440                         break;
  1432                     default:
  1441                     default:
  1433                         i++;
  1442                         i++;
  1434                         break;
  1443                         break;
  1435                     }
  1444                     }
  1436                 previous = ch;
  1445                 previous = ch;
  1437                 }
  1446                 }
  1438             position += segment.Length();
  1447             position += segment.Length();
  1439             if ( ( bodyBuf->Size() - position ) <= 0 )
  1448             if ( ( bodyBuf.Length() - position ) <= 0 )
  1440                 {
  1449                 {
  1441                 EndOfString = ETrue;
  1450                 EndOfString = ETrue;
  1442                 }
  1451                 }
  1443             }
  1452             }
  1444         
  1453         
  1445         CreateHyperlinksFromUrlsL( *bodyBuf );
  1454         CreateHyperlinksFromUrlsL( bodyBuf );
       
  1455         
       
  1456         HBufC8* content8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( bodyBuf );
       
  1457         CleanupStack::PushL( content8 );        
  1446         
  1458         
  1447         RFile targetFile;
  1459         RFile targetFile;
  1448         CleanupClosePushL( targetFile );
  1460         CleanupClosePushL( targetFile );
  1449         User::LeaveIfError( targetFile.Replace( iFs, aFileName, EFileWrite ) );
  1461         User::LeaveIfError( targetFile.Replace( iFs, aFileName, EFileWrite ) );
  1450         
  1462         
  1451         RBuf8 messageHeader;
  1463         RBuf8 messageHeader;
  1452         _LIT8( KCharsetUtf8, "UTF-8" );
  1464         _LIT( KCharsetUtf8, "UTF-8" );
  1453         TInt bufSize = KHtmlHeader1().Length() + KCharsetUtf8().Length() + KHtmlHeader2().Length();
  1465         TInt bufSize = KHtmlHeader1().Length() + KCharsetUtf8().Length() + KHtmlHeader2().Length();
  1454         messageHeader.CreateL( bufSize );
  1466         messageHeader.CreateL( bufSize );
  1455         messageHeader.CleanupClosePushL();
  1467         messageHeader.CleanupClosePushL();
  1456         
  1468         
  1457         messageHeader.Append( KHtmlHeader1 );
  1469         messageHeader.Append( KHtmlHeader1 );
  1461         RFileWriteStream fileStream( targetFile );
  1473         RFileWriteStream fileStream( targetFile );
  1462         fileStream.PushL();
  1474         fileStream.PushL();
  1463         fileStream.WriteL( messageHeader.Ptr(), messageHeader.Length() );
  1475         fileStream.WriteL( messageHeader.Ptr(), messageHeader.Length() );
  1464 
  1476 
  1465         TInt bufPos( 0 );
  1477         TInt bufPos( 0 );
  1466         TInt bufTotalSize = bodyBuf->Size();
  1478         TInt bufTotalSize = content8->Size();
  1467 
  1479 
  1468         while ( bufPos < bufTotalSize )
  1480         while ( bufPos < bufTotalSize )
  1469             {
  1481             {
  1470             TInt segmentLength = bodyBuf->Ptr( bufPos ).Length();
  1482             TInt segmentLength = content8->Mid( bufPos ).Length();
  1471             fileStream.WriteL( bodyBuf->Ptr( bufPos ).Ptr(), segmentLength );
  1483             fileStream.WriteL( content8->Mid( bufPos ).Ptr(), segmentLength );
  1472             bufPos += segmentLength;
  1484             bufPos += segmentLength;
  1473             }
  1485             }
  1474 
  1486 
  1475         fileStream.CommitL();
  1487         fileStream.CommitL();
  1476 
  1488 
  1477         CleanupStack::PopAndDestroy( &fileStream );
  1489         CleanupStack::PopAndDestroy( &fileStream );
  1478         CleanupStack::PopAndDestroy( &messageHeader );
  1490         CleanupStack::PopAndDestroy( &messageHeader );
  1479         CleanupStack::PopAndDestroy( &targetFile );
  1491         CleanupStack::PopAndDestroy( &targetFile );
  1480         CleanupStack::PopAndDestroy( bodyBuf );
  1492         CleanupStack::PopAndDestroy( content8 );
       
  1493         CleanupStack::PopAndDestroy( &bodyBuf ); // calls bodyBuf.Close();
  1481 
  1494 
  1482 // </cmail>
  1495 // </cmail>
  1483         }
  1496         }
  1484     }
  1497     }
  1485 
  1498 
  1486 // ---------------------------------------------------------------------------
  1499 // ---------------------------------------------------------------------------
  1487 // Finds and html formats hyperlinks in a document
  1500 // Finds and html formats hyperlinks in a document
  1488 // ---------------------------------------------------------------------------
  1501 // ---------------------------------------------------------------------------
  1489 //
  1502 //
  1490 // <cmail>
  1503 // <cmail>
  1491 void CFsEmailUiHtmlViewerContainer::CreateHyperlinksFromUrlsL( CBufBase& aSource )
  1504 void CFsEmailUiHtmlViewerContainer::CreateHyperlinksFromUrlsL( RBuf& aSource )
  1492     {
  1505     {
  1493     FUNC_LOG;
  1506     FUNC_LOG;
  1494     const TInt urlMaxLength = 2048;
  1507     const TInt urlMaxLength = 2048;
  1495     _LIT8( KHttp, "http://" );
  1508     _LIT( KHttp, "http://" );
  1496     _LIT8( KHttps, "https://");
  1509     _LIT( KHttps, "https://");
  1497     _LIT8( KWww, "www."); 
  1510     _LIT( KWww, "www."); 
  1498     
  1511     
  1499     TBool eos( aSource.Size() <= 0 );
  1512     TBool eos( aSource.Size() <= 0 );
  1500     TInt position( 0 );
  1513     TInt position( 0 );
  1501     TInt carryOverInc( 0 );
  1514     TInt carryOverInc( 0 );
  1502     
  1515     TInt maxlength = aSource.Length();
  1503     while ( !eos )
  1516     while ( !eos )
  1504         {
  1517         {
  1505         while ( carryOverInc >= aSource.Ptr( position ).Length() && aSource.Size() != 0 )
  1518         while ( carryOverInc >= aSource.MidTPtr( position ).Length() && aSource.Size() != 0 )
  1506             { // Skip segments of overlapping url string
  1519             { // Skip segments of overlapping url string
  1507             carryOverInc -= aSource.Ptr( position ).Length();
  1520             carryOverInc -= aSource.MidTPtr( position ).Length();
  1508             position += aSource.Ptr( position ).Length();
  1521             position += aSource.MidTPtr( position ).Length();
  1509             }
  1522             }
  1510         
  1523         
  1511         TPtr8 segment( aSource.Ptr( position ) );
  1524         TPtr16 segment( aSource.MidTPtr( position ) );
  1512         TLex8 lexSegment( segment );
  1525         TLex16 lexSegment( segment );
  1513         lexSegment.Inc( carryOverInc );
  1526         lexSegment.Inc( carryOverInc );
  1514         carryOverInc = 0;
  1527         carryOverInc = 0;
  1515         
  1528         
  1516         while (!lexSegment.Eos())
  1529         while (!lexSegment.Eos())
  1517             {
  1530             {
  1518             TPtrC8 nextToken( lexSegment.NextToken() );
  1531             TPtrC nextToken( lexSegment.NextToken() );
  1519             TInt foundAt( KErrNotFound );
  1532             TInt foundAt( KErrNotFound );
  1520             
  1533             
  1521             // Find HTTP, HTTPS, or WWW link in CBufSeg segment of size 1024 bytes.
  1534             // Find HTTP, HTTPS, or WWW link in CBufSeg segment of size 1024 bytes.
  1522             if ( ( ( foundAt = nextToken.FindC( KHttp ) ) != KErrNotFound ) ||
  1535             if ( ( ( foundAt = nextToken.FindC( KHttp ) ) != KErrNotFound ) ||
  1523                     (  ( foundAt = nextToken.FindC( KHttps ) ) != KErrNotFound ) ||
  1536                     (  ( foundAt = nextToken.FindC( KHttps ) ) != KErrNotFound ) ||
  1525                 {
  1538                 {
  1526                 if ( !lexSegment.Eos() )
  1539                 if ( !lexSegment.Eos() )
  1527                     { 
  1540                     { 
  1528                     if ( !foundAt )
  1541                     if ( !foundAt )
  1529                         { // Token starts with http/https/www.x
  1542                         { // Token starts with http/https/www.x
  1530                         TPtrC8 url;
  1543                         TPtrC url;
  1531                         TInt lineBreakPos( KErrNotFound );
  1544                         TInt lineBreakPos( KErrNotFound );
  1532                         if ( ( lineBreakPos = nextToken.FindC( KHtmlLineBreak ) ) != KErrNotFound )
  1545                         if ( ( lineBreakPos = nextToken.FindC( KHtmlLineBreak ) ) != KErrNotFound )
  1533                             { // Token contains html line break -> remove
  1546                             { // Token contains html line break -> remove
  1534                             url.Set( nextToken.Left( lineBreakPos ) );
  1547                             url.Set( nextToken.Left( lineBreakPos ) );
  1535                             }
  1548                             }
  1538                             url.Set( nextToken );
  1551                             url.Set( nextToken );
  1539                             }
  1552                             }
  1540                         
  1553                         
  1541                         if ( url.CompareC( KWww ) != KErrNone ) // if token=www., validate format 
  1554                         if ( url.CompareC( KWww ) != KErrNone ) // if token=www., validate format 
  1542                             {                                   // www.x
  1555                             {                                   // www.x
  1543                             RBuf8 urlBuf;
  1556                             RBuf urlBuf;
  1544                             TBool wwwLink( EFalse );
  1557                             TBool wwwLink( EFalse );
  1545                             if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 )
  1558                             if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 )
  1546                                 {
  1559                                 {
  1547                                 wwwLink = ETrue;
  1560                                 wwwLink = ETrue;
  1548                                 //Hyperlinks beginning with www. needs http:// prefix
  1561                                 //Hyperlinks beginning with www. needs http:// prefix
  1575                             TInt segOffset = lexSegment.Offset();
  1588                             TInt segOffset = lexSegment.Offset();
  1576                             TInt urlLength = urlBuf.Length();
  1589                             TInt urlLength = urlBuf.Length();
  1577                             
  1590                             
  1578                             //Test
  1591                             //Test
  1579                             TInt offset = lexSegment.Offset() - nextToken.Length();
  1592                             TInt offset = lexSegment.Offset() - nextToken.Length();
  1580                             TLexMark8 tokenMark;
  1593                             TLexMark tokenMark;
  1581                             // Move next character last token back
  1594                             // Move next character last token back
  1582                             lexSegment.Inc( - nextToken.Length() );
  1595                             lexSegment.Inc( - nextToken.Length() );
  1583                             lexSegment.Mark( tokenMark );
  1596                             lexSegment.Mark( tokenMark );
  1584                             aSource.Delete( offset + position, nextToken.Length() );
  1597                             aSource.Delete( offset + position, nextToken.Length() );
  1585                             aSource.InsertL( offset + position, urlBuf );
  1598                             aSource.ReAlloc( maxlength + urlBuf.Length() );
  1586                             segment.Set( aSource.Ptr( position ) );
  1599                             aSource.Insert( offset + position, urlBuf );
       
  1600                             segment.Set( aSource.MidTPtr( position ) );
  1587                             lexSegment.Assign( segment );
  1601                             lexSegment.Assign( segment );
  1588                             // Set next character to the position of inserted hyperlink
  1602                             // Set next character to the position of inserted hyperlink
  1589                             lexSegment.UnGetToMark( tokenMark );
  1603                             lexSegment.UnGetToMark( tokenMark );
  1590                             
  1604                             
  1591                             // If Max segment length is reached, set carry over value to 
  1605                             // If Max segment length is reached, set carry over value to 
  1608                         }
  1622                         }
  1609                     }
  1623                     }
  1610                 else
  1624                 else
  1611                     // Next token is end of string, here we handle the last token of a segment
  1625                     // Next token is end of string, here we handle the last token of a segment
  1612                     {
  1626                     {
  1613                     _LIT8( KUrlEnd, "<" );
  1627                     _LIT( KUrlEnd, "<" );
  1614                     
  1628                     
  1615                     TInt endOfUrlPos( KErrNotFound );
  1629                     TInt endOfUrlPos( KErrNotFound );
  1616                     TText8 ch = segment[ segment.Length() - 1];
  1630                     TText ch = segment[ segment.Length() - 1];
  1617                     RBuf8 url;
  1631                     RBuf url;
  1618                     url.CreateL( urlMaxLength );
  1632                     url.CreateL( urlMaxLength );
  1619                     url.CleanupClosePushL();
  1633                     url.CleanupClosePushL();
  1620                     
  1634                     
  1621                     // Find if hyperlink ends within this segment boundaries
  1635                     // Find if hyperlink ends within this segment boundaries
  1622                     if ( ch == KSOH || ch == KCR || ch == KLF || ch == KHT || ch == KCharacterSpace )
  1636                     if ( ch == KSOH || ch == KCR || ch == KLF || ch == KHT || ch == KCharacterSpace )
  1628                         endOfUrlPos = nextToken.Length() - KHtmlLineBreak().Length() + endOfUrlPos;
  1642                         endOfUrlPos = nextToken.Length() - KHtmlLineBreak().Length() + endOfUrlPos;
  1629                         }
  1643                         }
  1630                     else
  1644                     else
  1631                         { // Handle hyperlink spread in multiple segments
  1645                         { // Handle hyperlink spread in multiple segments
  1632                         TInt nextPos = position;
  1646                         TInt nextPos = position;
  1633                         TPtrC8 nextSegment( aSource.Ptr( nextPos ) );
  1647                         TPtrC nextSegment( aSource.MidTPtr( nextPos ) );
  1634                         TLex8 lexNextSegment( nextSegment );
  1648                         TLex lexNextSegment( nextSegment );
  1635                         TPtrC8 nextNextToken( nextToken );
  1649                         TPtrC nextNextToken( nextToken );
  1636                         TBool firstPass( ETrue );
  1650                         TBool firstPass( ETrue );
  1637                         
  1651                         
  1638                         while ( endOfUrlPos == KErrNotFound || nextPos >= aSource.Size() )
  1652                         while ( endOfUrlPos == KErrNotFound || nextPos >= aSource.Length() )
  1639                             {
  1653                             {
  1640                             if ( ( url.Length() + nextNextToken.Length() )  > urlMaxLength )
  1654                             if ( ( url.Length() + nextNextToken.Length() )  > urlMaxLength )
  1641                                 { // URL exceeds limit of 2K, do nothing
  1655                                 { // URL exceeds limit of 2K, do nothing
  1642                                 break;
  1656                                 break;
  1643                                 }
  1657                                 }
  1646                             if ( ( nextSegment.Length() == nextNextToken.Length() ) || firstPass )
  1660                             if ( ( nextSegment.Length() == nextNextToken.Length() ) || firstPass )
  1647                                 { // Token takes up the whole segment, or first pass( first segment 
  1661                                 { // Token takes up the whole segment, or first pass( first segment 
  1648                                   // with last token where hyperlink does not end within segment's
  1662                                   // with last token where hyperlink does not end within segment's
  1649                                   // boundaries, move to next segment
  1663                                   // boundaries, move to next segment
  1650                                 nextPos += nextSegment.Length();
  1664                                 nextPos += nextSegment.Length();
  1651                                 nextSegment.Set( aSource.Ptr( nextPos ) );
  1665                                 nextSegment.Set( aSource.MidTPtr( nextPos ) );
  1652                                 if( nextSegment.Length() == 0 )
  1666                                 if( nextSegment.Length() == 0 )
  1653                                     {      
  1667                                     {      
  1654                                     break;
  1668                                     break;
  1655                                     }
  1669                                     }
  1656                                 lexNextSegment.Assign( nextSegment );
  1670                                 lexNextSegment.Assign( nextSegment );
  1674                                 }
  1688                                 }
  1675                             }
  1689                             }
  1676  
  1690  
  1677                         if ( endOfUrlPos != KErrNotFound )
  1691                         if ( endOfUrlPos != KErrNotFound )
  1678                             { // Handle hyperlink that is within 2K limit
  1692                             { // Handle hyperlink that is within 2K limit
  1679                             RBuf8 urlBuf;
  1693                             RBuf urlBuf;
  1680                             TBool wwwLink( EFalse );
  1694                             TBool wwwLink( EFalse );
  1681 
  1695 
  1682                             if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 )
  1696                             if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 )
  1683                                 {
  1697                                 {
  1684                                 wwwLink = ETrue;
  1698                                 wwwLink = ETrue;
  1708                             
  1722                             
  1709                             TInt offset = lexSegment.Offset() - nextToken.Length();
  1723                             TInt offset = lexSegment.Offset() - nextToken.Length();
  1710                             // Remove hyperlink from the original message body
  1724                             // Remove hyperlink from the original message body
  1711                             aSource.Delete( offset + position, url.Length() );
  1725                             aSource.Delete( offset + position, url.Length() );
  1712                             // Insert html formated hyperlink
  1726                             // Insert html formated hyperlink
  1713                             aSource.InsertL( offset + position, urlBuf );
  1727                             aSource.ReAlloc( maxlength + urlBuf.Length() );
  1714                             segment.Set( aSource.Ptr( position ) );
  1728                             aSource.Insert( offset + position, urlBuf );
       
  1729                             segment.Set( aSource.MidTPtr( position ) );
  1715                             
  1730                             
  1716                             // Set carry on value to mark where new token should start in following segment
  1731                             // Set carry on value to mark where new token should start in following segment
  1717                             carryOverInc = endOfUrlPos;
  1732                             carryOverInc = endOfUrlPos;
  1718                             position = nextPos;
  1733                             position = nextPos;
  1719                             
  1734                             
  1723                     CleanupStack::PopAndDestroy( &url );
  1738                     CleanupStack::PopAndDestroy( &url );
  1724                     }
  1739                     }
  1725                 }
  1740                 }
  1726             }
  1741             }
  1727         position += segment.Length();
  1742         position += segment.Length();
  1728         if ( ( aSource.Size() - position ) <= 0 )
  1743         if ( ( aSource.Length() - position ) <= 0 )
  1729             {
  1744             {
  1730             eos = ETrue;
  1745             eos = ETrue;
  1731             }
  1746             }
  1732         }
  1747         }
  1733 
  1748 
  1807     {
  1822     {
  1808     CCoeControl::HandleResourceChange( aType );
  1823     CCoeControl::HandleResourceChange( aType );
  1809     if ( aType == CFsEmailUiViewBase::EScreenLayoutChanged )
  1824     if ( aType == CFsEmailUiViewBase::EScreenLayoutChanged )
  1810         {
  1825         {
  1811         RefreshCurrentMailHeader();
  1826         RefreshCurrentMailHeader();
  1812         }
  1827 	    SetRect( iView.ContainerRect() );
  1813     }
  1828         }
       
  1829    }
  1814 
  1830 
  1815 void CFsEmailUiHtmlViewerContainer::RefreshCurrentMailHeader()
  1831 void CFsEmailUiHtmlViewerContainer::RefreshCurrentMailHeader()
  1816     {
  1832     {
  1817     if ( iMessage )
  1833     if ( iMessage )
  1818         {
  1834         {
  1831             {
  1847             {
  1832             TRAP_IGNORE( ReloadPageL() );
  1848             TRAP_IGNORE( ReloadPageL() );
  1833             }
  1849             }
  1834         else
  1850         else
  1835             {
  1851             {
  1836             //Load page asynchronously after dismissing menu    
  1852             //Load page asynchronously after dismissing menu 
  1837             iEventHandler->DismissMenuAndReload();
  1853             //this is outdated call because it cancels Action menu which is no longer used in 9.2
       
  1854            // iEventHandler->DismissMenuAndReload();
  1838             }
  1855             }
  1839         }
  1856         }
  1840     }
  1857     }
  1841 
  1858 
  1842 void CFsEmailUiHtmlViewerContainer::ReloadPageL()
  1859 void CFsEmailUiHtmlViewerContainer::ReloadPageL()
  2024             return ETrue;
  2041             return ETrue;
  2025             }
  2042             }
  2026         else if (aUrl.Compare(KURLDisplayImages()) == 0)
  2043         else if (aUrl.Compare(KURLDisplayImages()) == 0)
  2027             {
  2044             {
  2028             DisplayStatusIndicatorL(KStatusIndicatorAutomaticHidingDuration);
  2045             DisplayStatusIndicatorL(KStatusIndicatorAutomaticHidingDuration);
       
  2046 			if( iMessage )
       
  2047 			{
  2029             iAppUi.DisplayImagesCache().AddMessageL(*iMessage);
  2048             iAppUi.DisplayImagesCache().AddMessageL(*iMessage);
       
  2049 			}
  2030             iBrCtlInterface->HandleCommandL(TBrCtlDefs::ECommandLoadImages + TBrCtlDefs::ECommandIdBase);
  2050             iBrCtlInterface->HandleCommandL(TBrCtlDefs::ECommandLoadImages + TBrCtlDefs::ECommandIdBase);
  2031             return ETrue;
  2051             return ETrue;
  2032             }
  2052             }
  2033         else if (aUrl.Compare(KURLCollapseHeader()) == 0)
  2053         else if (aUrl.Compare(KURLCollapseHeader()) == 0)
  2034             {
  2054             {
  2161     CleanupStack::PopAndDestroy( handler );
  2181     CleanupStack::PopAndDestroy( handler );
  2162     }
  2182     }
  2163 
  2183 
  2164 void CFsEmailUiHtmlViewerContainer::PrepareBodyHtmlL( const TDesC& aFileName )
  2184 void CFsEmailUiHtmlViewerContainer::PrepareBodyHtmlL( const TDesC& aFileName )
  2165     {
  2185     {
  2166     CFSMailMessagePart* htmlBodyPart = iMessage->HtmlBodyPartL();
  2186     
  2167     
  2187     if( iMessage )
  2168     if ( htmlBodyPart )
  2188         {
  2169         {
  2189         CFSMailMessagePart* htmlBodyPart = iMessage->HtmlBodyPartL();
  2170         CleanupStack::PushL( htmlBodyPart );
  2190 
  2171         // Copy html body part to email html file
  2191         if ( htmlBodyPart )
  2172         CopyToHtmlFileL( *htmlBodyPart, aFileName );
  2192             {
  2173         CleanupStack::PopAndDestroy( htmlBodyPart );
  2193             CleanupStack::PushL( htmlBodyPart );
  2174         }
       
  2175     else
       
  2176         {
       
  2177         CFSMailMessagePart* textBodyPart = iMessage->PlainTextBodyPartL();
       
  2178 
       
  2179         if ( textBodyPart )
       
  2180             {
       
  2181             CleanupStack::PushL( textBodyPart );
       
  2182             // Copy html body part to email html file
  2194             // Copy html body part to email html file
  2183             ConvertToHtmlFileL( *textBodyPart, aFileName );
  2195             CopyToHtmlFileL( *htmlBodyPart, aFileName );
  2184             CleanupStack::PopAndDestroy( textBodyPart );
  2196             CleanupStack::PopAndDestroy( htmlBodyPart );
  2185             }
  2197             }
  2186         else
  2198         else
  2187             {
  2199             {
  2188             User::Leave( KErrNotFound );
  2200             CFSMailMessagePart* textBodyPart = iMessage->PlainTextBodyPartL();
       
  2201     
       
  2202             if ( textBodyPart )
       
  2203                 {
       
  2204                 CleanupStack::PushL( textBodyPart );
       
  2205                 // Copy html body part to email html file
       
  2206                 ConvertToHtmlFileL( *textBodyPart, aFileName );
       
  2207                 CleanupStack::PopAndDestroy( textBodyPart );
       
  2208                 }
       
  2209             else
       
  2210                 {
       
  2211                 User::Leave( KErrNotFound );
       
  2212                 }
  2189             }
  2213             }
  2190         }
  2214         }
  2191     }
  2215     }
  2192 
  2216 
  2193 void CFsEmailUiHtmlViewerContainer::WriteEmptyBodyHtmlL( const TDesC& aFileName )
  2217 void CFsEmailUiHtmlViewerContainer::WriteEmptyBodyHtmlL( const TDesC& aFileName )