/*
* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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:
*
*/
// INCLUDES
#include "WmlControl.h"
#include <multipartparser.h>
#include "MVCView.h"
#include "MVCShell.h"
#include "WmlInterface.h"
#include "GDIDeviceContext.h"
#include "HistoryController.h"
#include "HistoryInterface.h"
#include "WmlDispatcher.h"
#include "StringUtils.h"
#include "nwx_string.h"
#include "nwx_mem.h"
// CONSTANTS
// MACROS
// DATA TYPES
// FUNCTION PROTOTYPES
// -----------------------------------------------------------------------------
// CWmlControl::ConstructL
// Private Class Method
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
void CWmlControl::ConstructL( CBrCtl* aBrCtl, TRect& aRect, MWmlInterface* aWKWmlInterface)
{
// Initialize messaging system
if (NW_Msg_Initialize( "PSQ1" ) != KBrsrSuccess){
User::Leave(KErrNoMemory);
}
iWmlContentInterface = NULL;
iWKWmlInterface = aWKWmlInterface;
iWmlView = CView::NewL(aBrCtl, aBrCtl, aRect, this);
iWmlShell = CShell::NewL(iWmlView, aBrCtl, aWKWmlInterface, this );
iBrCtl = aBrCtl ;
}
// -----------------------------------------------------------------------------
// CWmlControl::PageInfoLC
// Returns to the Browser Control info about the page. The info is returned on the Cleanup Stack.
// -----------------------------------------------------------------------------
//
HBufC* CWmlControl::PageInfoLC(TBrCtlDefs::TBrCtlPageInfo aBrCtlPageInfo)
{
HBufC* pageInfo = NULL;
TBool isUrl = EFalse;
if ( iHistoryController && iHistoryController->historyView() )
{
return iHistoryController->pageInfoLC( aBrCtlPageInfo );
}
else
switch (aBrCtlPageInfo)
{
case TBrCtlDefs::EPageInfoTitle:
pageInfo = iWmlShell->GetCurrentTitleInHBufCL(isUrl);
if (isUrl) // should modify the shell to not lookup the URL if no title available
{
delete pageInfo;
pageInfo = NULL;
}
break;
case TBrCtlDefs::EPageInfoUrl:
pageInfo = iWmlShell->GetCurrentUrlInHBufCL();
if ( !pageInfo->Compare(_L(" ")) )
{
delete pageInfo;
pageInfo = NULL;
}
break;
case TBrCtlDefs::EPageInfoContent:
pageInfo = iWmlShell->GetPageAsTextL();
break;
case TBrCtlDefs::EPageInfoSavedPage:
pageInfo = WMLGenerateSavedPageL();
break;
}
CleanupStack::PushL(pageInfo);
return pageInfo;
}
/*
* StartLoadingResource
* Public Class Method
* Purpose
* @since 3.1
* @param const TDesC& aURL
* @return CWmlResourceLoadListener*
*/
CWmlResourceLoadListener* CWmlControl::LoadResourceL( const TDesC& aUrl, void* aLoadContext,
void* aPartialLoadCallback, TUint16 aTransId)
{
if( iWmlContentInterface && (aTransId - iWmlContentInterface->getTransId()) > 1 ){
m_contentArray.ResetAndDestroy();
iWmlContentInterface = NULL;
}
CWmlContentInterface* contentInterface = CWmlContentInterface::NewL();
contentInterface->setUrl( aUrl );
contentInterface->setTransId( aTransId );
contentInterface->setLoadContext( aLoadContext );
contentInterface->setPartialCallBack( aPartialLoadCallback );
m_contentArray.AppendL( contentInterface );
HBufC8* url8 = HBufC8::New(aUrl.Length() + 1);
if(url8) {
TPtr8 url8Ptr(url8->Des());
url8Ptr.Copy(aUrl);
url8Ptr.ZeroTerminate();
iWKWmlInterface->loadResource( url8Ptr, iWmlContentInterface);
delete url8;
}
return NULL;
}
// -----------------------------------------------------------------------------
//
// C++ default constructor.
//
// -----------------------------------------------------------------------------
CWmlControl::CWmlControl()
{
}
// -----------------------------------------------------------------------------
//
// C++ destructor.
//
// -----------------------------------------------------------------------------
CWmlControl::~CWmlControl()
{
iWmlContentInterface = NULL;
delete iWmlShell;
delete iWmlView;
m_contentArray.ResetAndDestroy();
m_contentArray.Close();
}
// -----------------------------------------------------------------------------
// CBrCtl::SetBrowserSettingL
// From CBrCtlInterface
// Update a Browser Control setting
// -----------------------------------------------------------------------------
//
void CWmlControl::SetBrowserSettingL(TUint aSetting, TUint aValue)
{
iWmlView->SetBrowserSettingL( aSetting, aValue);
}
// -----------------------------------------------------------------------------
// CWebKitControl::GenerateSavedPageL
// Public Class Method
// Create a formatted descriptor containing all markup and
// resources for the active page
// -----------------------------------------------------------------------------
//
HBufC* CWmlControl::WMLGenerateSavedPageL()
{
RPointerArray<CBodyPart> partsArr;
//Creat the data here
CBodyPart* newPart = NULL;
HBufC8* hdrData( NULL );
TInt popDestCount( 0 );
//The following must be same as that of KContentTypeTextWml8
//in MultipartContentHandler.cpp otherwise Multipart parser
//will not process this corretcly.
_LIT8( KWmlContentType, "text/vnd.wap.wml" );
HBufC* wmlCurrentUrl = iWmlShell->GetCurrentUrlInHBufCL();
User::LeaveIfNull( wmlCurrentUrl );
CleanupStack::PushL( wmlCurrentUrl );
HBufC8* pageWMLMarkup = iWmlShell->GetPageAsWMLMarkUp();
User::LeaveIfNull( pageWMLMarkup );
CleanupStack::PushL( pageWMLMarkup );
TPtrC8 charsetPtr(0,0);
const TUint8* charset = iWmlShell->GetCharsetFromResponse();
if (charset != NULL)
{
charsetPtr.Set(charset,
NW_Asc_strlen(reinterpret_cast<const char*>(charset)));
}
hdrData = HBufC8::NewLC( KPartHeadersData().Length() +
wmlCurrentUrl->Length() + 1 +
charsetPtr.Length() +
KWmlContentType().Length() );
++popDestCount; //For 1st hdrData
HBufC8* tempWMLUrl = HBufC8::NewLC(wmlCurrentUrl->Des().Length() + 1);
tempWMLUrl->Des().Copy(*wmlCurrentUrl);
tempWMLUrl->Des().ZeroTerminate();
HBufC8* contentType = HBufC8::NewLC(KWmlContentType().Length());
contentType->Des().Copy(KWmlContentType);
hdrData->Des().Format( KPartHeadersData, tempWMLUrl, contentType, &charsetPtr);
//Do some clean up for first part
CleanupStack::PopAndDestroy( contentType);
CleanupStack::PopAndDestroy( tempWMLUrl);
// prepare new part and append to array
newPart = CBodyPart::NewL();
newPart->SetHeaders( *hdrData );
newPart->SetBody( pageWMLMarkup->Des() );
partsArr.Append( newPart );
// create CBodyPart objects from TWebCoreImageCarrier objects
CArrayFixFlat<TBrCtlImageCarrier>* imgArr =
iWmlView->GetPageImagesL();
User::LeaveIfNull( imgArr );
CleanupStack::PushL( imgArr );
++popDestCount; //imgArr
TInt numImages = imgArr->Count();
for( TInt k=0; k<numImages; k++ )
{
// prepare headers for part
TInt imageUrlLen = imgArr->At(k).Url().Length()+1; //One for NULL Termination
TInt imageContentTypeLen = imgArr->At(k).ContentType().Length()+1; //One for NULL Termination
hdrData = HBufC8::NewLC( KPartHeadersImg().Length() + imageUrlLen + imageContentTypeLen );
popDestCount++; //For 2nd hdrData
// convert url and content type to 8 bit descriptors
HBufC8* url8 = HBufC8::NewLC( imageUrlLen );
url8->Des().Copy( imgArr->At(k).Url() );
url8->Des().ZeroTerminate();
HBufC8* imgcontentType = HBufC8::NewLC(imageContentTypeLen);
imgcontentType->Des().Copy(imgArr->At(k).ContentType());
imgcontentType->Des().ZeroTerminate();
// combine header values with format
hdrData->Des().Format( KPartHeadersImg, url8, imgcontentType );
CleanupStack::PopAndDestroy( imgcontentType );
CleanupStack::PopAndDestroy( url8 );
// prepare new part and append to array
newPart = CBodyPart::NewL();
newPart->SetHeaders( *hdrData );
newPart->SetBody( imgArr->At(k).RawData() );
partsArr.Append( newPart );
}
// compose multipart/mixed document using MultipartParser
HBufC8* docBody8 = MultipartParser::ComposeL( partsArr, KSavePageBoundary(),
MultipartParser::EMultipartSubtypeMixed,
MultipartParser::EMultipartTopLevelHeaderContentType |
MultipartParser::EMultipartTopLevelHeaderContentLength |
MultipartParser::EMultipartTopLevelHeaderLastModified );
// cleanup descriptors
partsArr.ResetAndDestroy();
CleanupStack::PopAndDestroy( popDestCount );
CleanupStack::PopAndDestroy(pageWMLMarkup);
User::LeaveIfNull( docBody8 );
CleanupStack::PushL( docBody8 );
// convert multipart document to 16 bit descriptor
HBufC* docBody16 = HBufC::NewL( docBody8->Length() );
docBody16->Des().Copy( *docBody8 );
CleanupStack::PopAndDestroy( docBody8 );
CleanupStack::PushL(docBody16);
TInt contentLength = docBody16->Length();
TInt docLen = KSavePageDocTop().Length() + wmlCurrentUrl->Des().Length() +
KCrLf().Length() + contentLength;
HBufC* savedpage = HBufC::NewL( docLen );
savedpage->Des().Copy( wmlCurrentUrl->Des() );
savedpage->Des().Append( KCrLf );
savedpage->Des().Insert( 0, KSavePageDocTop );
savedpage->Des().Append( *docBody16 );
CleanupStack::PopAndDestroy( docBody16 );
CleanupStack::PopAndDestroy( wmlCurrentUrl);
return savedpage;
}
// -----------------------------------------------------------------------------
// CWmlControl::InputElementEditComplete( TBool aInputConfirmed )
//
// -----------------------------------------------------------------------------
//
void CWmlControl::InputElementEditComplete( TBool aInputConfirmed )
{
iWmlView->InputElementEditComplete( aInputConfirmed );
}//end CBrCtl::InputElementEditComplete()
// -----------------------------------------------------------------------------
// CWmlControl::coeControl()
//
// -----------------------------------------------------------------------------
//
CCoeControl* CWmlControl::coeControl()
{
return (CCoeControl*) iWmlView;
}
// -----------------------------------------------------------------------------
// CWmlControl::GainFocus()
//
// -----------------------------------------------------------------------------
void CWmlControl::GainFocus()
{
iWmlShell->GainFocus();
}
// -----------------------------------------------------------------------------
// CWmlControl::GainFocus()
//
// -----------------------------------------------------------------------------
CArrayFixFlat<TBrCtlImageCarrier>* CWmlControl::GetPageImagesL()
{
return ( iWmlView->GetPageImagesL() );
}
// -----------------------------------------------------------------------------
// CWmlControl::GetFocusedElementType()
//
// -----------------------------------------------------------------------------
TBrCtlDefs::TBrCtlElementType CWmlControl::GetFocusedElementType()
{
return ( iWmlView->GetFocusedElementType() );
}
// -----------------------------------------------------------------------------
// CWmlControl::LoseFocus()
//
// -----------------------------------------------------------------------------
void CWmlControl::LoseFocus()
{
iWmlShell->LoseFocus();
}
// -----------------------------------------------------------------------------
// CWmlControl::ProcessBack()
//
// -----------------------------------------------------------------------------
TInt CWmlControl::ProcessBack()
{
return ( iWmlShell->ProcessBack() );
}
// -----------------------------------------------------------------------------
// CWmlControl::HandleDo()
//
// -----------------------------------------------------------------------------
TInt CWmlControl::HandleDo( TUint32 aElemId )
{
// try to commit editing before HandleDo
InputElementEditComplete(ETrue);
return ( iWmlShell->HandleDo( aElemId ) );
}
// -----------------------------------------------------------------------------
// CWmlControl::HistoryStackPosition()
//
// -----------------------------------------------------------------------------
TWmlEngineDefs::THistoryStackPosition CWmlControl::HistoryStackPosition()
{
return ( iWmlShell->HistoryStackPosition() );
}
// -----------------------------------------------------------------------------
// CWmlControl::MakeVisible()
//
// -----------------------------------------------------------------------------
void CWmlControl::MakeVisible( TBool aVisible )
{
if (!aVisible)
{
// cancel editing if we go elsewhere
InputElementEditComplete(EFalse);
}
return ( iWmlView->MakeVisible(aVisible) );
}
// -----------------------------------------------------------------------------
// CWmlControl::SetFocus()
//
// -----------------------------------------------------------------------------
void CWmlControl::SetFocus(TBool aFocus, TDrawNow aDrawNow )
{
return ( iWmlView->SetFocus( aFocus, aDrawNow ) );
}
// -----------------------------------------------------------------------------
// CWmlControl::SetRect()
//
// -----------------------------------------------------------------------------
void CWmlControl::SetRect( const TRect &aRect )
{
return ( iWmlView->SetRect( aRect ) );
}
// -----------------------------------------------------------------------------
// CWmlControl::LoadImages()
//
// -----------------------------------------------------------------------------
void CWmlControl::LoadImages()
{
iWmlShell->ShowImagesL();
}
// -----------------------------------------------------------------------------
// CWmlControl::WmlViewRectangle()
//
// -----------------------------------------------------------------------------
TRect CWmlControl::WmlViewRectangle()
{
return TRect( iWmlView->Position(), iWmlView->Size() );
}
// -----------------------------------------------------------------------------
// CWmlControl::ScrollTo()
//
// -----------------------------------------------------------------------------
void CWmlControl::ScrollTo(TPoint aPoint)
{
iWmlView->ScrollTo(aPoint);
}
// -----------------------------------------------------------------------------
// CWmlControl::WMLPartialResponse()
//
// -----------------------------------------------------------------------------
TInt CWmlControl::WMLPartialResponse( CWmlContentInterface* aWmlContentInterface,
const TUint16* aUri,
TPtr8& aBody,
void* aHeaders,
TUint8* aContentTypeString,
TUint8* aContentLocationString,
TBool aNoStore,
TUint8* aBoundaryString,
TUint16* aLastModified,
TUint16 aCharset,
TUint8* aCharsetString,
TUint aHttpStatus,
TUint8 aMethod,
TUint16 aTransId,
TInt aChunkIndex,
void* aCertInfo,
TUint aContentLength,
TInt aErr,
void* aLoadContext,
void* aPartialCallback )
{
TBrowserStatusCode retVal = aWmlContentInterface->WMLPartialResponse(aUri,
aBody,
aHeaders,
aContentTypeString,
aContentLocationString,
aNoStore,
aBoundaryString,
aLastModified,
aCharset,
aCharsetString,
aHttpStatus,
aMethod,
aTransId,
aChunkIndex,
aCertInfo,
aContentLength,
aErr,
aLoadContext,
aPartialCallback);
return (TInt) retVal;
}
// -----------------------------------------------------------------------------
// CWmlControl::WmlLoadUrlL(..)
//
// -----------------------------------------------------------------------------
void CWmlControl::WmlLoadUrlL( const TDesC& aUrl )
{
return (iWmlShell->WmlShellLoadUrlL( aUrl, AppId() ) );
}
// -----------------------------------------------------------------------------
// CWmlControl::SetCertInfo( const TCertInfo* aCertInfo )
//
// -----------------------------------------------------------------------------
void CWmlControl::SetCertInfo( const TCertInfo* aCertInfo )
{
// set cert info
iCertInfo = aCertInfo;
}
void CWmlControl::WmlParameters( const char* data, TInt length, TDesC& contentType, TDesC& charsetType, TInt httpStatus, TInt chunkIndex, TDesC& url )
{
TUint8 method = 1;
TUint16 charset = 64;
TInt err = 0;
TInt contTypeLen = contentType.Length() + 1;
TUint8 *contType = new(ELeave)TUint8[contTypeLen];
TPtr8 contType8(contType, contTypeLen );
contType8.Copy( contentType );
contType8.ZeroTerminate();
TInt charSetLen = charsetType.Length() + 1;
TUint8 *charSet = new(ELeave)TUint8[charSetLen];
TPtr8 charSet8(charSet, charSetLen );
charSet8.Copy( charsetType );
charSet8.ZeroTerminate();
TPtr8 myFake (0, 0);
for (TInt i=0; i< m_contentArray.Count(); i++){
if((m_contentArray[i]->getUrl()->Des()).operator==(url) ){
iWmlContentInterface = m_contentArray[i];
}
}
if (iWmlContentInterface){
if (chunkIndex >= 0) {
TUint8 *body = new(ELeave)TUint8[length];
NW_Mem_memcpy(body, data, length);
TPtr8 bodyPtr((unsigned char*) body, length);
bodyPtr.SetLength(length);
WMLPartialResponse( iWmlContentInterface,
(const TUint16*)(iWmlContentInterface->getUrl()->Des()).Ptr(),
bodyPtr,
NULL,
(TUint8 *)contType8.Ptr(),
(TUint8 *)myFake.Ptr(),
EFalse,
NULL,
NULL,
charset,
(TUint8 *)charSet8.Ptr(),
httpStatus,
method,
iWmlContentInterface->getTransId(),
chunkIndex,
NULL,
length,
err,
iWmlContentInterface->getLoadContext(),
iWmlContentInterface->getPartialCallBack()
);
}
else {
TPtr8 myData8 ((unsigned char*)data, length);
WMLPartialResponse( iWmlContentInterface,
(const TUint16*)(iWmlContentInterface->getUrl()->Des()).Ptr(),
myData8,
NULL,
NULL,
NULL,
EFalse,
NULL,
NULL,
charset,
NULL,
httpStatus,
method,
iWmlContentInterface->getTransId(),
chunkIndex,
NULL,
length,
err,
iWmlContentInterface->getLoadContext(),
iWmlContentInterface->getPartialCallBack()
);
}
}
}
TSize CWmlControl::WMLDocumentSize()
{
TSize size(0, 0);
if (iWmlView) {
iWmlView->ContentSize(size);
}
return size;
}
TPoint CWmlControl::WMLDocumentPosition()
{
if (iWmlView) {
return TPoint(iWmlView->GetDeviceContext()->Origin()->x, iWmlView->GetDeviceContext()->Origin()->y);
}
return TPoint(0, 0);
}
/**
* Only following function is exported from the Dynamic DLL.
*/
EXPORT_C MWmlEngineInterface* NewWmlEngineL()
{
return new (ELeave) CWmlControl;
}
// End of File