svgtviewer/SvgtViewerPlugin/AppObserverUtilSrc/SVGTAppObserverUtil.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 09 Sep 2010 11:17:40 +0300
branchRCL_3
changeset 20 5fd161fa28b6
permissions -rw-r--r--
Revision: 201019 Kit: 201035

/*
* Copyright (c) 2004,2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  This class provides helper functions and a reference 
*                implementation for hyperlink handling, image fetching
*                and saving of the svg content. 
*
*/


#include <browserlauncher.h>
#include <DocumentHandler.h>
#include <uri16.h>
#include <uriutils.h>
#include <eikenv.h>
#include <eikappui.h>
#include <eikapp.h>
#include <eikdef.h>
#include <flogger.h>
#include <cdownloadmgruiuserinteractions.h>
#include <cdownloadmgruidownloadslist.h>
#include <cdownloadmgruilibregistry.h>
#include <browseroverriddensettings.h>

#ifdef __SERIES60_NATIVE_BROWSER
#include <browseruisdkcrkeys.h>    // Include only if s60 native 
                                   // browser available
#endif

#include <centralrepository.h> 
#include <apgtask.h>                                      // TApaTaskList
#include <apmstd.h>                                       // RApaLsSession
#include <commdb.h>
#include <ApDataHandler.h>                                // CApDataHandler
#include <ApAccessPointItem.h>                            // CApAccessPointItem
#include <ApUtils.h>                                      // CApUtils
#include <ApSelect.h>                                     // CApSelect 
#include <aknnotewrappers.h>
#include <AknGlobalNote.h>
#include <AknWaitDialog.h>
#include <AknCommonDialogs.h>
#include <AknProgressDialog.h>
#include <StringLoader.h>
#include <data_caging_path_literals.hrh>
#include <bautils.h>
#include <eikprogi.h>
#include <e32svr.h>
#include <svgtappobserverutil.rsg>
#include <SVGTAppObserverUtil.h>
#include <pathinfo.h>
#include <sysutil.h>
#include <imcvcodc.h>   //TImCodecB64
#include <AiwGenericParam.h>

#include "SVGTViewerAppDbgFlags.hrh"
#include "SVGTViewerAppDownloads.h"
#include "SVGTAppObserver.h"                              // temp
#include "SVGTUIDialog.h"                                 // AppDialog
#include "SVGTUIDialog.hrh"

#ifdef RD_MULTIPLE_DRIVE    
#include <AknCommonDialogsDynMem.h>
#endif
// CONSTANTS 

_LIT( KBrowserParameter, "4" ); // magic number for browser to open the URL
_LIT( KSpace, " " );

_LIT(KJpg,   ".jpg" );
_LIT(KJpeg,  ".jpeg" );
_LIT(KPng,   ".png" );
_LIT(KBmp,   ".bmp" );
_LIT(KSvg,   ".svg" );
_LIT(KSvgz,  ".svgz" );

#ifndef __SERIES60_NATIVE_BROWSER
    // Below constants need to be used if s60 native browser is not used.
    const TUid KCRUidBrowser   = {0x10008D39};
    const TUint32 KBrowserDefaultAccessPoint =  0x0000000E;
#endif // __S60_REMOVE_BROWSER

// SMIL Fit Value
_LIT( KSvgtDefSmilFitValue,"meet" );
// Resource file for App Observer Util
_LIT( KResourceFileName, "Z:SVGTAppObserverUtil.rsc" );

_LIT( KEmptyString, "" );
_LIT( KWww, "www" );
_LIT( KHttp, "http://");
_LIT( KDotDot, ".." );
_LIT( KBSlashStr, "/" );
_LIT( KSlashStr, "\\" );
_LIT( KDotSlashStr, ".\\" );
_LIT( KColonStr, ":" );
_LIT( KNewLineStr, "\n" );

#ifdef SVGTVIEWERAPP_DBG_FLAG
_LIT( KFileLoggingDir, "SVGTViewer" );
_LIT( KFileLog, "SaveLog.txt" );
#endif

// Maximum length of thread Id in Characters
const TInt KSvgMaxThreadIdStr = 10;

// ============================ MEMBER FUNCTIONS ===============================


// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
EXPORT_C CSVGTAppObserverUtil* CSVGTAppObserverUtil::NewL( 
                        CSVGTUIDialog* aAppDialog,
                        RFile* aFileHdlPtr,
                        const TDesC& aFilename, 
                        TBool aIsFileFullPathAvailable,
                        TBool aCanSaveContent,
                        TBool aShouldMoveContent)
    {
    CSVGTAppObserverUtil* self = 
                             CSVGTAppObserverUtil::NewLC( aAppDialog,
                                        aFileHdlPtr,
                                        aFilename, 
                                        aIsFileFullPathAvailable,
                                        aCanSaveContent,
                                        aShouldMoveContent );
    CleanupStack::Pop( self );
    return self;   
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::NewLC
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSVGTAppObserverUtil* CSVGTAppObserverUtil::NewLC( CSVGTUIDialog* aAppDialog,
                                            RFile* aFileHdlPtr,
                                            const TDesC& aFilename, 
                                            TBool aIsFileFullPathAvailable,
                                            TBool aCanSaveContent,
                                            TBool aShouldMoveContent)
    {
    CSVGTAppObserverUtil* self = 
                          new( ELeave ) CSVGTAppObserverUtil( aAppDialog );
    CleanupStack::PushL( self );
    self->ConstructL( aFileHdlPtr, aFilename, aIsFileFullPathAvailable, 
            aCanSaveContent, aShouldMoveContent );
    return self;
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
EXPORT_C CSVGTAppObserverUtil* CSVGTAppObserverUtil::NewL( 
                        CSVGTUIDialog* aAppDialog,
                        RFile* aFileHdlPtr )
    {
    CSVGTAppObserverUtil* self = 
                             CSVGTAppObserverUtil::NewLC( aAppDialog,
                                        aFileHdlPtr );
    CleanupStack::Pop( self );
    return self;   
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::NewLC
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSVGTAppObserverUtil* CSVGTAppObserverUtil::NewLC( 
                                            CSVGTUIDialog* aAppDialog,
                                            RFile* aFileHdlPtr )
    {
    CSVGTAppObserverUtil* self = 
                          new( ELeave ) CSVGTAppObserverUtil( aAppDialog );
    CleanupStack::PushL( self );
    
    self->ConstructL( aFileHdlPtr );
    return self;
    }

// -----------------------------------------------------------------------------    
// Destructor
// -----------------------------------------------------------------------------
EXPORT_C CSVGTAppObserverUtil::~CSVGTAppObserverUtil()
    {  
    
#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED         

    CSVGTViewerAppDownloads* downloads;
    
    iDownloadIter.SetToFirst();
    while ((downloads = iDownloadIter++) != NULL)
        {
        downloads->QueLink().Deque();
        delete downloads;
        iDownloadIter.SetToFirst();
        }
    
    // Close the DMgr UI Library first, as it uses the same 
    // Download Manager session that the Viewer uses
    delete iDMgrUiReg;
    
    // Close the Download Manager connection
    iDownloadMgr.Close();

    iDMgrDownloadsList = NULL;
    iDMgrUserInteractions = NULL;  
#endif     
    // Reset the app dialog, it is already freed in OpenFileL
    iAppDialog = NULL;     

    delete iFileManager;
    delete iSvgFileName;
    delete iSvgDstFileName;
    delete iDocHandler;
    
    delete iWaitNote;
    delete iTempFileName;
    if ( iResourceOffset != 0 )
        {
        iEikEnv->DeleteResourceFile( iResourceOffset );
        }
        
    // Reset the SVG File Handle as it is owned by the caller
    iSvgFileId = NULL;
    // Reset the Progress Info implementor pointer
    iProgressInfo = NULL;
    // Reset Environment pointer
    iEikEnv = NULL;
    }
    
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::FetchImage
// Called by Svg engine when there is an image tag encountered in the svg file
// parameters:
// aUri: the uri that needs to be downloaded or fetched locally
// aSession: File Session in which the file is opened.
// aFileHandle: handle of the downloaded file or locally fetched file.
// return value:
// KErrNone if the file is fetched successfully
// KErrNotFound if the file could not be fetched.
// -----------------------------------------------------------------------------
//   
EXPORT_C TInt CSVGTAppObserverUtil::FetchImage( 
                          const TDesC&  aUri , RFs&  aSession , 
                          RFile&  aFileHandle  )
    {
    TInt ret = KErrNone;
    
    TDownloadNeeded downloadNeeded = ELocalImageFile;
    TRAPD( error, downloadNeeded = IsDownloadNeededL( aUri ) );
    
    if ( error != KErrNone )
        {
        return KErrNotFound;
        }
    
    if ( downloadNeeded == ELocalImageFile )
        {
        TFileName fileName;
        if ( GetLocalFile( aUri, fileName, *iSvgFileName ) )
            {
            return aFileHandle.Open( aSession, fileName, EFileShareAny );            
            }
        else
            {
            return KErrNotFound;
            }        
        }
    else if ( downloadNeeded == ERemoteImageFile )
        {
        TRAPD( err,ret = StartDownloadingImageL( aUri, 
                                               aSession,
                                               aFileHandle,
                                               EFalse,
                                               EFalse /* Asynchronous mode */) ); 
        if ( err != KErrNone )
            {
            return KErrNotFound;
            }
        else
            {
            return ret;         
            }
        
        }
    else
        {
        return KErrNotFound;
        }   
    
    }

TInt CSVGTAppObserverUtil::FetchFont( const TDesC& /* aUri */, 
                                    RFs& /* aSession */, RFile& /* aFileHandle */ )
    {
    return KErrNotSupported;
    }

// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::LinkActivated
// Callback Function called by svg engine when a hyperlink is activated
// ---------------------------------------------------------------------------
//

EXPORT_C TBool CSVGTAppObserverUtil::LinkActivated( const TDesC& aUri )
    {  
    if( aUri.Length() == 0 )
        {
        return KErrNone;
        }
    TRAPD( error, LinkActivatedL( aUri ) );
    return ( error == KErrNone );
    }


// --------------------------------------------------------------------
// CSVGTAppObserverUtil::LinkActivatedWithShow
// Callback Function called by the svg engine when a hyperlink with show 
// attribute is activated 
// --------------------------------------------------------------------
//
EXPORT_C TBool CSVGTAppObserverUtil::LinkActivatedWithShow( 
    const TDesC& aUri ,
    const TDesC& aShow )
    {
    if( aUri.Length() == 0 )
        {
        return KErrNone;
        }
    TRAPD( error, LinkActivatedWithShowL( aUri, aShow ) );
    return ( error == KErrNone );
    }    

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::GetSmilFitValue
// Default implementation for observer function to get SMIL fit value.
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::GetSmilFitValue( TDes& aSmilValue )
    {
    aSmilValue.Copy( KSvgtDefSmilFitValue );
    }   
     
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::SetDownloadMenu
// Sets/Unsets the iDownloadMenuEnabled
// -----------------------------------------------------------------------------
//

EXPORT_C void CSVGTAppObserverUtil::SetDownloadMenu( TBool aAddDownloadMenu ) 
    {
    iDownloadMenuEnabled = aAddDownloadMenu;    
    }
    
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::SetDownloadMenu
// Sets/Unsets the iDownloadMenuEnabled
// -----------------------------------------------------------------------------
//    
EXPORT_C TBool CSVGTAppObserverUtil::CanShowDownload() const
    {
        if(iDownloadInProgress || iDownloadDone)
            {
            const CDownloadArray& array = iDownloadMgr.CurrentDownloads();
            return ( array.Count() ? ETrue : EFalse ); 
            }
            
        return EFalse;            
    }       

// --------------------------------------------------------------------
// void CSVGTAppObserverUtil::DisplayDownloadMenuL()
// Call back called by the UI dialog when the downloads menu is 
// selected. This function calls the DisplayDownloadsListL function
// provided by the download manager ui lib.
// --------------------------------------------------------------------
//    
EXPORT_C void CSVGTAppObserverUtil::DisplayDownloadMenuL()
    {   
#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED          
    if ( iDMgrDownloadsList )
        {
        TRAPD( error, iDMgrDownloadsList->DisplayDownloadsListL() );        
            {
            if ( error != KErrNone )
                {
#ifdef _DEBUG                        
                TBuf<64> buffer;
                _LIT(msg, "AP error : %d" );
                buffer.Format( msg, error );
                iEikEnv->InfoMsg( buffer );              
#endif                
                }
            }
        }   
#endif
    }
    
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::HandleDMgrEventL
// Called by Download manager when the image is being downloaded. 
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::HandleDMgrEventL( RHttpDownload& aDownload,
                                       THttpDownloadEvent aEvent ) 
    {
    
#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED       
           
#ifdef _DEBUG        
        TBuf<64> buffer;
        _LIT(msg, "download progressing : %d, %d" );
        buffer.Format( msg, aEvent.iDownloadState, aEvent.iProgressState );
        iEikEnv->InfoMsg( buffer );        
#endif        
        {
        
        if ( EHttpDlInprogress == aEvent.iDownloadState ) 
            {
            iDownloadInProgress = ETrue;
            iDownloadDone = EFalse;
            }
            
        if ( EHttpDlCompleted == aEvent.iDownloadState )
            {  
             
             iDownloadInProgress = EFalse;
             iDownloadDone = ETrue; 
                               
            // Get the download item from the list
            CSVGTViewerAppDownloads* downloadItem;   
            downloadItem = FindDownload( &aDownload );
            
#ifdef _DEBUG                    
                
           
            _LIT(downloadMsg, "download found" );
            iEikEnv->InfoMsg( downloadMsg );
#endif            
                    
                       
            if ( downloadItem )
                {
                // Get the file Name of the downloaded file
                TFileName fileName;
                aDownload.GetStringAttribute( EDlAttrDestFilename, fileName );                
#ifdef _DEBUG                       
                   
                _LIT(fileNameMsg, "got file name " );
                iEikEnv->InfoMsg( fileNameMsg );
#endif            

//##############################################
// For AssignImageData
                DoAssignImageDataL(downloadItem, aDownload);
//##############################################
                downloadItem->SetFileName( fileName );
        
                // Check whether the download happened in a synchronous way
                if ( downloadItem->SynchronousMode() )
                    {                    
                    downloadItem->SetDownloadCompleted( ETrue );
                    
                    // If wait note is being displayed, delete it
                    if ( iWaitNote )
                        {
                        // Delete the download wait note
                        TRAPD( err, iWaitNote->ProcessFinishedL() );
                        if ( err != KErrNone )
                            {
                            delete iWaitNote;
                            iWaitNote = NULL;    
                            }                        
                        }                 

                    // If synchronous stop the scheduler 
                    iWait.AsyncStop();  
                    }
                else    
                    {
                    // Otherwise check the embedded mode and open the file 
                    // using DocHandler
                    downloadItem->QueLink().Deque();
                    delete downloadItem;
                    }
                }
            }
        else 
            {
            // added for if user cancels the download.
             if ( EHttpDlDeleting == aEvent.iDownloadState && !iDownloadDone)   
                {
                 aDownload.Pause();
                aEvent.iDownloadState = EHttpDlFailed;
                }
                
            if ( EHttpDlFailed == aEvent.iDownloadState )
                {       
#ifdef _DEBUG                              
              
                _LIT(failMsg, " downloading failed" );
                iEikEnv->InfoMsg( failMsg );    
#endif               
                                
                TInt32 error = 0;
                TInt32 globalError = 0;
                aDownload.GetIntAttribute( EDlAttrErrorId, error );
                aDownload.GetIntAttribute( EDlAttrGlobalErrorId, globalError );
                
#ifdef _DEBUG                  
                TBuf<64> errorBuffer;
                _LIT(failedMsg, "downloading failed : %d, %d" );
                buffer.Format( failedMsg, error, globalError );
                iEikEnv->InfoMsg( errorBuffer );
#endif               
             
                // Get the download item from the list             
                CSVGTViewerAppDownloads* downloadItem;      
                downloadItem = FindDownload( &aDownload );
                // Check whether the download was started synchronously
               // if( !downloadItem->ImageLinkFlag())
                    {
                    HBufC* lUriBuf = HBufC::NewLC( KMaxUrlLength );
                    TPtr lUriPtr(lUriBuf->Des());
                    aDownload.GetStringAttribute( EDlAttrReqUrl, lUriPtr ); 
                    iAppDialog->AssignImageData(lUriPtr , NULL );
                    CleanupStack::PopAndDestroy( lUriBuf );
                    }
                    
                if ( downloadItem )
                    {
                    if ( downloadItem->SynchronousMode() )
                        {
                        
                        downloadItem->SetDownloadCompleted( EFalse );
                        if ( iWaitNote )
                            {
                            // Delete the download wait note
                            TRAPD( err, iWaitNote->ProcessFinishedL() );
                            if ( err != KErrNone )
                                {
                                delete iWaitNote;
                                iWaitNote = NULL;    
                                }
                            }                 

                        // If synchronous, stop the scheduler started.
                        iWait.AsyncStop();
                        }   
                    else
                        {
                        // Otherwise delete the download item from the list
                        downloadItem->QueLink().Deque();
                        delete downloadItem;
                        }
                    }
                }
            } 
        }
#endif        
    }    
    
// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::LinkActivatedL
// Leave variant of LinkActivated
// Launches the browser in embedded mode and passes the uri to the browser
// if the uri is a web page, if the uri refers to a local image file, or a 
// remote image file, launches the file using doc handler.
// ---------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::LinkActivatedL( const TDesC& aUri )
    {
    
    TDownloadNeeded dnloadNeeded = IsDownloadNeededL( aUri );
    
    if ( dnloadNeeded == ENotAnImageFile )
        {           

        // (2 = length of the first parameter + space)            
        HBufC* parameters = NULL;
        parameters = HBufC::NewLC( aUri.Length() + 2 );
    
        TPtr parametersPtr = parameters->Des();
        parametersPtr.Copy( KBrowserParameter );
        parametersPtr.Append( KSpace );
        parametersPtr.Append( aUri );             
       
        // Create BrowserLauncher
        CBrowserLauncher* launcher = NULL;
    
        launcher = CBrowserLauncher::NewLC();        
        
        TBrowserOverriddenSettings overriddenSettings;
        launcher->LaunchBrowserSyncEmbeddedL( *parameters, NULL, &overriddenSettings );     
        
        //launcher, parameters   
        CleanupStack::PopAndDestroy( 2, parameters );
        }
    else
        {
        if ( dnloadNeeded == ERemoteImageFile )
            {
            RFile fileHandle; // param not going to be used
            RFs fileSession;  // param not going to be used
            StartDownloadingImageL( aUri,
                                    fileSession, 
                                    fileHandle,
                                    EFalse, /* aSynchronous mode */
                                    ETrue,
                                    ETrue /* Embedded mode */ );                                     
            }
        else if ( dnloadNeeded == ELocalImageFile )
            {
            
            TFileName fileName;
            TInt error = KErrNone;            
            
            if ( GetLocalFile( aUri, fileName, *iSvgFileName ) )
                {
                TRAP( error, LaunchDownloadedFileL( fileName, ETrue, EFalse ) );
                } 
            else
                {
                error = KErrNotFound;               
                }
                
            if ( error != KErrNone )
                {
                TInt resourceId;
                resourceId = R_SVGT_FILE_NOT_FOUND;
                // Show information note
                HBufC* prompt = StringLoader::LoadLC( resourceId );
                CAknInformationNote* note = 
                        new ( ELeave ) CAknInformationNote( ETrue );
                note->ExecuteLD( *prompt );

                CleanupStack::PopAndDestroy( prompt );
                }
            }
        else        
            {           
            return;
            }
        }  
    }
      
    
// --------------------------------------------------------------------
// CSVGTAppObserverUtil::LinkActivatedWithShowL
// Called by LinkActivatedWithShow 
// Calls LinkActivatedL
// --------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::LinkActivatedWithShowL( 
    const TDesC& aUri ,
    const TDesC& /*aShow*/ )
    {
    LinkActivatedL( aUri );
    }  
// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::StartDownloadingImageL    
// Called by FetchImage, LinkActivated, LinkActivatedWithShow to download the
// image. This function calls the download manager client Api's to start the 
// download. The download completion will be indicated by the call back 
// HandleDownloadMgrEventL. As FetchImage is a synchronous function
// a CActiveSchedulerWait loop is started, after starting the http download.
// the wait loop is stopped when the call back HandleDownloadMgrEventL is 
// called. 
// 1. CreateDownloadAndSetAttributes
// 2. check result
//    If result no
//          check the status of the download
//          if Completed 
//               return the filehandle
//          if in progress 
//               continue downloading
//          if failed
//               return 
//    else
//        Start Download
// 3. If Synchronous
//        Start DownloadWaitNote
//        Start ActiveSchedulerWait.
// 4. Return
//              
// parameters:
// aUri: the hyperlink that needs to be downloaded.
// aSession: File session in which the file handle is opened.
// aFileHandle: Handle of the downloaded file
// aIsSynchronous: flag indicating whether download is synchronous or not
// aLinkFlag: Image flag to distinguish the Embeded & hyperlink.
// aIsEmbedded: flag indicating whether downloaded file has to opened in 
//              stand alone mode or embedded mode.
// ---------------------------------------------------------------------------
//
TInt CSVGTAppObserverUtil::StartDownloadingImageL(
                    const TDesC& aUri, 
                    RFs& aSession, 
                    RFile& aFileHandle,     
                    TBool aIsSynchronous,
                    TBool aLinkFlag,
                    TBool aIsEmbedded )        
    {  
                                  
#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED           

     
#if defined(__WINS__) || defined(__WINSCW__)
    //do nothing, hard code later on
#else

    
    TUint32 Iapid( 0 );
    if ( !GetDefaultInetAccessPointL( Iapid ) )       
        {            
        return KErrNotFound;    
        }
        
    
    iDownloadMgr.SetIntAttribute( EDlMgrIap, (TInt32)Iapid );
#endif // __wins__|| __winscw__


#ifdef _DEBUG     
    _LIT( setAP, "Access point set" );
    iEikEnv->InfoMsg( setAP ); 
#endif

   
    TInt result = ETrue;     
    // Add lDownload to cleanup stack and pop it after CreateDownloadL.
    CSVGTViewerAppDownloads *lDownload = CSVGTViewerAppDownloads::NewLC( 
            aIsEmbedded, aIsSynchronous, aLinkFlag );  
            
    HBufC8* url8 = NULL;     
    url8 = HBufC8::NewLC( aUri.Length() );    
    url8->Des().Copy( aUri );                      
              
    lDownload->SetDownloadHandle( 
                    &iDownloadMgr.CreateDownloadL( *url8 , result ) );
                    
    CleanupStack::PopAndDestroy( url8 ); // url8                                                                            
        
#ifdef _DEBUG    
    _LIT(dlCreated, "download created" );
    iEikEnv->InfoMsg( dlCreated ); 
#endif    
    
            
    // Add Downloads to the Menu Option
    if ( !iDownloadMenuEnabled && !aIsSynchronous )
        {
        SetDownloadMenu( ETrue );        
        }
            
    if ( !result )                           
        {  
          
        // url is already being downloaded or completed
        // Get the download State
        TInt32 downloadState = 0;
        TInt retval = KErrNone;
        lDownload->DownloadHandle()->GetIntAttribute( EDlAttrState,
                        downloadState );       
       
        if ( downloadState == EHttpDlCompleted )
            {
            TFileName fileName;
            lDownload->DownloadHandle()->GetStringAttribute( EDlAttrDestFilename
                            , fileName );
            if ( aIsSynchronous )
                {
                retval = aFileHandle.Open( aSession, fileName, EFileShareAny );
                }            
            else    
                {
                if(aLinkFlag)
                    {
                    // Handle Launching downloaded file in asynchronous mode                   
                    LaunchDownloadedFileL( fileName, aIsEmbedded , ETrue);    
                    }
                else
                    {
                    DoAssignImageDataL(lDownload, *(lDownload->DownloadHandle()));
                    }
                       
                }                     
            
            CleanupStack::PopAndDestroy( lDownload ); // lDownload     
            return retval;
            }               
        else
            {
            if ( downloadState == EHttpDlFailed )
                { 
                // Retry
                // Add to the linked list 
                iDownloads.AddFirst( *lDownload );               
                CleanupStack::Pop( lDownload ); // lDownload                     
                lDownload->DownloadHandle()->SetBoolAttribute( 
                                   EDlAttrNoContentTypeCheck, ETrue );              
                // Start the download       
                lDownload->DownloadHandle()->Start();
                
                return KErrNone;
                }
            else 
                {                             
                                                                                  
                if ( !FindDownload( lDownload->DownloadHandle() ) )
                    {
                    // Add to the linked list 
                    iDownloads.AddFirst( *lDownload );  
                    CleanupStack::Pop( lDownload ); // lDownload 
                    }
                else
                    {
                    CleanupStack::PopAndDestroy( lDownload ); // lDownload 
                    }
                }                   
            }
        }
    else
        { 
        if ( aIsSynchronous )
            {            
            TFileName fileName( KEmptyString );
            GetFileNameFromUri( aUri, fileName );               
            LaunchWaitNoteL( R_SVGT_DOWNLOAD_WAIT_NOTE, ETrue, fileName );                        
            }
       if ( !aIsSynchronous )
            {            
            lDownload->DownloadHandle()->SetIntAttribute( EDlAttrAction, 
                            lDownload->ImageLinkFlag() ? ELaunch : EDoNothing );             
//                iIsFetchImageCall ? EDoNothing : ELaunch );           
            }
       else
            {
            lDownload->DownloadHandle()->SetIntAttribute( EDlAttrAction,
                                                          EDoNothing );
            lDownload->DownloadHandle()->SetBoolAttribute( EDlAttrSilent, 
                                          ETrue );
            }
            
       lDownload->DownloadHandle()->SetBoolAttribute( 
                                   EDlAttrNoContentTypeCheck, ETrue );
            
                
#ifdef _DEBUG                 
        _LIT(dlCreateMsg, "result true dl created" );
        iEikEnv->InfoMsg( dlCreateMsg ); 
#endif        
       
       // Add to the linked list 
       iDownloads.AddFirst( *lDownload ); 
              
       CleanupStack::Pop( lDownload ); // lDownload     
              
       // Start the download       
       lDownload->DownloadHandle()->Start();
       }
        
    if ( aIsSynchronous )
        {  
        // Start the Scheduler Wait
        if ( !iWait.IsStarted() )
            {
            iWait.Start();
            }        
        
#ifdef _DEBUG                         
        _LIT(waitLoopMsg, "out of wait loop" );        
        iEikEnv->InfoMsg( waitLoopMsg ); 
#endif        
        if ( iSynchronousDownloadStopped )
            {
            // Download dismissed
            // Cancel the download
            lDownload->DownloadHandle()->Delete();                    
            return KErrCancel;     
            }      

        CSVGTViewerAppDownloads* downloadItem = NULL;
        downloadItem = FindDownload( lDownload->DownloadHandle() );
       
        if ( downloadItem )
            {
            TInt retval = KErrNone;
            TBool downloadCompleted = downloadItem->DownloadCompleted();                       
            
            if ( downloadCompleted )
                {                
                retval = aFileHandle.Open( aSession, 
                                           downloadItem->FileName(), 
                                           EFileShareAny );
                }
            else
                {
                retval = KErrNotFound;
                }
            
            downloadItem->QueLink().Deque();                    
            delete downloadItem;
            return retval;      
            }
        else
            {
            return KErrNotFound;     
            }
        }
    else
        {      
        return KErrNone;           
        }
        
#else
        return KErrNotFound;
#endif      
        
    }   

// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::GetDefaultInetAccessPointL
// if the return value is true, aIapId has the default Iap id.
// ---------------------------------------------------------------------------
EXPORT_C TBool CSVGTAppObserverUtil::GetDefaultInetAccessPointL
                              ( TUint32& aIapId ) const
    {

    // Try to find the default AP.
    // The Browser may stores the default AP in the shared data.
    CRepository* repository = CRepository::NewL( KCRUidBrowser );
    CleanupStack::PushL( repository );

    TInt wapApId = 0;
    TRAPD( error, repository->Get( KBrowserDefaultAccessPoint, wapApId ) );
    if ( error != KErrNone )
        {
#ifdef _DEBUG                         
        TBuf<64> buffer;
        _LIT(msg, "AP error : %d" );
        buffer.Format( msg, error );
        iEikEnv->InfoMsg( buffer );
        User::After(1000000);
#endif      
        return EFalse;   
        }
    TUint32 wapApId32( wapApId );
    TUint32 iapId32( 0 );
    
    CleanupStack::PopAndDestroy( repository );

    CCommsDatabase* commsDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
    CleanupStack::PushL( commsDb );
    CApDataHandler* apDataHandler = CApDataHandler::NewLC( *commsDb );
    CApAccessPointItem* apItem = CApAccessPointItem::NewLC();
    TRAPD( err, apDataHandler->AccessPointDataL( wapApId32, *apItem ) );
    CApUtils* apUtils = CApUtils::NewLC( *commsDb );

    TBool wapApFound( EFalse );
    TBool iapFound( EFalse );
    
    if ( err == KErrNone )
        {
        wapApFound = ETrue;
        }
    else 
        {
        // The first valid access point has to be selected if exists
        CApSelect* apSelect = CApSelect::NewLC
            (
                *commsDb, 
                KEApIspTypeAll, 
                EApBearerTypeAll, 
                KEApSortNameAscending
            );
        if ( apSelect->MoveToFirst() )
            {
            wapApFound = ETrue;
            wapApId32 = apSelect->Uid();
            }
        CleanupStack::PopAndDestroy( apSelect ); // apSelect
        }

    if ( wapApFound )
        {
        // Get the IAP ID from the WAP AP ID.
#ifndef __SERIES60_WSP
        iapId32 = 0;
        TRAPD( errTransl, iapId32 = apUtils->IapIdFromWapIdL( wapApId32 ) );
       
        if ( errTransl == KErrNone )
            {
            iapFound = ETrue;
            }
#else
        iapId32 = wapApId32;
        iapFound = ETrue;
#endif // __SERIES60_WSP
        }

    CleanupStack::PopAndDestroy( 4 ); // apUtils, apItem, 
                                      // apDataHandler, commsDb

    if ( iapFound )
        {
        aIapId = iapId32;
        }
    return iapFound;
    }
    
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::LaunchDownloadedFileL
// Called by Download manager when the image is downloaded.
// This function uses the document handler to launch the downloaded file.
// -----------------------------------------------------------------------------
//   
EXPORT_C void CSVGTAppObserverUtil::LaunchDownloadedFileL( const TDesC& aFileName, 
                                        TBool /* aIsEmbedded */,  
                                        TBool aAllowSave ) const
    {            
   
    TDataType dataType = TDataType();
    RFile fileHandle;          
    // Creates a sharable file handle
    iDocHandler->OpenTempFileL( aFileName, fileHandle );                
    CleanupClosePushL( fileHandle );        
    if ( aAllowSave )
        {      
        CAiwGenericParamList& paramList = iDocHandler->InParamListL();                
        // To show/hide save confirmation dlg
        TAiwVariant allowSaveVariant(aAllowSave);
        TAiwGenericParam genericParamAllowSave( EGenericParamAllowSave, 
                                                allowSaveVariant );
        paramList.AppendL( genericParamAllowSave );
        
        iDocHandler->OpenFileEmbeddedL( fileHandle, dataType, paramList );    
        }
    else
        {
        _LIT( KSvgFile, ".svg");
        _LIT( KSvgzFile, ".svgz");
        _LIT( KSvgbFile, ".svgb");
        if(aFileName.Right(4) == KSvgFile || aFileName.Right(5) == KSvgzFile || aFileName.Right(5) == KSvgbFile)
            {
            iDocHandler->OpenFileEmbeddedL( fileHandle, dataType );  
            }
        else
            {
            iDocHandler->OpenFileL( fileHandle, dataType );           
            }
        }
    CleanupStack::PopAndDestroy( &fileHandle ); // fileHandle        
    } 
    
// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::IsDownloadNeededL
// Called by link activated(WithShow), FetchImage 
// to check whether the uri needs a download
// If the filename is present in the uri and if it is a html, 
// returns ENotAnImageFile
// If the host is present & filename is not present, 
// returns ENotAnImageFile
// If the host is present & filename is present, 
// returns ERemoteImageFile
// If the uri doesnt need a download and if it is locally available, 
// returns ELocalImageFile 
// ---------------------------------------------------------------------------
//    
EXPORT_C CSVGTAppObserverUtil::TDownloadNeeded 
      CSVGTAppObserverUtil::IsDownloadNeededL( 
        const TDesC& aUri )
    {

    TUriParser UriParser;
    
    TBuf<KMaxFileName> localUri;
    // url starts with www so append http://
    if ( !aUri.Left( 4 ).Compare( KWww ) )     
        {
        localUri.Append( KHttp );
        localUri.Append( aUri );
        User::LeaveIfError( UriParser.Parse( localUri ) );   
        }
    else
        {
        User::LeaveIfError( UriParser.Parse( aUri ) );   
        }
    
    if ( UriParser.IsPresent( EUriHost ) )
        {
        // Extract the Path, filename and extension from the uri
        TFileName filename = UriParser.Extract( EUriPath ); 
        TParsePtrC fileParser( filename );
    
        if ( fileParser.NamePresent() && fileParser.ExtPresent() )
            {                        
            if ( fileParser.Ext().Compare( KJpg ) == 0  ||  
                 fileParser.Ext().Compare( KJpeg ) == 0 ||
                 fileParser.Ext().Compare( KBmp ) == 0  ||
                 fileParser.Ext().Compare( KPng ) == 0  ||
                 fileParser.Ext().Compare( KSvg ) == 0  ||
                 fileParser.Ext().Compare( KSvgz ) == 0 )
                {
                // file name and ext present and 
                // it is amy of the supported image types
                return ERemoteImageFile;         
                }
            else
                {
                //file Extension present but not a supported image ext,
                //may be some html file
                return ENotAnImageFile;
                }
            } 
        else
            {
            //Should be a domain name so return ENotAnImageFile
            return ENotAnImageFile;
            }
        }
    else
        {     
        return ELocalImageFile;
        }                        
    }

// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::GetFileNameFromUri
// This function gets the filename from the uri, 
// Returns true if the file name is retrieved
// Returns False if the file name could not be retrieved.
// ---------------------------------------------------------------------------
//
EXPORT_C TBool CSVGTAppObserverUtil::GetFileNameFromUri( const TDesC& aUri, 
        TDes& aFileName ) const
    {
    
    const TChar KBSlash = '/';
    TUriParser UriParser;
    if ( UriParser.Parse( aUri ) != KErrNone )
        {
        return EFalse;
        }
    
    if ( UriParser.IsPresent( EUriPath ) )
        {
        // Extract the Path, filename and extension from the uri
        TFileName filename = UriParser.Extract( EUriPath );        
        
        TParse fileParser;
        fileParser.Set( filename, NULL, NULL );
        
        TInt slashPos = filename.LocateReverse( KBSlash );
        if ( slashPos != KErrNotFound )
            {
            aFileName = filename.Right( filename.Length() - (slashPos + 1));
            return ETrue;               
            }
        else
            {
            return EFalse;      
            }      
        
        }
    else
        {
        return EFalse;
        }    
    
    }
// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::GetLocalFile
// This function gets the filename  with full path from the uri, 
// Returns true if the file name is retrieved
// Returns False if the file name could not be retrieved.
// ---------------------------------------------------------------------------
//    
EXPORT_C TBool CSVGTAppObserverUtil::GetLocalFile( 
        const TDesC& aUri, 
        TDes& aFileName ,
        const TDesC& aSvgFileName )
    {
    
    TBuf<KMaxFileName> copyUri = aUri;
    // Before giving the uri to the file parser,
    // convert '/' to '\'.          
    TInt pos;
    while( KErrNotFound != ( pos = copyUri.FindF( KBSlashStr ) ) )
        {
        copyUri.Replace(pos,1,KSlashStr );
        }

    // if the uri starts with ".\" remove ".\"
    if ( copyUri.Left( 2 ).Compare( KDotSlashStr ) == 0 ) 
        {
        copyUri = copyUri.Right( copyUri.Length() - KDotSlashStr().Length() );
        }   
        
    // If the second letter is not ':' 
    // and if it is not starting with '\',
    // and if the path has '/',
    // then prepend slash to it.
    if ( copyUri.Length() >= 2 && 
         copyUri.Mid( 1, 1 ).Compare( KColonStr ) != 0 && 
         copyUri.Mid( 0, 1 ).Compare( KSlashStr ) != 0 &&
         ( copyUri.Find( KSlashStr ) != KErrNotFound ) )
        {
        copyUri.Insert( 0, KSlashStr );
        }       
    
    TParse fileParser;
    if( fileParser.Set( copyUri, NULL, NULL ) != KErrNone )
        {
        return EFalse;
        } 
            
    if ( fileParser.DrivePresent() )
        {
        // The uri is an absolute path
        aFileName.Append( fileParser.Drive() ); 
        // Append path, file name and extension from the uri.
        if ( fileParser.PathPresent() )
            {
            aFileName.Append( fileParser.Path() );              
            }
        if ( fileParser.NamePresent() )
            {
            aFileName.Append( fileParser.Name() );              
            }
        if ( fileParser.ExtPresent() )
            {
            aFileName.Append( fileParser.Ext() );
            }
        RFs session;
        TInt connectError=session.Connect();
        if(connectError==KErrNone)
            { 
            RFile fileHandle;
            TInt openError  = fileHandle.Open( session, aFileName, EFileShareReadersOnly);    
            fileHandle.Close();
            session.Close();
            if ( openError != KErrNone  )
               {
               return EFalse;
               } 
            return ETrue;
            }
        session.Close();
        return EFalse;         
        }
    else
        {
        
        TParse svgFilenameParser;
        if ( svgFilenameParser.Set( aSvgFileName,NULL,NULL ) != KErrNone )
            {
            return EFalse;
            }
        
        if ( svgFilenameParser.DrivePresent() )
            {
            aFileName.Append( svgFilenameParser.Drive() );               
            }
        
        TInt dotdotPos = copyUri.Find( KDotDot );
        TInt rightPos = 0;        
        
        if ( dotdotPos != KErrNotFound )
            {
            // If ".." is present collapse it with the parent path
            if ( svgFilenameParser.PathPresent() )
                {                  
                do   
                    {
                    if ( dotdotPos > 1 )
                        {
                        svgFilenameParser.AddDir( copyUri.Left(dotdotPos - 1) );
                        }
                                                          
                    if ( svgFilenameParser.PopDir() != KErrNone )
                        {
                        return EFalse;
                        }               
                        
                    rightPos = (copyUri.Length()) - (dotdotPos + 3);
                    
                    if ( rightPos > 0 )
                        {                       
                        copyUri = copyUri.Right( rightPos );    
                        }
                                                                                                   
                    }while ( (dotdotPos  = copyUri.Find( KDotDot ) ) 
                                   != KErrNotFound ); 
                                   
                aFileName.Append( svgFilenameParser.Path() );
                aFileName.Append( copyUri );             
                }
            else
                {
                return EFalse;
                }                       
            }
        else
            {
            if ( svgFilenameParser.PathPresent() )
                {
                aFileName.Append( svgFilenameParser.Path() );
                }           
        
            // Append path, file name and extension from the uri.    
            if ( fileParser.PathPresent() )
                {
                //deletes an extra slash in aFileName
                TInt strlen = aFileName.Length();
                if(aFileName.Mid(strlen-1).Compare(KSlashStr) == 0)
                    {
                    aFileName.Delete(strlen-1, 1);
                    }
                aFileName.Append( fileParser.Path() );              
                }
                                
            if ( fileParser.NamePresent() )
                {
                aFileName.Append( fileParser.Name() );              
                }
            if ( fileParser.ExtPresent() )
                {
                aFileName.Append( fileParser.Ext() );
                }
            } 
        RFs session;
        // The error is caught to avoid any code scanner error
        TInt connectError=session.Connect();
        if(connectError==KErrNone)
            {
            RFile fileHandle;
            TInt openError  = fileHandle.Open(session, aFileName, EFileShareReadersOnly );    
            fileHandle.Close();
            session.Close();
            if ( openError != KErrNone  )
                {
                return EFalse;
                }      
            return ETrue;
            }
        session.Close();
        return EFalse;                
        }                                  
    }
               
    
#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED       
// ---------------------------------------------------------------------------
// CSVGTAppObserverUtil::FindDownload
// This iterates through the linked list and return the link 
// corresponding to the given http download handle
// If a link is not found returns NULL.
// ---------------------------------------------------------------------------
//    
CSVGTViewerAppDownloads* CSVGTAppObserverUtil::FindDownload(
                                         const RHttpDownload* aHttpDownload )
    {
    CSVGTViewerAppDownloads* downloadItem;
    TDblQueIter<CSVGTViewerAppDownloads> Iter( iDownloads );    
    if ( !iDownloads.IsEmpty() )
        {
            Iter.SetToFirst();
            while ( ( downloadItem = Iter ) != NULL )
                {
                if ( downloadItem->DownloadHandle() == aHttpDownload )
                    {
                    return downloadItem;
                    }  
                Iter++;
                }            
        }
    return NULL;     
    }
#endif    

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::CSVGTAppObserverUtil
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
EXPORT_C CSVGTAppObserverUtil::CSVGTAppObserverUtil( 
            CSVGTUIDialog* aAppDialog ) :
#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED
             iDownloads( CSVGTViewerAppDownloads::LinkOffset() ) ,
             iDownloadIter( iDownloads ),
             iDownloadMenuEnabled( EFalse ), // construct header & iterator
             iSynchronousDownloadStopped( EFalse ),
#endif 
              iAppDialog( aAppDialog ),
              iSavingDone( EFalse ),
              iCommandId( 0 ),
//              iIsFetchImageCall(EFalse),
              iTempFileUsed( EFalse ),
              iDownloadDone( EFalse ),
              iDownloadInProgress( EFalse )

    {
    }
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::ConstructL()
    { 
  
    // Get the CEikonEnv pointer
    iEikEnv = CEikonEnv::Static(); 
            
    // Find which drive this DLL is installed.
    TFileName fileName;

    // Get the full resource file
    TParse fp;

    // Add the resource dir
    fp.Set( KResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL);

    // Get the filename with full path
    fileName = fp.FullName();

    BaflUtils::NearestLanguageFile( iEikEnv->FsSession(), fileName ); //for
                                                               // localization
    iResourceOffset = iEikEnv->AddResourceFileL( fileName );


    // File manager utility needed for saving/moving files.
    iFileManager = CSVGTFileManager::NewL();
    
    iDocHandler = CDocumentHandler::NewL(); 

#ifdef SVGTVIEWERAPP_DOWNLOADMGR_ENABLED
    TUid hostUid = iEikEnv->EikAppUi()->Application()->AppDllUid();
       
    //creates a download manager session
    //parameters - uid, mhttpdownloadmgrobserver
    //embedded mode on - master flag True has to be passed when the app is 
    //in stand alone mode, false in case of embedded mode
    iDownloadMgr.ConnectL( hostUid ,*this , EFalse /* Embedded mode*/);
    // When SVGT Viewer exits, all the downloads are 
    // cancelled by the download manager
    iDownloadMgr.SetIntAttribute( EDlMgrExitAction , EExitDelete );

    iDMgrUiReg  = CDownloadMgrUiLibRegistry::NewL( iDownloadMgr );
    iDMgrDownloadsList = &iDMgrUiReg->RegisterDownloadsListL();
    iDMgrUserInteractions = &iDMgrUiReg->RegisterUserInteractionsL();
    iDMgrUserInteractions->SetBoolAttributeL( CDownloadMgrUiUserInteractions::EAttrSuppressDownloadConfirmation,
                                              ETrue );
#endif  
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::ConstructL(
                                            RFile* aFileHdlPtr,
                                            const TDesC& aFilename, 
                                            TBool aIsFileFullPathAvailable,
                                            TBool aCanSaveContent,
                                            TBool aShouldMoveContent )
    {
    iIsFullFilePathValid = aIsFileFullPathAvailable;
    iCanSaveContent = aCanSaveContent;
    iShouldMoveContent = aShouldMoveContent;
    iSvgFileId = aFileHdlPtr;
    if ( aIsFileFullPathAvailable )
        {
        iSvgFileName = aFilename.AllocL();
        }
    else
        {
        TFileName fullPathName;
        iSvgFileId->FullName( fullPathName );
        iSvgFileName = fullPathName.AllocL();
        }
    ConstructL();
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::ConstructL(
                                            RFile* aFileHdlPtr
                                            )
    {
    TBuf<1> lDummyFileName; /* This is needed by ConstructL, 
                               but will be ignored */
    
    ConstructL( aFileHdlPtr, 
                lDummyFileName, 
                EFalse /* IsFileFullPathAvailable */, 
                ETrue  /* CanSaveContent */,
                EFalse /* aShouldMoveContent */
              );
    }
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::CanShowSave
// Tells the SVG-T dialog if the save option should be displayed.
// e.g. If the dialog is launched from SVG-T viewer and which is launched
// embedded from Browser/Messaging then Save option would be displayed.
// Also when MMS launches the dialog.
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CSVGTAppObserverUtil::CanShowSave()
{
    return iCanSaveContent;
}

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::CanShowSave
// Tells the SVG-T dialog if saving of the content is done.
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CSVGTAppObserverUtil::IsSavingDone()
{
    return iSavingDone;
}
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::DoSaveL
// Performs the save operation on the content opened. 
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::DoSaveL( TInt aCommandId )
    {
    iCommandId = aCommandId;
    // Get filename.
    // Run Dialog.
    // Need to pause content
    iAppDialog->ProcessCommandL( ESvgtDlgPauseCommand );

    // Get the currently playing svg file's name and extension.    
    HBufC* lFileNameBuf = HBufC::NewLC( KMaxFileName );
    TPtr lFileNamePtr = lFileNameBuf->Des();
    GetFileNameAndExt( lFileNamePtr );
   
 #ifndef RD_MULTIPLE_DRIVE    
    // Get User's choice of name and folder for target file.
    TBool retval = AknCommonDialogs::RunSaveDlgNoDirectorySelectionLD(
        lFileNamePtr,
        R_SVGT_SAVE_LOCATIONS );
#else
      
    TBool retval = AknCommonDialogsDynMem::RunSaveDlgNoDirectorySelectionLD( 
                                         AknCommonDialogsDynMem::EMemoryTypeRemote | 
                                         AknCommonDialogsDynMem::EMemoryTypePhone | 
                                         AknCommonDialogsDynMem::EMemoryTypeMMC, 
                                         lFileNamePtr, R_SVGT_SAVE_LOCATIONS);
#endif
    
    if ( retval )
        {
        // User chose a valid file name        
        TBool lMoveFlag = EFalse;
        TBuf<1> lDummyFileName;
        RFile lDummyFile;
        TInt errSaveContent = KErrNone;
        TInt errSaveText = KErrNone;
        
        // Assume it is not the overwrite case by default
        iIsOverwriteCase = EFalse; 

        // Get the currently playing svg file's full path
        HBufC* lFullFilePathBuf = HBufC::NewLC( KMaxFileName );
        TPtr lFullFilePathPtr = lFullFilePathBuf->Des();
        
        if ( iSvgFileId )
            {
            iSvgFileId->FullName( lFullFilePathPtr );
            }
        // Check if file name is same as orig file -> overwrite case
        if ( !( lFileNamePtr.CompareF( lFullFilePathPtr ) ) )
            {
            iIsOverwriteCase = ETrue;
            }
        CleanupStack::PopAndDestroy( lFullFilePathBuf );
        lFullFilePathBuf = NULL;
               
        // Check if text edit happened
        if ( iAppDialog->IsTextContentChanged() )
            {
            if ( iTempFileName )
                {
                delete iTempFileName;
                iTempFileName = NULL;
                }
            iTempFileName = HBufC::NewL( KMaxFileName );
            TPtr lTempFilePtr = iTempFileName->Des();
            
            // Indicate that cleanup is to be performed in SVGTSavingDoneL        
            iTempFileUsed = ETrue;        
            
            TRAP( errSaveText, SaveSvgTextContentL( *iSvgFileId, lTempFilePtr ) );
            
            if ( !errSaveText )
                {
                // Temp file should be moved instead of
                // original file
                lMoveFlag = ETrue;

                if ( IsAllowMove() || iIsOverwriteCase )
                    {
                    // Based on Move option/self overwrite case, need to close 
                    // the content being played.           
                    // Need to close the currently running file-handle, 
                    // need to inform dialog to stop using it.
                    iAppDialog->StopUsingContentFileHandle();
                    iSvgFileId->Close(); 
                    }
                
                if ( IsAllowMove() )
                    {
                    // Remember that the original file should 
                    // be deleted if file save is successful.
                    iDeleteOrigFile = ETrue;    
                    }
                    

                TRAP( errSaveContent, SaveContentL( 
                      lDummyFile, 
                      lTempFilePtr,
                      lFileNamePtr, 
                      lMoveFlag ));            
                }
            }
            else // No text editing happened
                {

                if ( IsAllowMove() || iIsOverwriteCase )
                    {
                    // Based on Move option/self overwrite case, need to close 
                    // the content being played.           
                    // Need to close the currently running file-handle, 
                    // need to inform dialog to stop using it.
                    iAppDialog->StopUsingContentFileHandle();
                    iSvgFileId->Close(); 
                    }
                
                if ( IsAllowMove() )
                    {
                    lMoveFlag = ETrue;
                    TRAP( errSaveContent, SaveContentL( 
                        lDummyFile, 
                        *iSvgFileName,
                        lFileNamePtr, 
                        lMoveFlag ));
                    }
                    else
                        {
                        TRAP( errSaveContent, SaveContentL( 
                            *iSvgFileId, 
                            lDummyFileName,
                            lFileNamePtr, 
                            lMoveFlag ));
                        }
                }

        CleanupStack::PopAndDestroy( lFileNameBuf );
            
            
        if ( errSaveText || errSaveContent )
            {
            // If disk full problem, display note.
            if ( errSaveContent == KErrDiskFull || errSaveText == KErrDiskFull )
                {
                // mmc full note
                HBufC* text = StringLoader::LoadLC( R_SVGT_MMC_FULL );
                CAknGlobalNote* note = CAknGlobalNote::NewLC();
                note->SetSoftkeys( R_AVKON_SOFTKEYS_OK_EMPTY__OK );
                note->ShowNoteL( EAknGlobalErrorNote, *text );
                CleanupStack::PopAndDestroy(2);// note, text
                }

            // If temporary file was used, perform cleanup
            if ( iTempFileUsed )
                {
                if ( iTempFileName )
                    {
                    // Try and delete the temp file, ignore the error.
                    iEikEnv->FsSession().Delete( iTempFileName->Des() );
                    delete iTempFileName;
                    iTempFileName = NULL;
                    }
                iTempFileUsed = EFalse;
                }
                        
            // If the File Couldn't be Moved, then Open the original
            // file again and Set it back to dialog.
            if ( IsAllowMove() )
                {
                if( iSvgFileId->Open(iEikEnv->FsSession(),
                        iSvgFileName->Des(), EFileShareAny) != KErrNone )
                    {
                    // This should not happen, Couldn't reopen back the
                    // Original content!, No Point in showing save.
                    iCanSaveContent = EFalse; 
                    return;
                    }
                else
                    {
                    iAppDialog->StartUsingContentFileHandle();
                    }
                }
            }
            else
                {
                LaunchWaitNoteL( R_SVGT_SAVING_WAIT_NOTE, ETrue, lDummyFileName );
                }
        }
    else
        {
        // User pressed cancel in save dialog - cleanup
        CleanupStack::PopAndDestroy( lFileNameBuf );
        }
    }

EXPORT_C TInt CSVGTAppObserverUtil::NewFetchImageData( const TDesC& aUri )
    {
//    iIsFetchImageCall = ETrue
    TInt ret = KErrNone;
    
    TDownloadNeeded downloadNeeded = ELocalImageFile;
    TRAPD( error, downloadNeeded = IsDownloadNeededL( aUri ) );
    
    if ( error != KErrNone )
        {
        return KErrNotFound;
        }
    
    if ( downloadNeeded == ELocalImageFile )
        {
        TFileName fileName;
        if ( GetLocalFile( aUri, fileName, *iSvgFileName ) )
            {
            TRAPD(error, DoAssignLocalFileDataL( aUri, fileName ));
            return error;
            }
        else
            {
            iAppDialog->AssignImageData(aUri , NULL );
            return KErrNotFound;
            }        
        }
    else if ( downloadNeeded == ERemoteImageFile )
        {
        //creatred for Dummy purpose 
        RFs fs; 
        RFile file;
        
        TRAPD( err,ret = StartDownloadingImageL( aUri, fs, file,
                                               EFalse,
                                               EFalse /* Asynchronous mode */) ); 
        if ( err != KErrNone )
            {
            return KErrNotFound;
            }
        else
            {
            return ret;         
            }
        
        }
    else
        {
        return KErrNotFound;
        }   
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::SaveContentL
// Performs the save operation on the content opened given 
// source file handle, src/dst filename and whether to move/copy. 
// -----------------------------------------------------------------------------
//
void CSVGTAppObserverUtil::SaveContentL( RFile& aSrcFileHandle, // Used in copy
                                         const TDesC& aSrcFileName,   // Used in move
                                         TDes& aDstFileName,    // Dest File name
                                         TBool aMoveFlag )      // ETrue = Move
    {
    TInt ret = KErrNone;        
    // Start Saving Operation.        
    // Create directory 
    TInt error = iEikEnv->FsSession().MkDirAll( aDstFileName );
    if ( error != KErrNone && error != KErrAlreadyExists )
        {
        User::Leave( error );
        }
  
    // Check if the content should be moved. e.g. In Browser case.
    iFileManager->SetAllowMove( aMoveFlag );

    // Ask FileManager to start saving. ObserverUtil acts as
    // observer for filemanager operations. Based on whether
    // the Move operation is required or not,
    // there are two versions of filecopy operations.
    // In Move Full filepath is required
    if ( aMoveFlag )
        {
        if ( IsFileFullPathAvailable() )
            {
            // Keep the Destination file reference.
            if ( iSvgDstFileName )
                {
                delete iSvgDstFileName;
                iSvgDstFileName = NULL;
                }
            iSvgDstFileName = aDstFileName.AllocL();

            // Start the Move Now.
            ret = iFileManager->StartCopyOperationL( 
                this, aSrcFileName, aDstFileName );
            }
        else
            {
            // Shouldn't happen. If Move operation is required,
            // Full file path must be there.
            ret = KErrPathNotFound;  
            }
        }
    else
        {
        ret = iFileManager->StartCopyOperationL(
            this, aSrcFileHandle, aDstFileName );
        }
    User::LeaveIfError( ret );
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::GetUniqueFileName
// Generates a unique filename in the private directory
// -----------------------------------------------------------------------------
//
void CSVGTAppObserverUtil::GetUniqueFileName( TDes& aName ) const
    {
    TFileName lPpath;
    iEikEnv->FsSession().PrivatePath( lPpath );
    RThread lThread;
    _LIT( KFNameFormatStr,"%u");
    TBuf<KSvgMaxThreadIdStr> lThreadIdStr;
    lThreadIdStr.Format( KFNameFormatStr, (TUint)(lThread.Id()) );
    aName.Append( lPpath );
    aName.Append( lThreadIdStr );
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::IsGzipContent
// Checks whether the file is a GZipped content
// -----------------------------------------------------------------------------
//
TBool CSVGTAppObserverUtil::IsGzipContent( const RFile& aFileHandle ) const
{
    TUint8 ids[2];
    TPtr8 des( ids, 0, sizeof( TUint8 ) * 2 );
    TInt zero = 0;    
    
    // Reset to the beginning
    aFileHandle.Seek( ESeekStart, zero );
    
    // Read the first two bytes
    if ( aFileHandle.Read( des ) != KErrNone )
        {
        return EFalse;
        }

    // reset to start of file
    aFileHandle.Seek( ESeekStart, zero );
    return ( ids[0] == 31 && ids[1] == 139 );
//    return ( ids[0] == EZGZipFile::ID1 && ids[1] == EZGZipFile::ID2 );
}

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::SaveSvgContent
// Saves the SVG content to a temporary file
// -----------------------------------------------------------------------------
//
void CSVGTAppObserverUtil::SaveSvgTextContentL( const RFile& aSrcFileHandle,  
    TDes& aTempFileName )
    {
    TFileName lTempFileName;

    // Save the content path
    HBufC* lOrigFileNameBuf = HBufC::NewLC( KMaxFileName ); 
    TPtr lOrigFileNamePtr = lOrigFileNameBuf->Des();
    aSrcFileHandle.FullName( lOrigFileNamePtr );
    
    // Create the temp file in the same drive as the content file
    TParsePtrC lOrigPath( lOrigFileNamePtr );
    
    // Put the drive into the path
    lTempFileName.Append( lOrigPath.Drive() );
    
    // lOrigFileNameBuf no longer needed. No more references to
    // lOrigFileNamePtr.
//    CleanupStack::PopAndDestroy( lOrigFileNameBuf ); 
    
    // Generate a unique file name
    GetUniqueFileName( lTempFileName );
    
    TInt lOrigFileSize = 0;
    TInt lFileSizeErr = aSrcFileHandle.Size( lOrigFileSize );
    if ( lFileSizeErr )
        {
        User::Leave( lFileSizeErr );
        }
        
    // Check whether freespace available
    // Assume that the new file occupies same amount of space as the original 
    // file. Not so in the case of svgz file. 
#ifndef RD_MULTIPLE_DRIVE
    if( lOrigPath.Drive().CompareF( PathInfo::MemoryCardRootPath().Left(2) ) 
        == 0 )
        {
        if (SysUtil::MMCSpaceBelowCriticalLevelL(&(iEikEnv->FsSession()),
            lOrigFileSize ))
            {            
            User::Leave( KErrDiskFull ); // MMC full, Avkon shows note
            }
        }
    else
        {
        if (SysUtil::FFSSpaceBelowCriticalLevelL(&(iEikEnv->FsSession()),
            lOrigFileSize ))
            {
            User::Leave( KErrDiskFull ); // Phone memory full, Avkon shows 
                                         // note
            }
        }  
#else
//******************* Added to support multiple drives    *************************
    TInt intDrive;
    TChar ch = lOrigPath.Drive()[0];
    
    User::LeaveIfError( RFs::CharToDrive(ch,intDrive) );
    
    if( SysUtil::DiskSpaceBelowCriticalLevelL(&(iEikEnv->FsSession()),
                                lOrigFileSize, intDrive ))
        {
        User::Leave( KErrDiskFull ); // MMC full, Avkon shows note
        }

//*********************************************************************************
#endif
    // lOrigFileNameBuf no longer needed. No more references to
    // lOrigFileNamePtr.
    CleanupStack::PopAndDestroy( lOrigFileNameBuf ); 

    // Create the directory to the temp filename
    TInt lDirCreateError = iEikEnv->FsSession().MkDirAll( lTempFileName  );
    
    // Ignore error if the directory already exists
    if ( lDirCreateError  != KErrNone && lDirCreateError != KErrAlreadyExists )
        {
        User::Leave( lDirCreateError );
        }
    
    // Save the changed SVG content to that file name
    iAppDialog->SaveSvgDom( lTempFileName );
    
    // Check if content is gzipped
    if ( IsGzipContent( aSrcFileHandle ) )
        {
        // Zip the content
        }
    aTempFileName = lTempFileName;
    }
    
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::GetFileNameAndExt
// -----------------------------------------------------------------------------
// 
EXPORT_C void CSVGTAppObserverUtil::GetFileNameAndExt(TDes& filename) const
{

    // If FileName is valid use that, else check filehandle
    // and give back file-name from that.
    if ( iIsFullFilePathValid )
        {
            if ( iSvgFileName )
                {
                TParsePtrC p(*iSvgFileName);
                TPtrC ptr(p.NameAndExt());
                filename = ptr;
                }
        }
    else
        {
            if ( iSvgFileId )
                {
                iSvgFileId->Name( filename );
                }
        }

}

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::IsAllowMove
// -----------------------------------------------------------------------------
EXPORT_C TBool CSVGTAppObserverUtil::IsAllowMove() const
{
    return iShouldMoveContent;
}

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::IsFileFullPathAvailable
// -----------------------------------------------------------------------------
EXPORT_C TBool CSVGTAppObserverUtil::IsFileFullPathAvailable() const
    {
    return 1;
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::LauncWaitNoteL
// -----------------------------------------------------------------------------
//
void CSVGTAppObserverUtil::LaunchWaitNoteL(TInt aResourceId, 
        TBool aVisibilityDelayOff, const TDesC& aFileName )
    {
  
    delete iWaitNote;
    iWaitNote = NULL;
    iProgressInfo = NULL;
    
    if ( aResourceId == R_SVGT_DOWNLOAD_WAIT_NOTE )
        {
        iWaitNote = new (ELeave) CAknWaitDialog( (CEikDialog**)&iWaitNote, 
                                                      aVisibilityDelayOff );
        iWaitNote->PrepareLC(aResourceId);  
        
        TInt resourceId = R_SVGT_DOWNLOADING_FILE;
        HBufC* downloadMsg = StringLoader::LoadLC( resourceId );
        
        TBuf<KMaxFileName> titleString;                
        titleString.Append( downloadMsg->Des() );
        
        CleanupStack::PopAndDestroy( downloadMsg ); // downloadMsg
        
        // Add a force line feed to the note: 
        // qtn_svgt_waiting_downloading [ Downloading file ],
        // and the note will read like this:
        //     Downloading file
        //     filename
        titleString.Append( KNewLineStr );
       
        // Append the filename
        titleString.Append( aFileName );
        
        iWaitNote->SetTextL( titleString );
        
        iWaitNoteState = EDownloadImageWait;                                              
        }
    else if ( aResourceId == R_SVGT_SAVING_WAIT_NOTE )
        {
        iWaitNote = new (ELeave) CAknProgressDialog( (CEikDialog**)&iWaitNote, 
                                                      aVisibilityDelayOff );
        iWaitNote->PrepareLC(aResourceId);
        iProgressInfo = iWaitNote->GetProgressInfoL();
        iProgressInfo->SetFinalValue( KSVGTPercent );
        iWaitNoteState = ESaveFileWait;                                              
        }
    else
        {
        return;
        }
  
    if ( iWaitNote ) 
        {
        iWaitNote->SetCallback(this);
        iWaitNote->RunLD();
        }    
    else
        {
        return;
        }
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::DialogDismissedL
// This is for CAknWaitDialog callback
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::DialogDismissedL( TInt aButtonId )
    {
    
    switch (aButtonId)
        {
        case EAknSoftkeyQuit:
            {
            if ( iWaitNoteState == ESaveFileWait )
                {
                // Handle Save Cancel
                iFileManager->CancelCopy();            
                // Resume the presentation
                iAppDialog->ProcessCommandL( iCommandId );      
                }
            else if ( iWaitNoteState == EDownloadImageWait )
                {
                if ( iWait.IsStarted() )
                    {
                    iSynchronousDownloadStopped = ETrue;
                    iWait.AsyncStop();                              
                    }    
                }
                else
                    {
                    return;
                    }
            break;          
            }
        default:
            break;
        }                  
    }


// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::SVGTSavingDoneL
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::SVGTSavingDoneL( TInt aError )
    {
#ifdef SVGTVIEWERAPP_DBG_FLAG    
    TBuf<40> msg;
    _LIT( errorMsg, "Save Done Err %d" );
    msg.Format(errorMsg, aError );
    PrintDebugMsg( msg );
#endif       
    // If temporary file was used then, perform cleanup
    if ( iTempFileUsed )
        {
        if ( iTempFileName )
            {
            iEikEnv->FsSession().Delete( iTempFileName->Des() );
            delete iTempFileName;
            iTempFileName = NULL;
            }
        iTempFileUsed = EFalse;            
        }
    
    // Indicate to the dialog about the save completion
    iAppDialog->SaveComplete( aError );
    
    if ( !aError )
        {
        iSavingDone = ETrue;
        }
        
    if( iWaitNote )
        {
        if ( !aError && iProgressInfo )
            {
            iProgressInfo->SetAndDraw( KSVGTPercent );
            }
        iWaitNote->ProcessFinishedL();      
        delete iWaitNote;
        iWaitNote = NULL;    
    
#ifdef SVGTVIEWERAPP_DBG_FLAG        
        _LIT( errorMsg, "Proc Finished called" );        
        PrintDebugMsg( errorMsg() );  
#endif          
          
        }
           
    if ( !aError )
        {

        // "saved" note
        HBufC* text = StringLoader::LoadLC(R_SVGT_CLIP_SAVED);
        CAknInformationNote* dlg = new (ELeave) CAknInformationNote( ETrue );
        dlg->ExecuteLD(*text);
        CleanupStack::PopAndDestroy( text );  // text   

        
        }
    else
        {
        iEikEnv->HandleError( aError );
        }
    
    // If move allowed or it is the overwriting self case then             
    if ( IsAllowMove() || iIsOverwriteCase )
        {
        if ( !aError )
            {
            // No error occurred
            
            // File has been moved and source
            // deleted hence don't show save now.    
            iCanSaveContent = EFalse; 
            // If It was Move operation, then Open the new file
            // and give the handle to dialog.
            if ( iSvgFileId->Open(iEikEnv->FsSession(),
                 iSvgDstFileName->Des(), EFileShareAny) != KErrNone )
                {
                // Shouldn't happen. 
                return;
                }
            else
                {
                iAppDialog->StartUsingContentFileHandle();
                }
            }
        else // Error occurred while saving, try to recover
            {
            // If it was Move Operation, and failed, then Open
            // Original Source file again and give the handle to
            // dialog. Note this could fail potentially as the
            // original file could have been deleted.
            if ( iSvgFileId->Open(iEikEnv->FsSession(),
                 iSvgFileName->Des(), EFileShareAny) != KErrNone )
                {
                //Inconsistent state, can't show save also.
                iCanSaveContent = EFalse; 
                return;
                }
            else
                {
                // Can keep showing the save option still.
                iAppDialog->StartUsingContentFileHandle();
                }
            }
        }
    
    if ( !aError )
        {
        if ( iDeleteOrigFile )
            {
            iEikEnv->FsSession().Delete( iSvgFileName->Des() );
            iSvgFileName->Des().Zero();
            }
        // Pass the command id back to UiDialog
        iAppDialog->ProcessCommandL( iCommandId );  
        }
    }

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::SVGTPositionChanged
// -----------------------------------------------------------------------------
//
EXPORT_C void CSVGTAppObserverUtil::SVGTPositionChanged(TInt aPosition)
    {
    if (iWaitNote && iProgressInfo)
        {
        iProgressInfo->SetAndDraw(aPosition);
        }
    /*
    else if (iFullScreen)
        {
        TRAPD(ignore, iContainer->UpdateBufferingL(aPosition) ); 
        } // (L961)
        */
    }
   
#ifdef SVGTVIEWERAPP_DBG_FLAG    
// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::PrintDebugMsg
// -----------------------------------------------------------------------------
//
void CSVGTAppObserverUtil::PrintDebugMsg( const TDesC&  aMsg )
    {
#ifdef _DEBUG
    RFileLogger::Write( KFileLoggingDir, KFileLog, 
                        EFileLoggingModeAppend, aMsg );
#endif    
    }
#endif

// -----------------------------------------------------------------------------
// CSVGTAppObserverUtil::DoAssignImageDataL
// Reads the downloaded file & gives data to the svg engine.
// -----------------------------------------------------------------------------
//
void CSVGTAppObserverUtil::DoAssignImageDataL(const CSVGTViewerAppDownloads* aDownloadItem,
                                                RHttpDownload& aDownload)
    {
    if( aDownloadItem && !aDownloadItem->ImageLinkFlag() )
        {
        TFileName lFileName;
        // Get the file path of the downloaded file
        aDownload.GetStringAttribute( EDlAttrDestFilename, lFileName );

        TInt lFileSize = 0;
        RFile lSvgFile;
        // Attempt to open the file in read mode
        User::LeaveIfError( lSvgFile.Open(iEikEnv->FsSession(),lFileName,EFileRead ) );
        
        // Save on cleanup stack
        CleanupClosePushL( lSvgFile );
        
        // Get the size of the data to create read buffer
        User::LeaveIfError( lSvgFile.Size(lFileSize) );
        
        // Create buffer that will contain the file data
        HBufC8* lFileData = HBufC8::NewLC(lFileSize);
        TPtr8 lFileDataPtr(lFileData->Des());
        
        // Read from the file
        User::LeaveIfError( lSvgFile.Read(lFileDataPtr) );
        
        // Create buffer to store the URI of the file
        HBufC* lUriBuf = HBufC::NewLC( KMaxUrlLength );
        TPtr lUriPtr(lUriBuf->Des());
        
        // Get the URI from data structure
        aDownload.GetStringAttribute( EDlAttrReqUrl, lUriPtr ); 
        
        // Call the AssignImageData function
        // Mapping is maintained between URI <-> FileData
        iAppDialog->AssignImageData(lUriPtr , lFileData );
        
        CleanupStack::PopAndDestroy( lUriBuf );
        CleanupStack::Pop( lFileData );
        CleanupStack::PopAndDestroy(&lSvgFile); // lSvgFile.Close()
        }
    }

void CSVGTAppObserverUtil::DoAssignLocalFileDataL( const TDesC& aOriginalUri, 
                                                   const TDesC& aNewUri ) const
    {
    TInt lFileSize = 0;
    TBuf<KMaxPath>lFileName;
    lFileName.Copy(aNewUri);
    RFile lSvgFile;
    // Attempt to open the file in read mode
    User::LeaveIfError( lSvgFile.Open(iEikEnv->FsSession(),lFileName,EFileRead ) );
    
    // Save on cleanup stack
    CleanupClosePushL( lSvgFile );
    
    // Get the size of the data to create read buffer
    User::LeaveIfError( lSvgFile.Size(lFileSize) );
    // Create buffer that will contain the file data
    HBufC8* lFileData = HBufC8::NewLC(lFileSize);
    TPtr8 lFileDataPtr(lFileData->Des());
    // Read from the file
    User::LeaveIfError( lSvgFile.Read(lFileDataPtr) );
    
    // Call the AssignImageData function
    // Mapping is maintained between URI <-> FileData
    iAppDialog->AssignImageData(aOriginalUri , lFileData );
    
    CleanupStack::Pop( lFileData );
    CleanupStack::PopAndDestroy(&lSvgFile); // lSvgFile.Close()
    }

EXPORT_C void CSVGTAppObserverUtil::AssignEmbededDataL( const TDesC& aUri )
    {
    HBufC8* decoded = DoGetProcessedEmbededDataL( aUri );
    if ( decoded )
        {
        iAppDialog->AssignImageData( aUri, decoded );
        }
    }
    
HBufC8* CSVGTAppObserverUtil::DoGetProcessedEmbededDataL( const TDesC& aXlinkHrefValue ) const
    {
    HBufC8* retPtr = NULL;
    // find positions for ';' and ',' to determine encoding, mimetype
    TInt startIndex = aXlinkHrefValue.Locate( ';' );
    TInt endIndex = aXlinkHrefValue.Locate( ',' );

    // mimetype is after 'data:' : xlink:href="data:image/png;base64,
    // ignore mimetype extraction, decode will detect mimetype from decoded data.

    if (    startIndex != KErrNotFound && 
            endIndex != KErrNotFound &&
            startIndex < endIndex )
        {
        // extract encoding type
        TPtrC encoding( aXlinkHrefValue.Left( endIndex ).Right( endIndex - startIndex - 1 ) );
        // handle Base64 encoding
        _LIT( KEncodingBase64, "base64" );
        if ( encoding == KEncodingBase64 )
            {
            // find index of first character after white-space
            TInt index = endIndex + 1;
            while ( index < aXlinkHrefValue.Length() && TChar( aXlinkHrefValue[index] ).IsSpace() )
            index++;

            // must be 8-bit
            TInt length = aXlinkHrefValue.Length() - index;
            HBufC8* encoded = HBufC8::NewLC( length );
            encoded->Des().Copy( aXlinkHrefValue.Right( length ) );

            HBufC8* decoded = HBufC8::NewLC( length );
            TPtr8 decodedDes = decoded->Des();

            // decode
            TImCodecB64 encodingBase64;
            TInt decodeError = encodingBase64.Decode( *encoded, decodedDes );

            // Cleanup
            CleanupStack::Pop( decoded ); // encoded, decoded
            CleanupStack::PopAndDestroy( encoded ); 
            //delete encoded;

            // Check for decoding error
            if ( decodeError != KErrNone )
                {
                delete decoded;
                }
            else
                {
                retPtr = decoded;
                }
            }
        }
    return retPtr;
    }
    TBool CSVGTAppObserverUtil::ExitWhenOrientationChange()
    {
    	return EFalse;
    }

//  End of File