emailuis/emailui/src/FreestyleEmailUiHtmlViewerContainer.cpp
branchRCL_3
changeset 13 8592a65ad3fb
parent 12 4ce476e64c59
child 14 b13141f05c3d
equal deleted inserted replaced
12:4ce476e64c59 13:8592a65ad3fb
  1371         bodyBuf.CleanupClosePushL();
  1371         bodyBuf.CleanupClosePushL();
  1372         bodyBuf.Insert( 0, aContent);
  1372         bodyBuf.Insert( 0, aContent);
  1373         TInt maxlength = bodyBuf.MaxSize();
  1373         TInt maxlength = bodyBuf.MaxSize();
  1374         
  1374         
  1375         TInt position( 0 );
  1375         TInt position( 0 );
  1376         TText previous = 0;
       
  1377         TBool EndOfString( EFalse );
  1376         TBool EndOfString( EFalse );
  1378         
  1377         
  1379         while ( !EndOfString )
  1378         while ( !EndOfString )
  1380             {
  1379             {
  1381             TInt startPosition = position;
  1380             TInt startPosition = position;
  1440                         break;
  1439                         break;
  1441                     default:
  1440                     default:
  1442                         i++;
  1441                         i++;
  1443                         break;
  1442                         break;
  1444                     }
  1443                     }
  1445                 previous = ch;
       
  1446                 }
  1444                 }
  1447             position += segment.Length();
  1445             position += segment.Length();
  1448             if ( ( bodyBuf.Length() - position ) <= 0 )
  1446             if ( ( bodyBuf.Length() - position ) <= 0 )
  1449                 {
  1447                 {
  1450                 EndOfString = ETrue;
  1448                 EndOfString = ETrue;
  1502 //
  1500 //
  1503 // <cmail>
  1501 // <cmail>
  1504 void CFsEmailUiHtmlViewerContainer::CreateHyperlinksFromUrlsL( RBuf& aSource )
  1502 void CFsEmailUiHtmlViewerContainer::CreateHyperlinksFromUrlsL( RBuf& aSource )
  1505     {
  1503     {
  1506     FUNC_LOG;
  1504     FUNC_LOG;
  1507     const TInt urlMaxLength = 2048;
  1505     const TInt searhCases( CFindItemEngine::EFindItemSearchURLBin );
  1508     _LIT( KHttp, "http://" );
  1506     CFindItemEngine* itemEngine = CFindItemEngine::NewL( aSource, CFindItemEngine::TFindItemSearchCase( searhCases ) );
  1509     _LIT( KHttps, "https://");
  1507     CleanupStack::PushL ( itemEngine );
  1510     _LIT( KWww, "www."); 
  1508     if ( itemEngine->ItemCount() > 0 )
  1511     
  1509         {
  1512     TBool eos( aSource.Size() <= 0 );
  1510         _LIT( KHttp, "http://" );
  1513     TInt position( 0 );
  1511         _LIT( KUrlFormat, "<a href=\"%S\">%S</a>" );
  1514     TInt carryOverInc( 0 );
  1512         _LIT( KUrlFormatWithHttp, "<a href=\"http://%S\">%S</a>" );
  1515     TInt maxlength = aSource.Length();
       
  1516     while ( !eos )
       
  1517         {
       
  1518         while ( carryOverInc >= aSource.MidTPtr( position ).Length() && aSource.Size() != 0 )
       
  1519             { // Skip segments of overlapping url string
       
  1520             carryOverInc -= aSource.MidTPtr( position ).Length();
       
  1521             position += aSource.MidTPtr( position ).Length();
       
  1522             }
       
  1523         
  1513         
  1524         TPtr16 segment( aSource.MidTPtr( position ) );
  1514         const TInt sourceLength( aSource.Length() );
  1525         TLex16 lexSegment( segment );
  1515         // Allocate enough space for the final result
  1526         lexSegment.Inc( carryOverInc );
  1516         aSource.ReAllocL( sourceLength + TotalLengthOfItems( *itemEngine ) + KUrlFormatWithHttp().Length() * itemEngine->ItemCount() );
  1527         carryOverInc = 0;
  1517         aSource.SetMax();
       
  1518         // Organize buffer so that original data is in the back of the aSource
       
  1519         aSource.RightTPtr( sourceLength ).Copy( aSource.Left( sourceLength ) );
       
  1520         // Set source to new original data's position
       
  1521         const TPtrC source( aSource.RightTPtr( sourceLength ) );
       
  1522         // Set target to aSource's beginning
       
  1523         TPtr target( aSource.MidTPtr( 0 ) );
       
  1524         // Reset length, we now have an empty buffer to fill
       
  1525         target.SetLength( 0 );
  1528         
  1526         
  1529         while (!lexSegment.Eos())
  1527         TInt currentSourcePosition( 0 );
  1530             {
  1528         CFindItemEngine::SFoundItem item;
  1531             TPtrC nextToken( lexSegment.NextToken() );
  1529         for ( TBool available( itemEngine->Item( item ) ); available; available = itemEngine->NextItem( item ) )
  1532             TInt foundAt( KErrNotFound );
  1530             {
  1533             
  1531             target.Append( source.Mid( currentSourcePosition, item.iStartPos - currentSourcePosition ) );
  1534             // Find HTTP, HTTPS, or WWW link in CBufSeg segment of size 1024 bytes.
  1532             const TPtrC url( source.Mid( item.iStartPos, item.iLength ) );
  1535             if ( ( ( foundAt = nextToken.FindC( KHttp ) ) != KErrNotFound ) ||
  1533             TPtrC format( KUrlFormat() );
  1536                     (  ( foundAt = nextToken.FindC( KHttps ) ) != KErrNotFound ) ||
  1534             if ( url.FindF( KHttp() ) == KErrNotFound ) 
  1537                     ( ( foundAt = nextToken.FindC( KWww ) ) != KErrNotFound ) )
       
  1538                 {
  1535                 {
  1539                 if ( !lexSegment.Eos() )
  1536                 format.Set( KUrlFormatWithHttp() );
  1540                     { 
       
  1541                     if ( !foundAt )
       
  1542                         { // Token starts with http/https/www.x
       
  1543                         TPtrC url;
       
  1544                         TInt lineBreakPos( KErrNotFound );
       
  1545                         if ( ( lineBreakPos = nextToken.FindC( KHtmlLineBreak ) ) != KErrNotFound )
       
  1546                             { // Token contains html line break -> remove
       
  1547                             url.Set( nextToken.Left( lineBreakPos ) );
       
  1548                             }
       
  1549                         else
       
  1550                             {
       
  1551                             url.Set( nextToken );
       
  1552                             }
       
  1553                         
       
  1554                         if ( url.CompareC( KWww ) != KErrNone ) // if token=www., validate format 
       
  1555                             {                                   // www.x
       
  1556                             RBuf urlBuf;
       
  1557                             TBool wwwLink( EFalse );
       
  1558                             if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 )
       
  1559                                 {
       
  1560                                 wwwLink = ETrue;
       
  1561                                 //Hyperlinks beginning with www. needs http:// prefix
       
  1562                                 urlBuf.CreateL( KHtmlLinkTagWWW().Length() + url.Length() * 2
       
  1563                                         + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() + KHttp().Length() );
       
  1564                                 }                            
       
  1565                             else
       
  1566                                 {
       
  1567                                 urlBuf.CreateL( KHtmlLinkTag().Length() + url.Length() * 2
       
  1568                                         + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() );                                
       
  1569                                 }
       
  1570                             urlBuf.CleanupClosePushL();
       
  1571                             // Format html link
       
  1572                             if ( wwwLink )
       
  1573                                 {
       
  1574                                 urlBuf.AppendFormat( KHtmlLinkTagWWW, &KHttp, &url );
       
  1575                                 }
       
  1576                             else
       
  1577                                 {
       
  1578                                 urlBuf.AppendFormat( KHtmlLinkTag, &url );
       
  1579                                 }
       
  1580                             urlBuf.Append( url );
       
  1581                             urlBuf.Append( KHtmlLinkEndTag );
       
  1582                             if ( lineBreakPos != KErrNotFound )
       
  1583                                 { // Add line break if removed earlier
       
  1584                                 urlBuf.Append( KHtmlLineBreak );
       
  1585                                 }
       
  1586                             //Test
       
  1587                             TInt nextTokenLength = nextToken.Length();
       
  1588                             TInt segOffset = lexSegment.Offset();
       
  1589                             TInt urlLength = urlBuf.Length();
       
  1590                             
       
  1591                             //Test
       
  1592                             TInt offset = lexSegment.Offset() - nextToken.Length();
       
  1593                             TLexMark tokenMark;
       
  1594                             // Move next character last token back
       
  1595                             lexSegment.Inc( - nextToken.Length() );
       
  1596                             lexSegment.Mark( tokenMark );
       
  1597                             aSource.Delete( offset + position, nextToken.Length() );
       
  1598                             aSource.ReAlloc( maxlength + urlBuf.Length() );
       
  1599                             aSource.Insert( offset + position, urlBuf );
       
  1600                             segment.Set( aSource.MidTPtr( position ) );
       
  1601                             lexSegment.Assign( segment );
       
  1602                             // Set next character to the position of inserted hyperlink
       
  1603                             lexSegment.UnGetToMark( tokenMark );
       
  1604                             
       
  1605                             // If Max segment length is reached, set carry over value to 
       
  1606                             // properly set next character in following CBufSeg segment
       
  1607                             if ( ( offset + urlBuf.Length() ) >= segment.Length() )
       
  1608                                 {
       
  1609                                 carryOverInc = offset + urlBuf.Length() - segment.Length();
       
  1610                                 while ( !lexSegment.Eos() )
       
  1611                                     { // Set to segment's end
       
  1612                                     lexSegment.NextToken(); 
       
  1613                                     }
       
  1614                                 }
       
  1615                             else
       
  1616                                 {
       
  1617                                 lexSegment.Inc( urlBuf.Length() );
       
  1618                                 }
       
  1619                             
       
  1620                             CleanupStack::PopAndDestroy( &urlBuf );
       
  1621                             }
       
  1622                         }
       
  1623                     }
       
  1624                 else
       
  1625                     // Next token is end of string, here we handle the last token of a segment
       
  1626                     {
       
  1627                     _LIT( KUrlEnd, "<" );
       
  1628                     
       
  1629                     TInt endOfUrlPos( KErrNotFound );
       
  1630                     TText ch = segment[ segment.Length() - 1];
       
  1631                     RBuf url;
       
  1632                     url.CreateL( urlMaxLength );
       
  1633                     url.CleanupClosePushL();
       
  1634                     
       
  1635                     // Find if hyperlink ends within this segment boundaries
       
  1636                     if ( ch == KSOH || ch == KCR || ch == KLF || ch == KHT || ch == KCharacterSpace )
       
  1637                         {
       
  1638                         endOfUrlPos = nextToken.Length() - 1;
       
  1639                         }
       
  1640                     else if ( ( endOfUrlPos = nextToken.Right( KHtmlLineBreak().Length() ).Find( KUrlEnd ) ) != KErrNotFound )
       
  1641                         {
       
  1642                         endOfUrlPos = nextToken.Length() - KHtmlLineBreak().Length() + endOfUrlPos;
       
  1643                         }
       
  1644                     else
       
  1645                         { // Handle hyperlink spread in multiple segments
       
  1646                         TInt nextPos = position;
       
  1647                         TPtrC nextSegment( aSource.MidTPtr( nextPos ) );
       
  1648                         TLex lexNextSegment( nextSegment );
       
  1649                         TPtrC nextNextToken( nextToken );
       
  1650                         TBool firstPass( ETrue );
       
  1651                         
       
  1652                         while ( endOfUrlPos == KErrNotFound || nextPos >= aSource.Length() )
       
  1653                             {
       
  1654                             if ( ( url.Length() + nextNextToken.Length() )  > urlMaxLength )
       
  1655                                 { // URL exceeds limit of 2K, do nothing
       
  1656                                 break;
       
  1657                                 }
       
  1658                             
       
  1659                             url.Append( nextNextToken );
       
  1660                             if ( ( nextSegment.Length() == nextNextToken.Length() ) || firstPass )
       
  1661                                 { // Token takes up the whole segment, or first pass( first segment 
       
  1662                                   // with last token where hyperlink does not end within segment's
       
  1663                                   // boundaries, move to next segment
       
  1664                                 nextPos += nextSegment.Length();
       
  1665                                 nextSegment.Set( aSource.MidTPtr( nextPos ) );
       
  1666                                 if( nextSegment.Length() == 0 )
       
  1667                                     {      
       
  1668                                     break;
       
  1669                                     }
       
  1670                                 lexNextSegment.Assign( nextSegment );
       
  1671                                 nextNextToken.Set( lexNextSegment.NextToken() );
       
  1672                                 if ( firstPass )
       
  1673                                     { 
       
  1674                                     firstPass =  EFalse;
       
  1675                                     }
       
  1676                                 }
       
  1677                             else
       
  1678                                 { // Last segment's token with hyperlink's end
       
  1679                                 if ( ( endOfUrlPos = url.Find( KHtmlLineBreak ) ) != KErrNotFound )
       
  1680                                     { // Remove line break
       
  1681                                     url.Delete( endOfUrlPos, KHtmlLineBreak().Length() );
       
  1682                                     endOfUrlPos = nextNextToken.Length() - KHtmlLineBreak().Length();
       
  1683                                     }
       
  1684                                 else
       
  1685                                     {
       
  1686                                     endOfUrlPos = nextNextToken.Length();
       
  1687                                     }  
       
  1688                                 }
       
  1689                             }
       
  1690  
       
  1691                         if ( endOfUrlPos != KErrNotFound )
       
  1692                             { // Handle hyperlink that is within 2K limit
       
  1693                             RBuf urlBuf;
       
  1694                             TBool wwwLink( EFalse );
       
  1695 
       
  1696                             if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 )
       
  1697                                 {
       
  1698                                 wwwLink = ETrue;
       
  1699                                 urlBuf.CreateL( KHtmlLinkTagWWW().Length() + url.Length() * 2
       
  1700                                         + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() + KHttp().Length() );
       
  1701                                 }
       
  1702                             else
       
  1703                                 {
       
  1704                                 urlBuf.CreateL( KHtmlLinkTag().Length() + url.Length() * 2
       
  1705                                         + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() );                                
       
  1706                                 }
       
  1707 
       
  1708                             urlBuf.CleanupClosePushL();
       
  1709                             // Format html link                            
       
  1710                             if ( wwwLink )
       
  1711                                 {
       
  1712                                 urlBuf.AppendFormat( KHtmlLinkTagWWW, &KHttp, &url );
       
  1713                                 }
       
  1714                             else
       
  1715                                 {
       
  1716                                 urlBuf.AppendFormat( KHtmlLinkTag, &url );
       
  1717                                 }
       
  1718                             
       
  1719                             urlBuf.Append( url );
       
  1720                             urlBuf.Append( KHtmlLinkEndTag );
       
  1721                             urlBuf.Append( KHtmlLineBreak );
       
  1722                             
       
  1723                             TInt offset = lexSegment.Offset() - nextToken.Length();
       
  1724                             // Remove hyperlink from the original message body
       
  1725                             aSource.Delete( offset + position, url.Length() );
       
  1726                             // Insert html formated hyperlink
       
  1727                             aSource.ReAlloc( maxlength + urlBuf.Length() );
       
  1728                             aSource.Insert( offset + position, urlBuf );
       
  1729                             segment.Set( aSource.MidTPtr( position ) );
       
  1730                             
       
  1731                             // Set carry on value to mark where new token should start in following segment
       
  1732                             carryOverInc = endOfUrlPos;
       
  1733                             position = nextPos;
       
  1734                             
       
  1735                             CleanupStack::PopAndDestroy( &urlBuf );
       
  1736                             }     
       
  1737                         }
       
  1738                     CleanupStack::PopAndDestroy( &url );
       
  1739                     }
       
  1740                 }
  1537                 }
  1741             }
  1538             HBufC* formatBuffer = HBufC::NewLC( format.Length() + url.Length() * 2 );
  1742         position += segment.Length();
  1539             formatBuffer->Des().Format( format, &url, &url );            
  1743         if ( ( aSource.Length() - position ) <= 0 )
  1540             target.Append( *formatBuffer );
  1744             {
  1541             CleanupStack::PopAndDestroy(); // formatBuffer
  1745             eos = ETrue;
  1542             currentSourcePosition = item.iStartPos + item.iLength;
  1746             }
  1543             }        
  1747         }
  1544         // Append characters that are left in buffer
  1748 
  1545         if ( currentSourcePosition < sourceLength )
  1749     
  1546             {
  1750     }
  1547             target.Append( source.Mid( currentSourcePosition, sourceLength - currentSourcePosition ) );
  1751 
  1548             }
       
  1549         aSource.SetLength( target.Length() );
       
  1550         }
       
  1551     CleanupStack::PopAndDestroy(); // itemEngine
       
  1552     }
       
  1553 
       
  1554 
       
  1555 TInt CFsEmailUiHtmlViewerContainer::TotalLengthOfItems( CFindItemEngine& aItemEngine ) const
       
  1556     {
       
  1557     TInt totalLength( 0 );
       
  1558     CFindItemEngine::SFoundItem item;
       
  1559     aItemEngine.ResetPosition();
       
  1560     for ( TBool available( aItemEngine.Item( item ) ); available; available = aItemEngine.NextItem( item ) )
       
  1561         {
       
  1562         totalLength += item.iLength;
       
  1563         }
       
  1564     aItemEngine.ResetPosition();
       
  1565     return totalLength;
       
  1566     }
  1752 
  1567 
  1753 // ---------------------------------------------------------------------------
  1568 // ---------------------------------------------------------------------------
  1754 // Get Character set from CFSMailMessagePart
  1569 // Get Character set from CFSMailMessagePart
  1755 // ---------------------------------------------------------------------------
  1570 // ---------------------------------------------------------------------------
  1756 //
  1571 //