/*
* Copyright (c) 2006 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: CCSXHHTMLContentParser class definition
*
*/
#include "CSXHHTMLContentParser.h"
#include "CSXHXMLParseHandler.h"
#include "CSXHHtmlTOC1.h"
#include "CSXHKywdTOC1.h"
#include "CSXHHtmlTOC2.h"
#include "CSXHHelpDataBase.h"
#include "csxhconstants.h"
#include "CSXHRuntimeIndexing.h"
#include <eikenv.h>
#include <utf.h>
#include <data_caging_path_literals.hrh>
#include <zipfile.h>
#include <bautils.h>
#include <SenXmlReader.h>
#include <f32file.h>
#include <pathinfo.h>
//Input Language variation changes
#include <PtiEngine.h>
const TInt KOffset = 2;
CCSXHHTMLContentParser* CCSXHHTMLContentParser::NewL(CCoeEnv* aCoeEnv)
{
CCSXHHTMLContentParser* self = CCSXHHTMLContentParser::NewLC(aCoeEnv);
CleanupStack::Pop(self);
return self;
}
CCSXHHTMLContentParser* CCSXHHTMLContentParser::NewLC(CCoeEnv* aCoeEnv)
{
CCSXHHTMLContentParser* self = new (ELeave) CCSXHHTMLContentParser(aCoeEnv);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CCSXHHTMLContentParser::ConstructL()
{
//RUNTIME
GetSupportedFeatureListL();
}
CCSXHHTMLContentParser::CCSXHHTMLContentParser(CCoeEnv* aCoeEnv) : iCoeEnv(aCoeEnv)
{
}
CCSXHHTMLContentParser::~CCSXHHTMLContentParser()
{
delete iXmlReader;
//No need to delete the entries here, it will be done by the database
iHtmlTOC1List.Close();
//Delete all contents from the array.
TInt count = iDuplicateHelpTopicList.Count();
CCSXHHtmlTOC1* toc1;
for(TInt i=0;i<count;++i )
{
toc1 = iDuplicateHelpTopicList[i];
delete toc1;
}
iDuplicateHelpTopicList.Reset();
iDuplicateHelpTopicList.Close();
// Closes the array and frees all memory allocated to the array.
// iSupportedFeatures.Close();
delete iSupportedInputLanguages;
delete iFeatureManager_FeatureIds;
delete iIndexing;
}
void CCSXHHTMLContentParser::GenerateTOC1ListL(CCSXHHelpDataBase* aDataBase)
{
RFs& FileSession = iCoeEnv->FsSession();
TDriveList DirList;
if(FileSession.DriveList(DirList) != KErrNone)
return;
CCSXHXMLParseHandler_MetaFile* XMLParser = CCSXHXMLParseHandler_MetaFile::NewL(iCoeEnv);
CleanupStack::PushL(XMLParser);
InitializeReaderL(XMLParser);
TBuf<KMaxFileName>* rootDir = new(ELeave) TBuf<KMaxFileName>;
CleanupStack::PushL(rootDir);//5
// begin runtime index XML generating
//
iIndexing = CCSXHRuntimeIndexing::NewL();
TInt driveListSize = DirList.Length();
TBool dirExists = iIndexing->IndexFileExists();
CDirScan* scanner=CDirScan::NewLC(FileSession);
#ifdef _DEBUG
RDebug::Print(_L("runtime indexing object successfully build"));
#endif
for(TInt dir(0); dir < driveListSize; dir++)
{
TInt error;
TDriveInfo info;
TChar driveLetter = '?';
error = FileSession.Drive(info, dir);
if ( ( error == KErrNone ) &&
(DirList[dir] && info.iType != EMediaNotPresent))
{
RFs::DriveToChar( dir, driveLetter );
TInt dirChanged = iIndexing->CheckDirChange( driveLetter );
rootDir->Delete( 0, rootDir->Length() );//Clear the previous contents
rootDir->Append( driveLetter );
if ( dirExists
&& ( dirChanged == KNoChange
|| dirChanged == KNoDirExist) )
{
// xml exist and no install/uninstall happened
// while Z needs special process once its index file exists
#ifdef _DEBUG
RDebug::Print(_L("Used to launch, scan drive number: %d"), dir);
#endif
if ( dirChanged == KNoChange )
{
// no modify helps, so just parse index.xml
//
HandleMasterMetaFileL( aDataBase, driveLetter, XMLParser );
}
else // KNoDirExist
{
// help content folder removed due to some reason (uninstall/crash?)
// delete index file in case it exist
#ifdef _DEBUG
RDebug::Print( _L("no resource folder, delete index.xml if exists") );
#endif
iIndexing->DeleteIndexFile( driveLetter );
}
}
else
{
// xml not exist or install/uninstall not happend
//
if( GetHTMLContentPathForDriveL( rootDir,iCoeEnv ) )
{
#ifdef _DEBUG
RDebug::Print( _L("No index, scan folder for parsing, drive letter: %d"), dir );
#endif
iIndexing->BeginIndexFile( driveLetter );
scanner->SetScanDataL(*rootDir
,KEntryAttDir|KEntryAttMatchExclusive,
ESortByName|EAscending, CDirScan::EScanDownTree);
ScanAndParseXMLfileToCreateTOC1ObjectL(FileSession,scanner,aDataBase,
dir,XMLParser);
iIndexing->FinishAndCloseIndexFileL();
}
}
}
}
CleanupStack::PopAndDestroy( scanner );
CleanupStack::PopAndDestroy(rootDir);
CleanupStack::PopAndDestroy(XMLParser);
ClearReader();
}
TBool CCSXHHTMLContentParser::GetHTMLContentPathForDriveL(TBuf<KMaxFileName>* aContentDrive,CCoeEnv *aCoeEnv)
{
// get the path to language level
// Input: aContentDrive == C or E or Z
// Output: aContentDrive == C:\\resource\\xhtml\\01\\ (or Z:\\resource\\xhtml\\31\\)
//
aContentDrive->Append(KXhtmlFolder);
TInt len = aContentDrive->Length();
RFs& FileSession = aCoeEnv->FsSession();
RArray<TLanguage> langs;
BaflUtils::GetDowngradePathL(FileSession,User::Language(),langs);
for(int i = 0; i < langs.Count(); ++i)
{
TLanguage lang = langs[i];
//TSW Error: UKAL-6YL72P
//Tool chain uses full symbian language id in
//the directory name, which is not detected by help application.
//
if(lang < 10)
{
aContentDrive->AppendNumFixedWidth(lang,EDecimal,2);
}
else
{
aContentDrive->AppendNum(lang);
}
aContentDrive->Append(KFwdSlash);
if(BaflUtils::PathExists(FileSession,*aContentDrive))
{
langs.Reset();
return ETrue;
}
else
{
aContentDrive->Delete((len-1),aContentDrive->Length()-len);
}
}
langs.Reset();
return EFalse;
}
TBool CCSXHHTMLContentParser::HandleMasterMetaFileL(CCSXHHelpDataBase* aDataBase,
TChar& aDrive, MSenContentHandlerClient *aPrevHandler)
{
RFs& FileSession = iCoeEnv->FsSession();
TBuf<KMaxFileName> masterFile;
iIndexing->GetPrivatePath( masterFile );
masterFile.Append( aDrive );
masterFile.Append( KFwdSlash );
iIndexing->AppendLocale( masterFile );
masterFile.Append( KMasterMetaFile );
if(BaflUtils::FileExists( FileSession,masterFile ) )
{
#ifdef _DEBUG
RDebug::Print(_L("index exist begin to parse! %c"), aDrive );
#endif
CCSXHXMLParseHandler_MasterMetaFile* masterMetaHandler =
CCSXHXMLParseHandler_MasterMetaFile::NewL(iCoeEnv);
masterMetaHandler->SetDataBasePtr(aDataBase);
masterMetaHandler->SetHtmlContentParserPtr(this);
CleanupStack::PushL(masterMetaHandler);
iXmlReader->SetContentHandler(*masterMetaHandler);
// ParseL is not in async
iXmlReader->ParseL(FileSession,masterFile);
iXmlReader->SetContentHandler(*aPrevHandler);
CleanupStack::PopAndDestroy(masterMetaHandler);
}
return ETrue;
}
void CCSXHHTMLContentParser::GenerateTOC2ListL(CCSXHGenericTOC1&
aGenericTOC1Object, RPointerArray<CCSXHHelpContentBase>* GenericTOC2List)
{
CCSXHXMLParseHandler_IndexFile* XMLParser = CCSXHXMLParseHandler_IndexFile::NewL(iCoeEnv);
CleanupStack::PushL(XMLParser);
InitializeReaderL(XMLParser);
XMLParser->SetArray(GenericTOC2List);
XMLParser->SetGenericTOC1Object(aGenericTOC1Object);
XMLParser->SetHtmlContentParserPtr(this);
RFs& FileSession = iCoeEnv->FsSession();
CCSXHHtmlTOC1* toc1 = STATIC_CAST(CCSXHHtmlTOC1*,&aGenericTOC1Object);
TBuf<KMaxFileName> lookupindexfile;
toc1->GetHelpFileL(lookupindexfile);
XMLParser->SetPath(lookupindexfile);
lookupindexfile.Append(KIndexFile);
if(BaflUtils::FileExists(FileSession,lookupindexfile))
iXmlReader->ParseL (FileSession,lookupindexfile);
TBuf<KMaxFileName>HelpContentName(toc1->GetName());
int toc1Count = iDuplicateHelpTopicList.Count();
for(int i=0;i < toc1Count;i++)
{
CCSXHHtmlTOC1* temptoc1 = iDuplicateHelpTopicList[i];
if(temptoc1->GetName().CompareF(HelpContentName) == 0)
{
TBuf<KMaxFileName> lookup;
temptoc1->GetHelpFileL(lookup);
XMLParser->SetPath(lookup);
lookup.Append(KIndexFile);
if(BaflUtils::FileExists(FileSession,lookup))
iXmlReader->ParseL (FileSession,lookup);
}
}
CleanupStack::PopAndDestroy(XMLParser);
ClearReader();
}
TAny* CCSXHHTMLContentParser::GetTopicContentL(CCSXHGenericTOC2* aTopic)
{
CCSXHHtmlTOC2* topic = STATIC_CAST(CCSXHHtmlTOC2*,aTopic);
TBuf<KMaxFileName> htmlFile;
topic->GetHtmlFileName(htmlFile);
return GetContentsFromFileL(htmlFile,iCoeEnv,iFeatureControl);
}
void CCSXHHTMLContentParser::ScanAndParseXMLfileToCreateTOC1ObjectL(RFs& FileSession,
CDirScan* scanner,
CCSXHHelpDataBase* aDataBase,
const TInt& aDrive,
CCSXHXMLParseHandler* XMLParser
)
{
CDir* entryList = NULL;
scanner->NextL(entryList);
if(!entryList)
return;
CleanupStack::PushL(entryList);
TInt entryCount = entryList->Count();
TLinearOrder<CCSXHHelpContentBase> anOrder(Orderer<CCSXHHelpContentBase>);
TBuf<KMaxFileName> lookup;
while(entryCount--)
{
TEntry entry=(*entryList)[entryCount];
//Clear the previous values
lookup.Delete(0,lookup.Length());
lookup.Append(scanner->FullPath());
lookup.Append(entry.iName);
lookup.Append(KFwdSlash);
lookup.Append(KMetaFile);
//Check whether a file exists
if(!BaflUtils::FileExists(FileSession,lookup))
continue;
TRAPD(parserResult,iXmlReader->ParseL (FileSession,lookup ));
if(parserResult == KErrNone)
{
if(CheckFeatureIDL(XMLParser->GetFeatureIds()))
{
if(!IsAppUIdPresentAlready(entry.iName))
{
CCSXHHtmlTOC1* CategoryObj = CCSXHHtmlTOC1::NewL(
XMLParser->GetApplicationName(),entry.iName,aDrive);
iIndexing->RuntimeGenerateIndexL( *CategoryObj, XMLParser->GetFeatureIds() );
if(CategoryObj && aDataBase->GetMainTopics()->InsertChild(CategoryObj,EFalse))
iHtmlTOC1List.Append(CategoryObj);//Keep a local copy*/
else
{
if(CategoryObj)
iDuplicateHelpTopicList.Append(CategoryObj);
}
}
}
}
}
CleanupStack::PopAndDestroy(entryList);
}
void CCSXHHTMLContentParser::InsertHTMLToc1L(
const TDesC &appUidName,const TDesC &appName,
const TInt& aDrive , CCSXHHelpDataBase* aDataBase, const TDesC &FeatureIds)
{
if(CheckFeatureIDL(FeatureIds))
{
if(!IsAppUIdPresentAlready(appUidName))
{
CCSXHHtmlTOC1* CategoryObj = CCSXHHtmlTOC1::NewL(appName,appUidName,aDrive);
if(CategoryObj && aDataBase->GetMainTopics()->InsertChild(CategoryObj,EFalse))
iHtmlTOC1List.Append(CategoryObj);//Keep a local copy*/
else
{
if(CategoryObj)
iDuplicateHelpTopicList.Append(CategoryObj);
}
}
}
}
HBufC8* CCSXHHTMLContentParser::GetContentsFromFileL(const TDesC& htmlFile,CCoeEnv* aCoeEnv,
RFeatureControl& aFeatureControl)
{
RFs& fileSession = aCoeEnv->FsSession();
TInt SlashPosition = htmlFile.LocateReverse('\\');
TBuf<KMaxFileName>* CompressedFile = new (ELeave) TBuf<KMaxFileName>;
CleanupStack::PushL(CompressedFile); //1
CompressedFile->Copy(htmlFile.Mid(0,SlashPosition+1));
CompressedFile->Append(KContentZipFile);
HBufC8* CssContent = CreateBufferForCSSContentL(aFeatureControl);
if(!BaflUtils::FileExists(fileSession,*CompressedFile))
{
CleanupStack::PopAndDestroy(CompressedFile);
HBufC8* buffer = GetContentsFromHTMLFileL(htmlFile,aCoeEnv);
return MergeCssAndHTMLContentL(buffer,CssContent);
}
// Create an instance of CZipFile.
CZipFile* zipFile = CZipFile::NewL(fileSession, *CompressedFile);
CleanupStack::PushL(zipFile); //2
// Iterate and get the file name
CZipFileMemberIterator* members = zipFile->GetMembersL();
CleanupStack::PushL(members);//3
CZipFileMember* member = members->NextL(); // Get the first file in zip
TInt nCount=0;
const TBuf<KMaxFileName>*Fname;
TBuf<KMaxFileName> *HtmlFileName = new (ELeave) TBuf<KMaxFileName>;
CleanupStack::PushL(HtmlFileName); //4
HtmlFileName->Copy(htmlFile.Mid(SlashPosition+1));
for(nCount=0;member!=NULL;nCount++)
{
Fname = member->Name();
if(Fname->Compare(*HtmlFileName)==0 )
{
break;
}
delete member;
member = members->NextL();
}
if(NULL == member)
{
CleanupStack::PopAndDestroy(HtmlFileName);
CleanupStack::PopAndDestroy(members);
CleanupStack::PopAndDestroy(zipFile);
CleanupStack::PopAndDestroy(CompressedFile);
HBufC8* buffer = GetContentsFromHTMLFileL(htmlFile,aCoeEnv);
return MergeCssAndHTMLContentL(buffer,CssContent);
}
CleanupStack::PushL(member);//5
RZipFileMemberReaderStream* stream;
zipFile->GetInputStreamL(member, stream);
CleanupStack::PushL(stream);//6
// Extracts aFileName to a buffer.
// If the file is quite huge, then read the file in streaming mode.
// For example, use 4KB buffer and read it in an active object.
HBufC8* buffer = HBufC8::NewLC(member->UncompressedSize());//5
TPtr8 bufferPtr(buffer->Des());
User::LeaveIfError(stream->Read(bufferPtr, member->UncompressedSize()));
// Release all the resources.
CleanupStack::Pop(buffer);
CleanupStack::PopAndDestroy(stream);
CleanupStack::PopAndDestroy(member);
CleanupStack::PopAndDestroy(HtmlFileName);
CleanupStack::PopAndDestroy(members);
CleanupStack::PopAndDestroy(zipFile);
CleanupStack::PopAndDestroy(CompressedFile);
return MergeCssAndHTMLContentL(buffer,CssContent);
}
TBool CCSXHHTMLContentParser::HandleMasterKeywordFileL(CCSXHHelpDataBase* aDataBase)
{
RFs& FileSession = iCoeEnv->FsSession();
CCSXHXMLParseHandler_MasterKywd* XMLParser_MasterKywd = CCSXHXMLParseHandler_MasterKywd::NewL(iCoeEnv);
CleanupStack::PushL(XMLParser_MasterKywd);
InitializeReaderL(XMLParser_MasterKywd);
XMLParser_MasterKywd->SetHtmlContentParserPtr(this);
XMLParser_MasterKywd->SetDataBasePtr(aDataBase);
TBool bMasterKeywordFilePresent = EFalse;
//Check for the availability of Master Keyword file
TBuf<KMaxFileName>* Master_kywdPath = new(ELeave) TBuf<KMaxFileName>;
CleanupStack::PushL(Master_kywdPath);//5
Master_kywdPath->Append(PathInfo::RomRootPath().Left(1));
GetHTMLContentPathForDriveL(Master_kywdPath,iCoeEnv);
Master_kywdPath->Append(KMasterKywdFile);
if(BaflUtils::FileExists(FileSession,*Master_kywdPath))
{
TRAP_IGNORE(iXmlReader->ParseL(FileSession,*Master_kywdPath ));
bMasterKeywordFilePresent = ETrue;
}
//KMasterKywdFile;
CleanupStack::PopAndDestroy(Master_kywdPath);
CleanupStack::PopAndDestroy(XMLParser_MasterKywd);
ClearReader();
return bMasterKeywordFilePresent;
}
void CCSXHHTMLContentParser::GenerateKywdTOC1ListL(CCSXHHelpDataBase* aDataBase)
{
if(!iHtmlTOC1List.Count())
return;
TBool bMasterKeywordFilePresent = HandleMasterKeywordFileL(aDataBase);
CCSXHXMLParseHandler_Kywd* XMLParser = CCSXHXMLParseHandler_Kywd::NewL(iCoeEnv);
CleanupStack::PushL(XMLParser);
InitializeReaderL(XMLParser);
XMLParser->SetDataBasePtr(aDataBase);
XMLParser->SetIsTOC2(EFalse);
XMLParser->SetHtmlContentParserPtr(this);
//Parse keyword.xml file from Main Array list
ParseKeywdFileAndCreatekywdTOC1ObjectsL(iHtmlTOC1List,XMLParser,bMasterKeywordFilePresent);
//Parse keyword.xml file from duplicate Array list
ParseKeywdFileAndCreatekywdTOC1ObjectsL(iDuplicateHelpTopicList,XMLParser,bMasterKeywordFilePresent);
CleanupStack::PopAndDestroy(XMLParser);
ClearReader();
}
void CCSXHHTMLContentParser::GenerateTOC2ListForKeywordSearchL
(CCSXHHelpDataBase* aDataBase,CCSXHKywdTOC1* aKywdTOC1Object)
{
RPointerArray<CCSXHHtmlTOC1>* TOC1HtmlList = aKywdTOC1Object->GetHtmlTOC1List();
if(!TOC1HtmlList)
return;
CCSXHXMLParseHandler_Kywd* XMLParser = CCSXHXMLParseHandler_Kywd::NewL(iCoeEnv);
CleanupStack::PushL(XMLParser);
InitializeReaderL(XMLParser);
int toc1Count = TOC1HtmlList->Count();
CCSXHHtmlTOC1* toc1;
RFs& FileSession = iCoeEnv->FsSession();
XMLParser->SetDataBasePtr(aDataBase);
XMLParser->SetIsTOC2(ETrue);
XMLParser->SetHtmlContentParserPtr(this);
TBuf<KMaxFileName>* lookup = new(ELeave)TBuf<KMaxFileName>;
CleanupStack::PushL(lookup);//3
XMLParser->SetTOC1Title(aKywdTOC1Object->GetName());
for(int i = 0; i < toc1Count ; ++i )
{
toc1 = (*TOC1HtmlList)[i];
//Get Corresponding toc1 from Main array and set toc1 object
XMLParser->SetCurrentHtmlToc1(GetCorrespondingTOC1FromMainArray(toc1->GetName()));
//Clear the previous values
lookup->Delete(0,lookup->Length());
toc1->GetHelpFileL(*lookup);
XMLParser->SetPath(*lookup);
lookup->Append(KKeywordsFile);
TRAP_IGNORE(iXmlReader->ParseL (FileSession,*lookup ));
aDataBase->IncrementKeywordSearchCount();
}
CleanupStack::PopAndDestroy(lookup);
CleanupStack::PopAndDestroy(XMLParser);
ClearReader();
}
CCSXHHelpContentBase* CCSXHHTMLContentParser::GetContextTopic
(const TUid& aUid, const TDesC& contextName)
{
int toc1Count = iHtmlTOC1List.Count();
CCSXHHtmlTOC1* toc1,*temptoc1;
for(int i = 0; i < toc1Count; ++i)
{
toc1 = iHtmlTOC1List[i];
if(aUid == toc1->GetAppUid())
{
return toc1->GetContextTopic(contextName);
}
}
toc1Count = iDuplicateHelpTopicList.Count();
for(int i = 0; i < toc1Count; ++i)
{
toc1 = iDuplicateHelpTopicList[i];
if(aUid == toc1->GetAppUid())
{
temptoc1 = GetCorrespondingTOC1FromMainArray(toc1->GetName());
return temptoc1->GetContextTopic(contextName);
}
}
return NULL;
}
CCSXHHelpContentBase* CCSXHHTMLContentParser::GetHtmlTopicForUrlL(const TDesC& aUrl)
{
CCSXHHelpContentBase* tocobj = GetObjectBasedonUrlL(iHtmlTOC1List,aUrl,ETrue);
if(NULL == tocobj)
tocobj = GetObjectBasedonUrlL(iDuplicateHelpTopicList,aUrl,EFalse);
return tocobj;
}
CCSXHHelpContentBase* CCSXHHTMLContentParser::GetObjectBasedonUrlL(RPointerArray<CCSXHHtmlTOC1>& aTOC1ObjectsArray,
const TDesC& aUrl, TBool aMainArrayList)
{
/*For URLs of form
file:://<Drive Name>:/system/xhtml/<Lang ID>/<App UID>/Html name
We can have help topics for other cases, help topic objects not possible
*/
TBuf<KMaxFileName> aFileUrl;
int toc1Count = aTOC1ObjectsArray.Count();
CCSXHHtmlTOC1* toc1,*temptoc1;
for(int j = 0; j < toc1Count; ++j)
{
toc1 = aTOC1ObjectsArray[j];
TBuf<KMaxFileName> htmlFile;
toc1->GetHelpFileL(htmlFile);
//Convert fwd slashes to back slashes
TInt i = htmlFile.Find(KFwdSlash) ;
while (KErrNotFound != i)
{
htmlFile.Replace(i,1,KBackSlash);
i = htmlFile.Find(KFwdSlash) ;
}
i = aUrl.FindC(htmlFile);
if(i != KErrNotFound)
{
TFileName fileName;
i = aUrl.LocateReverseF('/');
fileName = aUrl.Mid(i + 1);
if(aMainArrayList)
temptoc1 = toc1;
else
temptoc1 = GetCorrespondingTOC1FromMainArray(toc1->GetName());
return temptoc1->GetHtmlTopicForFile(fileName);
}
}
return NULL;
}
void CCSXHHTMLContentParser::GetHtmlFileL(CCoeEnv* coeEnv,const short& aDir,
const TAppUid& aUid,TBuf<KMaxFileName>& aFileName)
{
aFileName.Copy(KEmptyString);
RFs& FileSession = coeEnv->FsSession();
TDriveList DirList;
if( (FileSession.DriveList(DirList)<KErrNone) ||
(aDir >= DirList.Length()))
return;
TChar driveLetter = '?';
TDriveInfo info;
TInt error = FileSession.Drive(info, aDir);
if ((error == KErrNone) &&
(DirList[aDir] && info.iType != EMediaNotPresent))
{
RFs::DriveToChar(aDir, driveLetter);
aFileName.Append(driveLetter);
GetHTMLContentPathForDriveL(&aFileName,coeEnv);
aUid.AppendUid(aFileName);
aFileName.Append(KFwdSlash);
}
}
void CCSXHHTMLContentParser::InitializeReaderL(CCSXHXMLParseHandler* aXMLParser)
{
if(iXmlReader == NULL )
{
iXmlReader = CSenXmlReader::NewL();
iXmlReader->SetContentHandler(*aXMLParser);
}
}
void CCSXHHTMLContentParser::ClearReader()
{
delete iXmlReader;
iXmlReader = NULL;
}
TBool CCSXHHTMLContentParser::IsUidCategoryPresent(const TUid& aUid)
{
int toc1Count = iHtmlTOC1List.Count();
CCSXHHtmlTOC1* toc1;
for(int i = 0; i < toc1Count; ++i)
{
toc1 = iHtmlTOC1List[i];
if(aUid == toc1->GetAppUid())
return ETrue;
}
toc1Count = iDuplicateHelpTopicList.Count();
for(int i = 0; i < toc1Count; ++i)
{
toc1 = iDuplicateHelpTopicList[i];
if(aUid == toc1->GetAppUid())
return ETrue;
}
return EFalse;
}
TBool CCSXHHTMLContentParser::GetHTMLToc1(const TDesC& aUid,CCSXHXMLParseHandler* aParser)
{
TUint AppId;
if(!aUid.Length())
return EFalse;
TLex FolderUid(aUid.Mid(KOffset));
FolderUid.Val(AppId,EHex);
TUid ApplicationUid = TUid::Uid((TInt)AppId);
int toc1Count = iHtmlTOC1List.Count();
CCSXHHtmlTOC1* toc1;
for(int i = 0; i < toc1Count; ++i)
{
toc1 = iHtmlTOC1List[i];
if(ApplicationUid == toc1->GetAppUid())
{
STATIC_CAST(CCSXHXMLParseHandler_MasterKywd*,aParser)->SetCurrentHtmlToc1(toc1);
return ETrue;
}
}
toc1Count = iDuplicateHelpTopicList.Count();
for(int i = 0; i < toc1Count; ++i)
{
toc1 = iDuplicateHelpTopicList[i];
if(ApplicationUid == toc1->GetAppUid())
{
STATIC_CAST(CCSXHXMLParseHandler_MasterKywd*,aParser)->SetCurrentHtmlToc1(toc1);
return ETrue;
}
}
return EFalse;
}
//To get Corresponding toc1 from main array.
CCSXHHtmlTOC1* CCSXHHTMLContentParser::GetCorrespondingTOC1FromMainArray(const TDesC& aApplicationName)
{
TInt toc1Count = iHtmlTOC1List.Count();
CCSXHHtmlTOC1* toc1;
for(int i=0;i<toc1Count;++i)
{
toc1 = iHtmlTOC1List[i];
if(toc1->GetName().CompareF(aApplicationName) == 0)
return toc1;
}
return NULL;
}
//Check UId is already present in the list.
TBool CCSXHHTMLContentParser::IsAppUIdPresentAlready(const TDesC& aUid)
{
TBool result = EFalse;
TInt toc1Count = iHtmlTOC1List.Count();
CCSXHHtmlTOC1* toc1;
TUint AppId;
TLex FolderUid(aUid.Mid(KOffset));
FolderUid.Val(AppId,EHex);
TUid ApplicationUid = TUid::Uid((TInt)AppId);
for(int i=0;i<toc1Count;++i)
{
toc1 = iHtmlTOC1List[i];
if(ApplicationUid == toc1->GetAppUid())
{
result = ETrue;
break;
}
}
toc1Count = iDuplicateHelpTopicList.Count();
for(int i=0;i<toc1Count;++i)
{
toc1 = iDuplicateHelpTopicList[i];
if(ApplicationUid == toc1->GetAppUid())
{
result = ETrue;
break;
}
}
return result;
}
void CCSXHHTMLContentParser::ParseKeywdFileAndCreatekywdTOC1ObjectsL(
RPointerArray<CCSXHHtmlTOC1>& aTOC1ObjectsArray,
CCSXHXMLParseHandler_Kywd* XMLParser, TBool bMasterKeywordFilePresent)
{
int toc1Count = aTOC1ObjectsArray.Count();
CCSXHHtmlTOC1* toc1;
TBuf<KMaxFileName>* lookup = new(ELeave)TBuf<KMaxFileName>;
CleanupStack::PushL(lookup);//1
RFs& FileSession = iCoeEnv->FsSession();
for(int i = 0; i < toc1Count; ++i)
{
toc1 = aTOC1ObjectsArray[i];
if(bMasterKeywordFilePresent && toc1->IsROMDrive())
continue;
//Clear the previous values
lookup->Delete(0,lookup->Length());
toc1->GetHelpFileL(*lookup);
lookup->Append(KKeywordsFile);
//Check whether a file exists
if(!BaflUtils::FileExists(FileSession,*lookup))
continue;
XMLParser->SetCurrentHtmlToc1(toc1);
TRAP_IGNORE(iXmlReader->ParseL(FileSession,*lookup ));
}
CleanupStack::PopAndDestroy(lookup);
}
//RUNTIME
void CCSXHHTMLContentParser::GetSupportedFeatureListL()
{
RFeatureUidArray SupportedFeatures;
TInt err = iFeatureControl.Connect();
if ( err == KErrNone )
{
// ListSupportedFeatures() returns one of the Symbian error codes.
err = iFeatureControl.ListSupportedFeatures( SupportedFeatures );
// Remember to call CloseL after using RFeatureControl.
// It disconnects the Feature Manager server.
iFeatureControl.Close();
}
//As per new req. add true, flase to id and create an array.
iFeatureManager_FeatureIds = new (ELeave) CDesCArrayFlat(2);
TBuf<25>CurrFId;
for(TInt i=0;i<SupportedFeatures.Count();i++)
{
CurrFId.Copy(KEmptyString);
CurrFId.AppendNum(SupportedFeatures[i].iUid);
iFeatureManager_FeatureIds->AppendL(CurrFId);
CurrFId.Copy(KTrue_StringtoAppend);
CurrFId.AppendNum(SupportedFeatures[i].iUid);
iFeatureManager_FeatureIds->AppendL(CurrFId);
CurrFId.Copy(KFalse_StringtoAppend);
CurrFId.AppendNum(SupportedFeatures[i].iUid);
iFeatureManager_FeatureIds->AppendL(CurrFId);
}
//Input Language variation changes
//-----------------------------------------
//Create an array with supported input language
CPtiEngine* ptiEngine = CPtiEngine::NewL();
CleanupStack::PushL( ptiEngine );
CArrayFix<TInt>* languageCodeArray = new(ELeave)CArrayFixFlat<TInt>(2);
ptiEngine->GetAvailableLanguagesL( languageCodeArray );
TInt nCount = languageCodeArray->Count();
iSupportedInputLanguages = new (ELeave) CDesCArrayFlat(2);
//Codescanner gives error, if member variables are pushed.
//CleanupStack::PushL( iSupportedInputLanguages );
for(TInt i=0; i<nCount;i++)
{
TInt languageCode = languageCodeArray->At(i);
TBuf<25>Currlang(_L("LANGUAGE_"));
if(languageCode < 10)
Currlang.AppendNumFixedWidth(languageCode,EDecimal,2);
else
Currlang.AppendNum(languageCode);
iSupportedInputLanguages->AppendL(Currlang);
}
//CleanupStack::Pop(iSupportedInputLanguages);
CleanupStack::PopAndDestroy( ptiEngine );
delete languageCodeArray;
//-----------------------------------------
SupportedFeatures.Close();
}
//RUNTIME
TBool CCSXHHTMLContentParser::CheckFeatureIDL(const TDesC& aFeatureIds)
{
if(/*KHexPrefixLength == aFeatureIds.Length() &&*/
KErrNotFound != aFeatureIds.Find(KDefaultFeatureIdStringTemp))
{
return ETrue;
}
HBufC* Ids = HBufC::NewLC(aFeatureIds.Length());
TPtr CurrentFeatureIds = Ids->Des();
CurrentFeatureIds.Copy(aFeatureIds);
CleanupStack::Pop(Ids);
CDesCArray* FeatureIdList = new (ELeave) CDesCArrayFlat(2); ;
TInt EndPos = CurrentFeatureIds.Locate(' ');
CleanupStack::PushL(FeatureIdList);
while (KErrNotFound != EndPos)
{
FeatureIdList->AppendL(CurrentFeatureIds.Mid(0,EndPos));// FId_Val);
CurrentFeatureIds = CurrentFeatureIds.Mid(EndPos+1);
EndPos = CurrentFeatureIds.Locate(' ') ;
}
if(KErrNotFound == EndPos && 0!= CurrentFeatureIds.Length())
{
FeatureIdList->AppendL(CurrentFeatureIds);
}
CleanupStack::Pop(FeatureIdList);
TInt position;
if(KErrNone == FeatureIdList->Find(KDefaultFeatureIdString,position) ||
KErrNone == FeatureIdList->Find(KDefaultFeatureIdStringTemp,position) )
{
delete FeatureIdList;
delete Ids;
return ETrue;
}
TInt nCount = FeatureIdList->MdcaCount();
//FeatureManager list contains all enabled featureIds, appended with true, and false.
//New Req. text associated with true_featureId, should be displayed, if Id is enabled.
//else, if featureId is disabled, text associated with false_featureId should be displayed.
// 1. if featureId string contains "false" and it is not in the list, return ETrue.
// 2. if featureId string does not contain "false" and it is present in the list, return ETrue.
// 3. if featureId is part of input language, return ETrue.
for(TInt j=0;j < nCount;j++)
{
if(
(KErrNotFound != FeatureIdList->MdcaPoint(j).Find(KFalseString) &&
KErrNone != iFeatureManager_FeatureIds->Find(FeatureIdList->MdcaPoint(j),position))||
(KErrNotFound == FeatureIdList->MdcaPoint(j).Find(KFalseString) &&
KErrNone == iFeatureManager_FeatureIds->Find(FeatureIdList->MdcaPoint(j),position)) ||
KErrNone == iSupportedInputLanguages->Find(FeatureIdList->MdcaPoint(j),position)
)
{
delete FeatureIdList;
delete Ids;
return ETrue;
}
}
delete Ids;
delete FeatureIdList;
return EFalse;
}
HBufC8* CCSXHHTMLContentParser::CreateBufferForCSSContentL(RFeatureControl& aFeatureControl)
{
RFeatureUidArray SupportedFeatures;
TInt err = aFeatureControl.Connect();
if ( err == KErrNone )
{
// ListSupportedFeatures() returns one of the Symbian error codes.
err = aFeatureControl.ListSupportedFeatures( SupportedFeatures );
// Remember to call CloseL after using RFeatureControl.
// It disconnects the Feature Manager server.
aFeatureControl.Close();
}
//Input Language variation changes
//-----------------------------------------
CPtiEngine* ptiEngine = CPtiEngine::NewL();
CleanupStack::PushL( ptiEngine );
CArrayFix<TInt>* languageCodeArray = new(ELeave)CArrayFixFlat<TInt>(2);
ptiEngine->GetAvailableLanguagesL( languageCodeArray );
TInt nInputLangCount = languageCodeArray->Count();
TInt nCount = SupportedFeatures.Count();
HBufC8* CssContent = HBufC8::NewLC(nCount * KMaxUnits * 6 + nInputLangCount * 3 + 400);
TPtr8 bufferPtr(CssContent->Des());
AppendStyleSheetContent_listitem(bufferPtr,nCount,SupportedFeatures,*languageCodeArray);
AppendStyleSheetContent_paragraph(bufferPtr,nCount,SupportedFeatures,*languageCodeArray);
AppendStyleSheetContent_ahref(bufferPtr,nCount,SupportedFeatures,*languageCodeArray);
AppendStyleSheetContent_none(bufferPtr,nCount,SupportedFeatures);
SupportedFeatures.Close();
CleanupStack::Pop(CssContent);
//Input Language variation changes
//-----------------------------------------
CleanupStack::PopAndDestroy( ptiEngine );
delete languageCodeArray;
//-----------------------------------------
return CssContent;
}
HBufC8* CCSXHHTMLContentParser::GetContentsFromHTMLFileL(const TDesC& htmlFile,CCoeEnv* aCoeEnv)
{
RFs& fsSession = aCoeEnv->FsSession();
RFile file;
TInt err = file.Open(fsSession,htmlFile,EFileRead|EFileShareReadersOrWriters);
if(KErrNone == err)
{
TInt FileSize;
HBufC8* htmlFileContent = NULL;
if(KErrNone == file.Size(FileSize))
{
htmlFileContent = HBufC8::NewLC(FileSize);
TPtr8 PtrContent = htmlFileContent->Des();
file.Read(PtrContent);
CleanupStack::Pop(htmlFileContent);
}
file.Close();
return htmlFileContent;
}
else
{
return NULL;
}
}
HBufC8* CCSXHHTMLContentParser::MergeCssAndHTMLContentL(HBufC8* aHTMLBuffer, HBufC8* aCssContent)
{
TInt BufferLength=0;
if(aHTMLBuffer)
BufferLength = aHTMLBuffer->Size();
if(aCssContent)
BufferLength += aCssContent->Size();
HBufC8* Htmlbuffer = HBufC8::NewLC(BufferLength);
TPtr8 HtmlbufferPtr(Htmlbuffer->Des());
if(aCssContent)
{
HtmlbufferPtr.Copy(aCssContent->Des());
delete aCssContent;
}
if(aHTMLBuffer)
{
HtmlbufferPtr.Append(aHTMLBuffer->Des());
delete aHTMLBuffer;
}
if(Htmlbuffer)
CleanupStack::Pop(Htmlbuffer);
return Htmlbuffer;
}
void CCSXHHTMLContentParser::AppendStyleSheetContent_listitem(TPtr8& abufferptr,TInt aFeatureIdCount,
RFeatureUidArray& aSupportedFeatures,
CArrayFix<TInt>& alanguageCodeArray)
{
//List Items
//---------------------------------------------------------
abufferptr.Copy(KCsstext_First);
for(TInt i=0;i<aFeatureIdCount;++i)
{
TBuf<KMaxFileName> FeatureId;
FeatureId.Format(KtextFormat_true_l,aSupportedFeatures[i].iUid);
//FeatureId.Append(KComma);
abufferptr.Append(FeatureId);
}
for(TInt i=0;i<alanguageCodeArray.Count();++i)
{
TBuf<KMaxFileName> FeatureId;
if(alanguageCodeArray[i] < 10)
FeatureId.Format(KtextFormat_lang_0l,alanguageCodeArray[i]);
else
FeatureId.Format(KtextFormat_lang_l,alanguageCodeArray[i]);
abufferptr.Append(FeatureId);
}
abufferptr.Append(KDefaultFeatureId);
abufferptr.Append(KCsstext_displayp_li);
abufferptr.Append(KCsstext_Last);
//---------------------------------------------------------
}
void CCSXHHTMLContentParser::AppendStyleSheetContent_paragraph(TPtr8& abufferptr,TInt aFeatureIdCount,
RFeatureUidArray& aSupportedFeatures,
CArrayFix<TInt>& alanguageCodeArray)
{
//Paragraph
//---------------------------------------------------------
abufferptr.Append(KCsstext_First);
for(TInt i=0;i<aFeatureIdCount;++i)
{
TBuf<KMaxFileName> FeatureId;
FeatureId.Format(KtextFormat_true_b,aSupportedFeatures[i].iUid);
//FeatureId.Append(KComma);
abufferptr.Append(FeatureId);
}
for(TInt i=0;i<alanguageCodeArray.Count();++i)
{
TBuf<KMaxFileName> FeatureId;
if(alanguageCodeArray[i] < 10)
FeatureId.Format(KtextFormat_lang_0b,alanguageCodeArray[i]);
else
FeatureId.Format(KtextFormat_lang_b,alanguageCodeArray[i]);
abufferptr.Append(FeatureId);
}
abufferptr.Append(KDefaultFeatureId);
abufferptr.Append(KCsstext_displayp_p);
abufferptr.Append(KCsstext_Last);
//---------------------------------------------------------
}
void CCSXHHTMLContentParser::AppendStyleSheetContent_ahref(TPtr8& abufferptr,TInt aFeatureIdCount,
RFeatureUidArray& aSupportedFeatures,
CArrayFix<TInt>& alanguageCodeArray)
{
//A href
//---------------------------------------------------------
abufferptr.Append(KCsstext_First);
for(TInt i=0;i<aFeatureIdCount;++i)
{
TBuf<KMaxFileName> FeatureId;
FeatureId.Format(KtextFormat_true_a,aSupportedFeatures[i].iUid);
abufferptr.Append(FeatureId);
}
for(TInt i=0;i<alanguageCodeArray.Count();++i)
{
TBuf<KMaxFileName> FeatureId;
if(alanguageCodeArray[i] < 10)
FeatureId.Format(KtextFormat_lang_0a,alanguageCodeArray[i]);
else
FeatureId.Format(KtextFormat_lang_a,alanguageCodeArray[i]);
abufferptr.Append(FeatureId);
}
abufferptr.Append(KDefaultFeatureId);
abufferptr.Append(KCsstext_displayp_a);
abufferptr.Append(KCsstext_Last);
//---------------------------------------------------------
}
void CCSXHHTMLContentParser::AppendStyleSheetContent_none(TPtr8& abufferptr,TInt aFeatureIdCount,
RFeatureUidArray& aSupportedFeatures
)
{
//False
//---------------------------------------------------------
abufferptr.Append(KCsstext_First);
for(TInt i=0;i<aFeatureIdCount;++i)
{
TBuf<KMaxFileName> FeatureId;
FeatureId.Format(KtextFormat_false,aSupportedFeatures[i].iUid,aSupportedFeatures[i].iUid,aSupportedFeatures[i].iUid);
abufferptr.Append(FeatureId);
}
abufferptr.Append(KDefaultFeatureId);
abufferptr.Append(KCsstext_displayp_n);
abufferptr.Append(KCsstext_Last);
//---------------------------------------------------------
}