emailuis/emailui/src/FreestyleEmailUiHtmlViewerContainer.cpp
changeset 2 5253a20d2a1e
parent 1 12c456ceeff2
child 3 a4d6f1ea0416
equal deleted inserted replaced
1:12c456ceeff2 2:5253a20d2a1e
    19 #include "emailtrace.h"
    19 #include "emailtrace.h"
    20 #include <AknsDrawUtils.h>
    20 #include <AknsDrawUtils.h>
    21 #include <coemain.h>
    21 #include <coemain.h>
    22 #include <commdbconnpref.h>
    22 #include <commdbconnpref.h>
    23 #include <bautils.h>
    23 #include <bautils.h>
    24 
    24 #include <biditext.h>
    25 //<cmail>
    25 //<cmail>
    26 #include "CFSMailMessage.h"
    26 #include "CFSMailMessage.h"
    27 //</cmail>
    27 //</cmail>
    28 #include <brctlinterface.h>
    28 #include <brctlinterface.h>
    29 #include <sysutil.h>
    29 #include <sysutil.h>
    30 
    30 #include <SchemeHandler.h>
    31 
    31 
    32 #include "FreestyleEmailUiAppui.h"
    32 #include "FreestyleEmailUiAppui.h"
    33 #include "FreestyleEmailUiUtilities.h"
    33 #include "FreestyleEmailUiUtilities.h"
    34 #include "FreestyleEmailUiHtmlViewerContainer.h"
    34 #include "FreestyleEmailUiHtmlViewerContainer.h"
    35 #include "FreestyleEmailUiHtmlViewerView.h"
    35 #include "FreestyleEmailUiHtmlViewerView.h"
    45 _LIT( KAllFiles, "*" );
    45 _LIT( KAllFiles, "*" );
    46 
    46 
    47 _LIT( KHeaderHtmlFile, "header.html" );
    47 _LIT( KHeaderHtmlFile, "header.html" );
    48 _LIT( KBodyHtmlFile, "body.html" );
    48 _LIT( KBodyHtmlFile, "body.html" );
    49 _LIT( KMessageHtmlFile, "email.html" );
    49 _LIT( KMessageHtmlFile, "email.html" );
       
    50 _LIT( KMessageHtmlRTLFile, "email_rtl.html" );
    50 _LIT( KZDrive, "z:" );
    51 _LIT( KZDrive, "z:" );
    51 _LIT( KHtmlFlagFile, "html.flag" );
    52 _LIT( KHtmlFlagFile, "html.flag" );
    52 
    53 _LIT( KURLSlash, "/");
    53 // <cmail>
       
    54 // Constants used in html content modification
    54 // Constants used in html content modification
    55 const TInt KMaxCharsToSearch( 200 );
    55 const TInt KMaxCharsToSearch( 200 );
    56 _LIT8( KStartTag, "<html" );
    56 _LIT8( KStartTag, "<html" );
    57 _LIT8( KHeadTag, "<head>");
    57 _LIT8( KHeadTag, "<head>");
    58 _LIT8( KHtmlHeader1, "<html><head><title></title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
    58 _LIT8( KHtmlHeader1, "<html><head><title></title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
    62 _LIT8( KCharsetTag8, "charset");
    62 _LIT8( KCharsetTag8, "charset");
    63 _LIT( KCharsetTag, "charset");
    63 _LIT( KCharsetTag, "charset");
    64 _LIT8( KHTMLEmptyContent, "<HTML><BODY></BODY></HTML>");
    64 _LIT8( KHTMLEmptyContent, "<HTML><BODY></BODY></HTML>");
    65 _LIT( KHTMLDataScheme, "data:0");
    65 _LIT( KHTMLDataScheme, "data:0");
    66 
    66 
    67 // </cmail>
    67 
       
    68 _LIT8( KHtmlLineBreak, "<br>" );
       
    69 _LIT8( KHtmlLineBreakCRLF, "<br>\xD\xA" );
       
    70 _LIT8( KHtmlLessThan, "&lt;" );
       
    71 _LIT8( KHtmlGreaterThan, "&gt;" );
       
    72 _LIT8( KHtmlAmpersand, "&amp;" );
       
    73 _LIT8( KHtmlQuotation, "&quot;" );
       
    74 _LIT8( KHtmlLinkTag, "<a href=\"%S\">" );
       
    75 _LIT8( KHtmlLinkEndTag, "</a>" );
       
    76 _LIT( KURLTypeBody, "body");
       
    77 
       
    78 const TText8 KGreaterThan = 0x3e;
       
    79 const TText8 KLessThan = 0x3c;
       
    80 const TText8 KAmpersand = 0x26;
       
    81 const TText8 KQuotation = 0x22;
       
    82 const TText8 KCharacterSpace = 0x20;
       
    83 const TText8 KSOH = 0x01; // Start Of Heading
       
    84 const TText8 KCR = 0x0d; // Carriage Return
       
    85 const TText8 KLF = 0x0a; // Line Feed
       
    86 const TText8 KHT = 0x09; // Horizontal Tab
       
    87 const TReal KOverlayButtonMarginX = 0.01; // 1%
       
    88 const TReal KOverlayButtonMarginY = 0.01; // 1%
       
    89 const TReal KOverlayButtonSizeP = 0.15; // 15%
       
    90 const TReal KOverlayButtonSizeLs = 0.20; // 25%
       
    91 const TReal KOverlayButtonPosP = 0.88;
       
    92 const TReal KOverlayButtonPosLs = 0.85;
    68 
    93 
    69 // ---------------------------------------------------------------------------
    94 // ---------------------------------------------------------------------------
    70 // Two-phased constructor.
    95 // Two-phased constructor.
    71 // ---------------------------------------------------------------------------
    96 // ---------------------------------------------------------------------------
    72 //
    97 //
   113     iMessageParts.Close();
   138     iMessageParts.Close();
   114     delete iEventHandler;
   139     delete iEventHandler;
   115     delete iBrCtlInterface;
   140     delete iBrCtlInterface;
   116     iConnection.Close();
   141     iConnection.Close();
   117     iSocketServer.Close();
   142     iSocketServer.Close();
       
   143     
       
   144     delete iOverlayControlNext;
       
   145     delete iOverlayControlPrev;
   118     }
   146     }
   119 
   147 
   120 // <cmail> Because of browser changes, followings must be performed before iAppUi.exit()
   148 // <cmail> Because of browser changes, followings must be performed before iAppUi.exit()
   121 void CFsEmailUiHtmlViewerContainer::PrepareForExit()
   149 void CFsEmailUiHtmlViewerContainer::PrepareForExit()
   122     {
   150     {
   143     BaflUtils::EnsurePathExistsL( iFs, iTempHtmlFolderPath );
   171     BaflUtils::EnsurePathExistsL( iFs, iTempHtmlFolderPath );
   144     SetHTMLResourceFlagFullName();
   172     SetHTMLResourceFlagFullName();
   145     EnsureHTMLResourceL();
   173     EnsureHTMLResourceL();
   146     
   174     
   147     CreateWindowL();
   175     CreateWindowL();
   148     SetRect( iAppUi.ClientRect() );
   176     SetRect( iView.ContainerRect() );
   149 
       
   150 
   177 
   151     TUint brCtlCapabilities = TBrCtlDefs::ECapabilityClientResolveEmbeddedURL |
   178     TUint brCtlCapabilities = TBrCtlDefs::ECapabilityClientResolveEmbeddedURL |
   152                               TBrCtlDefs::ECapabilityDisplayScrollBar |
   179                               TBrCtlDefs::ECapabilityDisplayScrollBar |
   153                               TBrCtlDefs::ECapabilityClientNotifyURL |
   180                               TBrCtlDefs::ECapabilityClientNotifyURL |
   154                               TBrCtlDefs::ECapabilityLoadHttpFw |
   181                               TBrCtlDefs::ECapabilityLoadHttpFw |
   165     iBrCtlInterface->SetBrowserSettingL( TBrCtlDefs::ESettingsPageOverview, EFalse );
   192     iBrCtlInterface->SetBrowserSettingL( TBrCtlDefs::ESettingsPageOverview, EFalse );
   166     iBrCtlInterface->SetBrowserSettingL( TBrCtlDefs::ESettingsTextWrapEnabled, ETrue );
   193     iBrCtlInterface->SetBrowserSettingL( TBrCtlDefs::ESettingsTextWrapEnabled, ETrue );
   167     iBrCtlInterface->SetBrowserSettingL( TBrCtlDefs::ESettingsFontSize, TBrCtlDefs::EFontSizeLevelLarger );
   194     iBrCtlInterface->SetBrowserSettingL( TBrCtlDefs::ESettingsFontSize, TBrCtlDefs::EFontSizeLevelLarger );
   168 
   195 
   169     iEventHandler = CFreestyleMessageHeaderURLEventHandler::NewL( iAppUi, iView );
   196     iEventHandler = CFreestyleMessageHeaderURLEventHandler::NewL( iAppUi, iView );
       
   197     
       
   198     TRect nextButtonRect = OverlayButtonRect( EFalse );
       
   199     iOverlayControlNext = COverlayControl::NewL( this, this, nextButtonRect, 
       
   200             EMbmFreestyleemailuiQgn_indi_cmail_arrow_next, 
       
   201             EMbmFreestyleemailuiQgn_indi_cmail_arrow_next_mask );
       
   202 
       
   203     TRect prevButtonRect = OverlayButtonRect( ETrue );
       
   204     iOverlayControlPrev = COverlayControl::NewL( this, this, prevButtonRect,
       
   205             EMbmFreestyleemailuiQgn_indi_cmail_arrow_previous,
       
   206             EMbmFreestyleemailuiQgn_indi_cmail_arrow_previous_mask );
       
   207     iScrollPosition = 0;
   170     ActivateL();
   208     ActivateL();
       
   209     }
       
   210 
       
   211 void CFsEmailUiHtmlViewerContainer::MakeVisible( TBool aVisible )
       
   212     {
       
   213     UpdateOverlayButtons( aVisible );
       
   214     CCoeControl::MakeVisible( aVisible );
       
   215     }
       
   216 
       
   217 void CFsEmailUiHtmlViewerContainer::HandleOverlayPointerEventL( COverlayControl* aControl, 
       
   218         const TPointerEvent& aEvent )
       
   219     {
       
   220     if( aEvent.iType == TPointerEvent::EButton1Up )
       
   221         {
       
   222         if( aControl == iOverlayControlNext )
       
   223             {
       
   224             iView.HandleCommandL( EFsEmailUiCmdNextMessage );
       
   225             }
       
   226         else if( aControl == iOverlayControlPrev )
       
   227             {
       
   228             iView.HandleCommandL( EFsEmailUiCmdPreviousMessage );
       
   229             }
       
   230         }
       
   231     }
       
   232 
       
   233 void CFsEmailUiHtmlViewerContainer::UpdateOverlayButtons( TBool aVisible )
       
   234     {
       
   235     TBool nextAvailable = EFalse;
       
   236     TBool prevAvailable = EFalse;
       
   237     if( iMessage )
       
   238         {
       
   239         TFSMailMsgId currentMsgId = iMessage->GetMessageId();
       
   240         TFSMailMsgId tmpMsgId;
       
   241         TFSMailMsgId tmpMsgFolderId;
       
   242         nextAvailable = iAppUi.IsNextMsgAvailable( currentMsgId, tmpMsgId, tmpMsgFolderId );
       
   243         prevAvailable = iAppUi.IsPreviousMsgAvailable( currentMsgId, tmpMsgId, tmpMsgFolderId );
       
   244         }
       
   245     
       
   246     if( iOverlayControlPrev )
       
   247         {
       
   248         iOverlayControlPrev->SetRect( OverlayButtonRect( ETrue ) );
       
   249         iOverlayControlPrev->MakeVisible( aVisible && prevAvailable );
       
   250         }
       
   251     if( iOverlayControlNext )
       
   252         {
       
   253         iOverlayControlNext->SetRect( OverlayButtonRect( EFalse ) );
       
   254         iOverlayControlNext->MakeVisible( aVisible && nextAvailable );
       
   255         }
       
   256     }
       
   257 
       
   258 // Get rect for button
       
   259 TRect CFsEmailUiHtmlViewerContainer::OverlayButtonRect( TBool aLeft )
       
   260     {
       
   261     TRect rect = Rect();
       
   262     TSize size = rect.Size();
       
   263     
       
   264     TBool landscape = size.iWidth > size.iHeight;
       
   265     TInt buttonSize;
       
   266 
       
   267     if( landscape )
       
   268         {
       
   269         buttonSize = size.iHeight * KOverlayButtonSizeLs;
       
   270         }
       
   271     else
       
   272         {
       
   273         buttonSize = size.iWidth * KOverlayButtonSizeP;
       
   274         }
       
   275 
       
   276     rect.iBr.iY = size.iHeight * (1-KOverlayButtonMarginY);
       
   277     
       
   278     if( aLeft )
       
   279         {
       
   280         rect.iTl.iX = size.iWidth * KOverlayButtonMarginX;
       
   281         rect.iBr.iX = rect.iTl.iX + buttonSize;
       
   282         }
       
   283     else
       
   284         {
       
   285         rect.iBr.iX = size.iWidth * (1 - KOverlayButtonMarginX);
       
   286         rect.iTl.iX = rect.iBr.iX - buttonSize;
       
   287         }
       
   288     
       
   289     rect.iTl.iY = rect.iBr.iY - buttonSize;
       
   290     return rect;
   171     }
   291     }
   172 
   292 
   173 // Getter for br contro, interface
   293 // Getter for br contro, interface
   174 CBrCtlInterface* CFsEmailUiHtmlViewerContainer::BrowserControlIf()
   294 CBrCtlInterface* CFsEmailUiHtmlViewerContainer::BrowserControlIf()
   175     {
   295     {
   198 // ---------------------------------------------------------------------------
   318 // ---------------------------------------------------------------------------
   199 // Loads content from given mail message.
   319 // Loads content from given mail message.
   200 // ---------------------------------------------------------------------------
   320 // ---------------------------------------------------------------------------
   201 //
   321 //
   202 void CFsEmailUiHtmlViewerContainer::LoadContentFromMailMessageL(
   322 void CFsEmailUiHtmlViewerContainer::LoadContentFromMailMessageL(
   203     CFSMailMessage* aMailMessage )
   323     CFSMailMessage* aMailMessage, TBool aResetScrollPos )
   204     {
   324     {
   205     FUNC_LOG;
   325     FUNC_LOG;
   206     ASSERT( aMailMessage );
   326     ASSERT( aMailMessage );
   207     iMessage = aMailMessage;
   327     iMessage = aMailMessage;
       
   328     // Cancel any browser fetch operation, just in case the browser is still
       
   329     // loading a previous message (since we are about to overwrite it).
       
   330     CancelFetch();
   208     
   331     
   209     TPath headerHtmlFile;
   332     TPath headerHtmlFile;
   210     headerHtmlFile.Copy( iHtmlFolderPath );
   333     headerHtmlFile.Copy( iHtmlFolderPath );
   211     headerHtmlFile.Append( KHeaderHtmlFile );
   334     headerHtmlFile.Append( KHeaderHtmlFile );
   212     
   335     
   213     // insert email header into email.html file
   336     // insert email header into email.html file
   214     // CFreestyleMessageHeaderHTML will replace contents of email.html
   337     // CFreestyleMessageHeaderHTML will replace contents of email.html
   215     // So, no need to clear the contents
   338     // So, no need to clear the contents
   216     CFreestyleMessageHeaderHTML::ExportL( *iMessage, iFs, headerHtmlFile, iAppUi.ClientRect().Width() );
   339     TLanguage language = User::Language();
       
   340     TBidiText::TDirectionality direction = TBidiText::ScriptDirectionality( language );    
       
   341     if(aResetScrollPos)
       
   342         {
       
   343         iScrollPosition = 0; 
       
   344         }
       
   345     CFreestyleMessageHeaderHTML::ExportL( *iMessage, iFs, headerHtmlFile, iAppUi.ClientRect().Width(), 
       
   346                                             iScrollPosition,
       
   347                                             direction);
   217     
   348     
   218     // Remove all previously created files from temporary HTML folder
   349     // Remove all previously created files from temporary HTML folder
   219     EmptyTempHtmlFolderL();
   350     EmptyTempHtmlFolderL();
   220 
   351 
   221     CFSMailMessagePart* htmlBodyPart = iMessage->HtmlBodyPartL();
   352     CFSMailMessagePart* htmlBodyPart = iMessage->HtmlBodyPartL();
   260             
   391             
   261             CleanupStack::PopAndDestroy( contentBuffer8 );
   392             CleanupStack::PopAndDestroy( contentBuffer8 );
   262             CleanupStack::PopAndDestroy( contentBuffer );
   393             CleanupStack::PopAndDestroy( contentBuffer );
   263             CleanupStack::PopAndDestroy( textBodyPart ); 
   394             CleanupStack::PopAndDestroy( textBodyPart ); 
   264             }
   395             }
   265 
       
   266         }
   396         }
   267     // pass the emailHtmlFile to the browser for it to load
   397     // pass the emailHtmlFile to the browser for it to load
   268     if ( bodyPartAvailable )
   398     if ( bodyPartAvailable )
   269         {
   399         {
   270         TPath emailHtmlFile;
   400         TPath emailHtmlFile;
   271         emailHtmlFile.Copy( iHtmlFolderPath );
   401         emailHtmlFile.Copy( iHtmlFolderPath );
   272         emailHtmlFile.Append( KMessageHtmlFile );
   402         if ( direction == TBidiText::ELeftToRight )
       
   403             {
       
   404             emailHtmlFile.Append( KMessageHtmlFile );
       
   405             }
       
   406         else
       
   407             {
       
   408             emailHtmlFile.Append( KMessageHtmlRTLFile );
       
   409             }
   273         LoadContentFromFileL( emailHtmlFile );
   410         LoadContentFromFileL( emailHtmlFile );
   274         }
   411         }
       
   412     
       
   413     UpdateOverlayButtons( ETrue );
   275     }
   414     }
   276 
   415 
   277 // ---------------------------------------------------------------------------
   416 // ---------------------------------------------------------------------------
   278 // Reset content
   417 // Reset content
   279 // ---------------------------------------------------------------------------
   418 // ---------------------------------------------------------------------------
   345 // ---------------------------------------------------------------------------
   484 // ---------------------------------------------------------------------------
   346 //
   485 //
   347 void CFsEmailUiHtmlViewerContainer::SizeChanged()
   486 void CFsEmailUiHtmlViewerContainer::SizeChanged()
   348     {
   487     {
   349     FUNC_LOG;
   488     FUNC_LOG;
       
   489 
       
   490     TRect rect = Rect();
   350     if ( iBrCtlInterface )
   491     if ( iBrCtlInterface )
   351         {
   492         {
   352         TRect rect = Rect();
       
   353         iBrCtlInterface->SetRect( rect );
   493         iBrCtlInterface->SetRect( rect );
   354         }
   494         }
       
   495     
       
   496         if ( iMessage )
       
   497             {
       
   498             // update the width in header part and reload
       
   499             TPath headerHtmlFile;
       
   500             headerHtmlFile.Copy( iHtmlFolderPath );
       
   501             headerHtmlFile.Append( KHeaderHtmlFile );
       
   502                 
       
   503             TRAP_IGNORE( CFreestyleMessageHeaderHTML::ExportL( *iMessage, iFs, headerHtmlFile, 
       
   504                   rect.Width(), iScrollPosition ) )
       
   505                 
       
   506             TPath emailHtmlFile;
       
   507             emailHtmlFile.Copy( iHtmlFolderPath );
       
   508             emailHtmlFile.Append( KMessageHtmlFile );
       
   509             TRAP_IGNORE( LoadContentFromFileL( emailHtmlFile ) )
       
   510             }
       
   511     
       
   512     UpdateOverlayButtons( IsVisible() );
   355     }
   513     }
   356 
   514 
   357 // ---------------------------------------------------------------------------
   515 // ---------------------------------------------------------------------------
   358 // From CCoeControl.
   516 // From CCoeControl.
   359 // ---------------------------------------------------------------------------
   517 // ---------------------------------------------------------------------------
   488             CleanupStack::PopAndDestroy( part );
   646             CleanupStack::PopAndDestroy( part );
   489             }
   647             }
   490         if ( iMessage )
   648         if ( iMessage )
   491             {
   649             {
   492             LoadContentFromMailMessageL( iMessage );
   650             LoadContentFromMailMessageL( iMessage );
       
   651             
       
   652             UpdateOverlayButtons( ETrue );
   493             }
   653             }
   494         }
   654         }
   495     else if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled ||
   655     else if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled ||
   496             aEvent.iProgressStatus < 0 )
   656             aEvent.iProgressStatus < 0 )
   497         {
   657         {
   552 //
   712 //
   553 TBool CFsEmailUiHtmlViewerContainer::ResolveLinkL( const TDesC& aUrl,
   713 TBool CFsEmailUiHtmlViewerContainer::ResolveLinkL( const TDesC& aUrl,
   554     const TDesC& /*aCurrentUrl*/, MBrCtlLinkContent& /*aBrCtlLinkContent*/ )
   714     const TDesC& /*aCurrentUrl*/, MBrCtlLinkContent& /*aBrCtlLinkContent*/ )
   555     {
   715     {
   556     FUNC_LOG;
   716     FUNC_LOG;
   557     return iEventHandler->HandleEventL( aUrl );
   717     if (IsMessageBodyURL(aUrl))
       
   718         {
       
   719         iView.StartFetchingMessageL();
       
   720         return ETrue;
       
   721         }
       
   722     else
       
   723         {
       
   724         if ( NeedToLaunchBrowserL( aUrl ) )
       
   725             {
       
   726             LaunchBrowserL( aUrl );
       
   727             return ETrue;
       
   728             }
       
   729         else
       
   730             {
       
   731             return iEventHandler->HandleEventL( aUrl );
       
   732             }     
       
   733         }
   558     }
   734     }
   559 
   735 
   560 // ---------------------------------------------------------------------------
   736 // ---------------------------------------------------------------------------
   561 // From MBrCtlLinkResolver.
   737 // From MBrCtlLinkResolver.
   562 // ---------------------------------------------------------------------------
   738 // ---------------------------------------------------------------------------
   985 // Writes buffer content to given file after adding tags
  1161 // Writes buffer content to given file after adding tags
   986 // ---------------------------------------------------------------------------
  1162 // ---------------------------------------------------------------------------
   987 //
  1163 //
   988 // <cmail>
  1164 // <cmail>
   989 void CFsEmailUiHtmlViewerContainer::ConvertToHTML( const TDesC8& aContent,
  1165 void CFsEmailUiHtmlViewerContainer::ConvertToHTML( const TDesC8& aContent,
   990     const TDesC& aFileName, CFSMailMessagePart& aHtmlBodyPart )
  1166     const TDesC& aFileName, CFSMailMessagePart& aTextBodyPart )
   991     {
  1167     {
   992     FUNC_LOG;
  1168     FUNC_LOG;
       
  1169     const TInt KBodyTextChunkSizeBytes = 1024;
       
  1170     
   993     if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aContent.Size(), EDriveC ) )
  1171     if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aContent.Size(), EDriveC ) )
   994          {
  1172          {
   995          // Can not write the data, there's not enough free space on disk.
  1173          // Can not write the data, there's not enough free space on disk.
   996          User::Leave( KErrDiskFull );
  1174          User::Leave( KErrDiskFull );
   997         }
  1175         }
   998     else
  1176     else
   999         {
  1177         {
       
  1178         CBufBase* bodyBuf = CBufSeg::NewL( KBodyTextChunkSizeBytes );
       
  1179         CleanupStack::PushL( bodyBuf );
       
  1180         
       
  1181         bodyBuf->InsertL( 0, aContent );
       
  1182         
       
  1183         TInt position( 0 );
       
  1184         TText8 previous = 0;
       
  1185         TBool EndOfString( EFalse );
       
  1186         
       
  1187         while ( !EndOfString )
       
  1188             {
       
  1189             TInt startPosition = position;
       
  1190             TPtr8 segment( bodyBuf->Ptr( startPosition ) );
       
  1191             int i = 0;
       
  1192             
       
  1193             while(i < segment.Length())
       
  1194                 {
       
  1195                 TInt currentPos = position + i;
       
  1196                 TText8 ch = segment[i];
       
  1197                 
       
  1198                 switch( ch )
       
  1199                     {
       
  1200                     case KSOH:  // end of line for IMAP and POP
       
  1201                         bodyBuf->Delete( currentPos, 1 );
       
  1202                         bodyBuf->InsertL( currentPos, KHtmlLineBreakCRLF );
       
  1203                         i += KHtmlLineBreakCRLF().Length();
       
  1204                         segment.Set( bodyBuf->Ptr( startPosition ) );
       
  1205                         break;
       
  1206                     case KLF: // line feed
       
  1207                         if ( previous == KCR )
       
  1208                             {
       
  1209                             bodyBuf->InsertL( currentPos, KHtmlLineBreak );
       
  1210                             i += KHtmlLineBreak().Length();
       
  1211                             segment.Set( bodyBuf->Ptr( startPosition ) );
       
  1212                             }
       
  1213                         else
       
  1214                             {
       
  1215                             i++;
       
  1216                             }
       
  1217                         break;  
       
  1218                     case KQuotation:
       
  1219                         bodyBuf->Delete( currentPos, 1 );
       
  1220                         bodyBuf->InsertL( currentPos, KHtmlQuotation );
       
  1221                         i += KHtmlQuotation().Length();
       
  1222                         segment.Set( bodyBuf->Ptr( startPosition ) );
       
  1223                         break;
       
  1224                     case KAmpersand:
       
  1225                         bodyBuf->Delete( currentPos, 1 );
       
  1226                         bodyBuf->InsertL( currentPos, KHtmlAmpersand );
       
  1227                         i += KHtmlAmpersand().Length();
       
  1228                         segment.Set( bodyBuf->Ptr( startPosition ) );
       
  1229                         break;
       
  1230                     case KGreaterThan:
       
  1231                         bodyBuf->Delete( currentPos, 1 );
       
  1232                         bodyBuf->InsertL( currentPos, KHtmlGreaterThan );
       
  1233                         i += KHtmlGreaterThan().Length();
       
  1234                         segment.Set( bodyBuf->Ptr( startPosition ) );
       
  1235                         break;
       
  1236                     case KLessThan:
       
  1237                         bodyBuf->Delete( currentPos, 1 );
       
  1238                         bodyBuf->InsertL( currentPos, KHtmlLessThan );
       
  1239                         i += KHtmlLessThan().Length();
       
  1240                         segment.Set( bodyBuf->Ptr( startPosition ) );
       
  1241                         break;
       
  1242                     default:
       
  1243                         i++;
       
  1244                         break;
       
  1245                     }
       
  1246                 previous = ch;
       
  1247                 }
       
  1248             position += segment.Length();
       
  1249             if ( ( bodyBuf->Size() - position ) <= 0 )
       
  1250                 {
       
  1251                 EndOfString = ETrue;
       
  1252                 }
       
  1253             }
       
  1254         
       
  1255         CreateHyperlinksFromUrlsL( *bodyBuf );
       
  1256         
  1000         RFile targetFile;
  1257         RFile targetFile;
  1001         CleanupClosePushL( targetFile );
  1258         CleanupClosePushL( targetFile );
  1002 
       
  1003         User::LeaveIfError( targetFile.Replace( iFs, aFileName, EFileWrite ) );
  1259         User::LeaveIfError( targetFile.Replace( iFs, aFileName, EFileWrite ) );
  1004         
  1260         
  1005         HBufC8* charSet = GetCharacterSetL( aHtmlBodyPart );
  1261         HBufC8* charSet = GetCharacterSetL( aTextBodyPart );
  1006         CleanupStack::PushL( charSet );
  1262         CleanupStack::PushL( charSet );
  1007         
  1263         
  1008         User::LeaveIfError( targetFile.Write( KHtmlHeader1 ) );
  1264         RBuf8 messageHeader;
  1009         User::LeaveIfError( targetFile.Write( *charSet ) );
  1265         TInt bufSize = KHtmlHeader1().Length() + charSet->Length() + KHtmlHeader2().Length();
  1010         User::LeaveIfError( targetFile.Write( KHtmlHeader2 ) );
  1266         messageHeader.CreateL( bufSize );
       
  1267         messageHeader.CleanupClosePushL();
       
  1268         
       
  1269         messageHeader.Append( KHtmlHeader1 );
       
  1270         messageHeader.Append( *charSet );
       
  1271         messageHeader.Append( KHtmlHeader2 );
       
  1272         
       
  1273         RFileWriteStream fileStream( targetFile );
       
  1274         fileStream.PushL();
       
  1275         fileStream.WriteL( messageHeader.Ptr(), messageHeader.Length() );
       
  1276         
       
  1277         TInt bufPos( 0 );
       
  1278         TInt bufTotalSize = bodyBuf->Size();
       
  1279         
       
  1280         while ( bufPos < bufTotalSize )
       
  1281             {
       
  1282             TInt segmentLength = bodyBuf->Ptr( bufPos ).Length();
       
  1283             fileStream.WriteL( bodyBuf->Ptr( bufPos ).Ptr(), segmentLength );
       
  1284             bufPos += segmentLength;
       
  1285             }
       
  1286 
       
  1287         fileStream.CommitL();
       
  1288         
       
  1289         CleanupStack::PopAndDestroy( &fileStream );
       
  1290         CleanupStack::PopAndDestroy( &messageHeader );
  1011         CleanupStack::PopAndDestroy( charSet );
  1291         CleanupStack::PopAndDestroy( charSet );
  1012 
  1292         CleanupStack::PopAndDestroy( &targetFile );
  1013 
  1293         CleanupStack::PopAndDestroy( bodyBuf );
  1014         // Write the original content
  1294 
  1015         for(int i=0;i<aContent.Length();i++)
  1295 // </cmail>
  1016             {
  1296         }
  1017           if( i==aContent.Length()-1 )
  1297     }
  1018             {
  1298 
  1019             aContent.Mid( i,1 ).CompareC( _L8("\x01" ) )==0 ? 
  1299 // ---------------------------------------------------------------------------
  1020             User::LeaveIfError( targetFile.Write( _L8("<br>") ) ):
  1300 // Finds and html formats hyperlinks in a document
  1021             User::LeaveIfError( targetFile.Write( aContent.Mid(i,1) ) );
  1301 // ---------------------------------------------------------------------------
  1022             }
  1302 //
  1023           else
  1303 // <cmail>
  1024             {
  1304 void CFsEmailUiHtmlViewerContainer::CreateHyperlinksFromUrlsL( CBufBase& aSource )
  1025             if(aContent.Mid( i,1 ).CompareC( _L8("\x01" ) )==0 ||
  1305     {
  1026             aContent.Mid( i,2 ).CompareC( _L8("\x0D\x0A" ) )==0 ) 
  1306     FUNC_LOG;
  1027               {
  1307     const TInt urlMaxLength = 2048;
  1028               User::LeaveIfError( targetFile.Write( _L8("<br>") ));
  1308     _LIT8( KHttp, "http://" );
  1029               }
  1309     _LIT8( KHttps, "https://");
  1030             else
  1310     _LIT8( KWww, "www."); 
  1031               {
  1311     
  1032           User::LeaveIfError( targetFile.Write( aContent.Mid(i,1) ) );                        
  1312     TBool eos( EFalse );
       
  1313     TInt position( 0 );
       
  1314     TInt carryOverInc( 0 );
       
  1315     
       
  1316     while ( !eos )
       
  1317         {
       
  1318         while ( carryOverInc >= aSource.Ptr( position ).Length() )
       
  1319             { // Skip segments of overlapping url string
       
  1320             carryOverInc -= aSource.Ptr( position ).Length();
       
  1321             position += aSource.Ptr( position ).Length();
       
  1322             }
       
  1323         
       
  1324         TPtr8 segment( aSource.Ptr( position ) );
       
  1325         TLex8 lexSegment( segment );
       
  1326         lexSegment.Inc( carryOverInc );
       
  1327         carryOverInc = 0;
       
  1328         
       
  1329         while (!lexSegment.Eos())
       
  1330             {
       
  1331             TPtrC8 nextToken( lexSegment.NextToken() );
       
  1332             TInt foundAt( KErrNotFound );
       
  1333             
       
  1334             // Find HTTP, HTTPS, or WWW link in CBufSeg segment of size 1024 bytes.
       
  1335             if ( ( ( foundAt = nextToken.FindC( KHttp ) ) != KErrNotFound ) ||
       
  1336                     (  ( foundAt = nextToken.FindC( KHttps ) ) != KErrNotFound ) ||
       
  1337                     ( ( foundAt = nextToken.FindC( KWww ) ) != KErrNotFound ) )
       
  1338                 {
       
  1339                 if ( !lexSegment.Eos() )
       
  1340                     { 
       
  1341                     if ( !foundAt )
       
  1342                         { // Token starts with http/https/www.x
       
  1343                         TPtrC8 url;
       
  1344                         TInt lineBreakPos( KErrNotFound );
       
  1345                         if ( ( lineBreakPos = nextToken.FindC( KHtmlLineBreak ) ) != KErrNotFound )
       
  1346                             { // Token contains html line break -> remove
       
  1347                             url.Set( nextToken.Left( lineBreakPos ) );
       
  1348                             }
       
  1349                         else
       
  1350                             {
       
  1351                             url.Set( nextToken );
       
  1352                             }
       
  1353                         
       
  1354                         if ( url.CompareC( KWww ) != KErrNone ) // if token=www., validate format 
       
  1355                             {                                   // www.x
       
  1356                             RBuf8 urlBuf;
       
  1357                             urlBuf.CreateL( KHtmlLinkTag().Length() + url.Length() * 2
       
  1358                                     + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() );
       
  1359                             urlBuf.CleanupClosePushL();
       
  1360                             // Format html link
       
  1361                             urlBuf.AppendFormat( KHtmlLinkTag, &url );
       
  1362                             urlBuf.Append( url );
       
  1363                             urlBuf.Append( KHtmlLinkEndTag );
       
  1364                             if ( lineBreakPos != KErrNotFound )
       
  1365                                 { // Add line break if removed earlier
       
  1366                                 urlBuf.Append( KHtmlLineBreak );
       
  1367                                 }
       
  1368                             //Test
       
  1369                             TInt nextTokenLength = nextToken.Length();
       
  1370                             TInt segOffset = lexSegment.Offset();
       
  1371                             TInt urlLength = urlBuf.Length();
       
  1372                             
       
  1373                             //Test
       
  1374                             TInt offset = lexSegment.Offset() - nextToken.Length();
       
  1375                             TLexMark8 tokenMark;
       
  1376                             // Move next character last token back
       
  1377                             lexSegment.Inc( - nextToken.Length() );
       
  1378                             lexSegment.Mark( tokenMark );
       
  1379                             aSource.Delete( offset + position, nextToken.Length() );
       
  1380                             aSource.InsertL( offset + position, urlBuf );
       
  1381                             segment.Set( aSource.Ptr( position ) );
       
  1382                             lexSegment.Assign( segment );
       
  1383                             // Set next character to the position of inserted hyperlink
       
  1384                             lexSegment.UnGetToMark( tokenMark );
       
  1385                             
       
  1386                             // If Max segment length is reached, set carry over value to 
       
  1387                             // properly set next character in following CBufSeg segment
       
  1388                             if ( ( offset + urlBuf.Length() ) >= segment.Length() )
       
  1389                                 {
       
  1390                                 carryOverInc = offset + urlBuf.Length() - segment.Length();
       
  1391                                 while ( !lexSegment.Eos() )
       
  1392                                     { // Set to segment's end
       
  1393                                     lexSegment.NextToken(); 
       
  1394                                     }
       
  1395                                 }
       
  1396                             else
       
  1397                                 {
       
  1398                                 lexSegment.Inc( urlBuf.Length() );
       
  1399                                 }
       
  1400                             
       
  1401                             CleanupStack::PopAndDestroy( &urlBuf );
       
  1402                             }
       
  1403                         }
       
  1404                     }
       
  1405                 else
       
  1406                     // Next token is end of string, here we handle the last token of a segment
       
  1407                     {
       
  1408                     _LIT8( KUrlEnd, "<" );
       
  1409                     
       
  1410                     TInt endOfUrlPos( KErrNotFound );
       
  1411                     TText8 ch = segment[ segment.Length() - 1];
       
  1412                     RBuf8 url;
       
  1413                     url.CreateL( urlMaxLength );
       
  1414                     url.CleanupClosePushL();
       
  1415                     
       
  1416                     // Find if hyperlink ends within this segment boundaries
       
  1417                     if ( ch == KSOH || ch == KCR || ch == KLF || ch == KHT || ch == KCharacterSpace )
       
  1418                         {
       
  1419                         endOfUrlPos = nextToken.Length() - 1;
       
  1420                         }
       
  1421                     else if ( ( endOfUrlPos = nextToken.Right( KHtmlLineBreak().Length() ).Find( KUrlEnd ) ) != KErrNotFound )
       
  1422                         {
       
  1423                         endOfUrlPos = nextToken.Length() - KHtmlLineBreak().Length() + endOfUrlPos;
       
  1424                         }
       
  1425                     else
       
  1426                         { // Handle hyperlink spread in multiple segments
       
  1427                         TInt nextPos = position;
       
  1428                         TPtrC8 nextSegment( aSource.Ptr( nextPos ) );
       
  1429                         TLex8 lexNextSegment( nextSegment );
       
  1430                         TPtrC8 nextNextToken( nextToken );
       
  1431                         TBool firstPass( ETrue );
       
  1432                         
       
  1433                         while ( endOfUrlPos == KErrNotFound || nextPos >= aSource.Size() )
       
  1434                             {
       
  1435                             if ( ( url.Length() + nextNextToken.Length() )  > urlMaxLength )
       
  1436                                 { // URL exceeds limit of 2K, do nothing
       
  1437                                 break;
       
  1438                                 }
       
  1439                             
       
  1440                             url.Append( nextNextToken );
       
  1441                             if ( ( nextSegment.Length() == nextNextToken.Length() ) || firstPass )
       
  1442                                 { // Token takes up the whole segment, or first pass( first segment 
       
  1443                                   // with last token where hyperlink does not end within segment's
       
  1444                                   // boundaries, move to next segment
       
  1445                                 nextPos += nextSegment.Length();
       
  1446                                 nextSegment.Set( aSource.Ptr( nextPos ) );
       
  1447                                 lexNextSegment.Assign( nextSegment );
       
  1448                                 nextNextToken.Set( lexNextSegment.NextToken() );
       
  1449                                 if ( firstPass )
       
  1450                                     { 
       
  1451                                     firstPass =  EFalse;
       
  1452                                     }
       
  1453                                 }
       
  1454                             else
       
  1455                                 { // Last segment's token with hyperlink's end
       
  1456                                 if ( ( endOfUrlPos = url.Find( KHtmlLineBreak ) ) != KErrNotFound )
       
  1457                                     { // Remove line break
       
  1458                                     url.Delete( endOfUrlPos, KHtmlLineBreak().Length() );
       
  1459                                     endOfUrlPos = nextNextToken.Length() - KHtmlLineBreak().Length();
       
  1460                                     }
       
  1461                                 else
       
  1462                                     {
       
  1463                                     endOfUrlPos = nextNextToken.Length();
       
  1464                                     }  
       
  1465                                 }
       
  1466                             }
       
  1467  
       
  1468                         if ( endOfUrlPos != KErrNotFound )
       
  1469                             { // Handle hyperlink that is within 2K limit
       
  1470                             RBuf8 urlBuf;
       
  1471                             urlBuf.CreateL( KHtmlLinkTag().Length() + url.Length() * 2
       
  1472                                     + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() );
       
  1473                             urlBuf.CleanupClosePushL();
       
  1474                             // Format html link
       
  1475                             urlBuf.AppendFormat( KHtmlLinkTag, &url );
       
  1476                             urlBuf.Append( url );
       
  1477                             urlBuf.Append( KHtmlLinkEndTag );
       
  1478                             urlBuf.Append( KHtmlLineBreak );
       
  1479                             
       
  1480                             TInt offset = lexSegment.Offset() - nextToken.Length();
       
  1481                             // Remove hyperlink from the original message body
       
  1482                             aSource.Delete( offset + position, url.Length() );
       
  1483                             // Insert html formated hyperlink
       
  1484                             aSource.InsertL( offset + position, urlBuf );
       
  1485                             segment.Set( aSource.Ptr( position ) );
       
  1486                             
       
  1487                             // Set carry on value to mark where new token should start in following segment
       
  1488                             carryOverInc = endOfUrlPos;
       
  1489                             position = nextPos;
       
  1490                             
       
  1491                             CleanupStack::PopAndDestroy( &urlBuf );
       
  1492                             }     
       
  1493                         }
       
  1494                     CleanupStack::PopAndDestroy( &url );
       
  1495                     }
  1033                 }
  1496                 }
  1034               }
  1497             }
  1035             }
  1498         position += segment.Length();
  1036         INFO("Add end tags");
  1499         if ( ( aSource.Size() - position ) <= 0 )
  1037         User::LeaveIfError( targetFile.Write( KHtmlEndTags ) );
  1500             {
  1038             
  1501             eos = ETrue;
  1039 
  1502             }
  1040         CleanupStack::PopAndDestroy( &targetFile );
  1503         }
  1041         }
  1504 
  1042 // </cmail>
  1505     
  1043     }
  1506     }
  1044 
  1507 
  1045 
  1508 
  1046 // ---------------------------------------------------------------------------
  1509 // ---------------------------------------------------------------------------
  1047 // Get Character set from CFSMailMessagePart
  1510 // Get Character set from CFSMailMessagePart
  1074         }
  1537         }
  1075     
  1538     
  1076     CleanupStack::Pop( charSet );
  1539     CleanupStack::Pop( charSet );
  1077     return charSet;
  1540     return charSet;
  1078     }
  1541     }
       
  1542 
  1079 void CFsEmailUiHtmlViewerContainer::StopObserving()
  1543 void CFsEmailUiHtmlViewerContainer::StopObserving()
  1080     {
  1544     {
  1081     if( iObservingDownload )
  1545     if( iObservingDownload )
  1082         {
  1546         {
  1083         if ( iMessage && iAppUi.DownloadInfoMediator() )
  1547         if ( iMessage && iAppUi.DownloadInfoMediator() )
  1114 	CCoeControl::HandleResourceChange( aType );
  1578 	CCoeControl::HandleResourceChange( aType );
  1115 	
  1579 	
  1116 	if ( aType == CFsEmailUiViewBase::EScreenLayoutChanged )
  1580 	if ( aType == CFsEmailUiViewBase::EScreenLayoutChanged )
  1117 		{
  1581 		{
  1118 	    // only update header if we get a layout change from email ui
  1582 	    // only update header if we get a layout change from email ui
  1119 		if ( iMessage )
  1583 		RefreshCurrentMailHeader();
  1120             {
       
  1121             // update the width in header part and reload
       
  1122             TPath headerHtmlFile;
       
  1123             headerHtmlFile.Copy( iHtmlFolderPath );
       
  1124             headerHtmlFile.Append( KHeaderHtmlFile );
       
  1125             
       
  1126             TRAP_IGNORE( CFreestyleMessageHeaderHTML::ExportL( *iMessage, iFs, headerHtmlFile, iAppUi.ClientRect().Width() ) )
       
  1127             
       
  1128             TPath emailHtmlFile;
       
  1129             emailHtmlFile.Copy( iHtmlFolderPath );
       
  1130             emailHtmlFile.Append( KMessageHtmlFile );
       
  1131             
       
  1132             TRAP_IGNORE( LoadContentFromFileL( emailHtmlFile ) )
       
  1133             
       
  1134             SetRect( iAppUi.ClientRect() );
       
  1135             }
       
  1136 		}
  1584 		}
  1137 	}
  1585 	}
       
  1586 
       
  1587 void CFsEmailUiHtmlViewerContainer::RefreshCurrentMailHeader()
       
  1588 	{
       
  1589 	if ( iMessage )
       
  1590 		{
       
  1591 		// Update the width in header part and reload
       
  1592 		TPath headerHtmlFile;
       
  1593 		headerHtmlFile.Copy( iHtmlFolderPath );
       
  1594 		headerHtmlFile.Append( KHeaderHtmlFile );
       
  1595 		
       
  1596 		TLanguage language = User::Language();
       
  1597 		TBidiText::TDirectionality direction = TBidiText::ScriptDirectionality( language );    
       
  1598 		TRAP_IGNORE( CFreestyleMessageHeaderHTML::ExportL( *iMessage, iFs, headerHtmlFile, iAppUi.ClientRect().Width(), direction ) )
       
  1599 		
       
  1600         TPath emailHtmlFile;
       
  1601         emailHtmlFile.Copy( iHtmlFolderPath );
       
  1602         if ( direction == TBidiText::ELeftToRight )
       
  1603             {
       
  1604             emailHtmlFile.Append( KMessageHtmlFile );
       
  1605             }
       
  1606         else
       
  1607             {
       
  1608             emailHtmlFile.Append( KMessageHtmlRTLFile );
       
  1609             }
       
  1610 		
       
  1611         //Load page synchronously if menu invisible
       
  1612         if(!iEventHandler->IsMenuVisible())
       
  1613             {
       
  1614             TRAP_IGNORE( LoadContentFromFileL( emailHtmlFile ) );
       
  1615             SetRect( iAppUi.ClientRect() );
       
  1616             }
       
  1617         //Load page asynchronously after dismissing menu    
       
  1618         else
       
  1619             {
       
  1620             iEventHandler->DismissMenuAndReload();
       
  1621             }		
       
  1622 		}
       
  1623 	}
       
  1624 
       
  1625 void CFsEmailUiHtmlViewerContainer::ReloadPageL()
       
  1626     {
       
  1627     TLanguage language = User::Language();
       
  1628     TBidiText::TDirectionality direction = TBidiText::ScriptDirectionality( language );    
       
  1629     TPath emailHtmlFile;
       
  1630     emailHtmlFile.Copy( iHtmlFolderPath );
       
  1631     if ( direction == TBidiText::ELeftToRight )
       
  1632             {
       
  1633         emailHtmlFile.Append( KMessageHtmlFile );
       
  1634         }
       
  1635     else
       
  1636         {
       
  1637         emailHtmlFile.Append( KMessageHtmlRTLFile );
       
  1638         }
       
  1639     TRAP_IGNORE( LoadContentFromFileL( emailHtmlFile ) );
       
  1640     SetRect( iAppUi.ClientRect() );
       
  1641     }
       
  1642 
       
  1643 /**
       
  1644  * The body fetch link is cmail://body/fetch. Look for the URL separator
       
  1645  * and the presence of cmail and body on the url.
       
  1646  * @param aUrl 
       
  1647  * return ETrue for  a valid body URL
       
  1648  */
       
  1649 TBool CFsEmailUiHtmlViewerContainer::IsMessageBodyURL(const TDesC& aUrl)
       
  1650     {
       
  1651     TInt index = aUrl.Find(KURLSchemeSeparator);
       
  1652     if (index == KErrNotFound)
       
  1653         {
       
  1654         return EFalse;
       
  1655         }
       
  1656     else
       
  1657         {
       
  1658         if (aUrl.Left(index).CompareF(KURLSchemeCmail) == 0)
       
  1659             {
       
  1660             TInt bodyIndex = aUrl.Find(KURLTypeBody);                      
       
  1661             if (bodyIndex == KErrNotFound)
       
  1662                 {
       
  1663                 return EFalse;
       
  1664                 }
       
  1665             else
       
  1666                 {
       
  1667                 TPtrC16 data= aUrl.Mid(bodyIndex);
       
  1668                 TInt separator = data.Find(KURLSlash);
       
  1669                 if(separator == KErrNotFound)
       
  1670                     {
       
  1671                     return EFalse;
       
  1672                     }
       
  1673                 else
       
  1674                     {
       
  1675                     TPtrC16 temp = data.Mid(separator+1);
       
  1676                     TLex lex(temp);
       
  1677                     lex.Val(iScrollPosition);                  
       
  1678                     }
       
  1679                 return ETrue;
       
  1680                 }
       
  1681             
       
  1682             }
       
  1683         else
       
  1684             {
       
  1685             return EFalse;
       
  1686             }
       
  1687         }
       
  1688     } 
       
  1689 // ---------------------------------------------------------------------------
       
  1690 // From MBrCtlWindowObserver
       
  1691 // ---------------------------------------------------------------------------
       
  1692 //
       
  1693 CBrCtlInterface* CFsEmailUiHtmlViewerContainer::OpenWindowL( TDesC& /*aUrl*/, TDesC* /*aTargetName*/, 
       
  1694                                                              TBool /*aUserInitiated*/, TAny* /*aReserved*/ )
       
  1695     {
       
  1696     return iBrCtlInterface;
       
  1697     }
       
  1698 
       
  1699 // ---------------------------------------------------------------------------
       
  1700 // From MBrCtlWindowObserver
       
  1701 // ---------------------------------------------------------------------------
       
  1702 //
       
  1703 CBrCtlInterface* CFsEmailUiHtmlViewerContainer::FindWindowL( const TDesC& /*aTargetName*/ ) const
       
  1704     {
       
  1705     return NULL;
       
  1706     }
       
  1707 
       
  1708 // ---------------------------------------------------------------------------
       
  1709 // From MBrCtlWindowObserver
       
  1710 // ---------------------------------------------------------------------------
       
  1711 //
       
  1712 void CFsEmailUiHtmlViewerContainer::HandleWindowCommandL( const TDesC& /*aTargetName*/, 
       
  1713                                                           TBrCtlWindowCommand /*aCommand*/ )
       
  1714     {
       
  1715     
       
  1716     }
       
  1717 
       
  1718 // ---------------------------------------------------------------------------
       
  1719 // Check if a tap on the URL requires browser(standalone) to be launched
       
  1720 // ---------------------------------------------------------------------------
       
  1721 //
       
  1722 TBool CFsEmailUiHtmlViewerContainer::NeedToLaunchBrowserL( const TDesC& aUrl )
       
  1723     {
       
  1724     TBool launchBrowser( ETrue );
       
  1725     // look for file:///
       
  1726     _LIT( KFileLink, "file:///");
       
  1727     
       
  1728     // This might be linking to header.html or body.html frames
       
  1729     // Ignore them.
       
  1730     if ( aUrl.Left( KFileLink().Length() ).CompareF( KFileLink ) == 0 )
       
  1731         {
       
  1732         //Now there is a chance that this could be from HTML folder
       
  1733         // Replace all slash character with backslash characters
       
  1734         HBufC* embeddedUrl = aUrl.AllocLC();
       
  1735         TPtr ptr = embeddedUrl->Des();
       
  1736         
       
  1737         _LIT( KBackslash, "\\" );
       
  1738         for ( TInt pos = ptr.Locate('/'); pos >= 0; pos = ptr.Locate('/') )
       
  1739             {
       
  1740             ptr.Replace( pos, 1, KBackslash );
       
  1741             }
       
  1742 
       
  1743         // Check whether given url refers to file in the html folder
       
  1744         TInt pos = embeddedUrl->FindF( iHtmlFolderPath );
       
  1745         CleanupStack::PopAndDestroy( embeddedUrl );
       
  1746         pos >= 0 ? launchBrowser = EFalse : ETrue;        
       
  1747         }
       
  1748     // Ignore links starting with cmail://
       
  1749     else if ( aUrl.Left( KURLSchemeCmail().Length() ).CompareF( KURLSchemeCmail ) == 0 )
       
  1750         {
       
  1751         launchBrowser = EFalse;
       
  1752         }
       
  1753 
       
  1754     return launchBrowser;
       
  1755     }
       
  1756 
       
  1757 // ---------------------------------------------------------------------------
       
  1758 // Launch the browser as a standalone app
       
  1759 // ---------------------------------------------------------------------------
       
  1760 //
       
  1761 void CFsEmailUiHtmlViewerContainer::LaunchBrowserL( const TDesC& aUrl )
       
  1762     {
       
  1763     CSchemeHandler* handler = CSchemeHandler::NewL( aUrl );
       
  1764     CleanupStack::PushL( handler );
       
  1765     handler->HandleUrlStandaloneL();
       
  1766     CleanupStack::PopAndDestroy( handler );
       
  1767     }
       
  1768