diff -r 12f60d9a73b3 -r cbffe13eac63 csxhelp/HelpEngine/src/CSXHHTMLContentParser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/csxhelp/HelpEngine/src/CSXHHTMLContentParser.cpp Wed Sep 01 12:30:56 2010 +0100 @@ -0,0 +1,1419 @@ +/* +* 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 "CSXHViewIDs.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +//Input Language variation changes +#include + +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;iFsSession(); + + TDriveList DirList; + if(FileSession.DriveList(DirList) != KErrNone) + return; + CCSXHXMLParseHandler_MetaFile* XMLParser = CCSXHXMLParseHandler_MetaFile::NewL(iCoeEnv); + CleanupStack::PushL(XMLParser); + InitializeReaderL(XMLParser); + + + TBuf* rootDir = new(ELeave) TBuf; + CleanupStack::PushL(rootDir);//5 + + // begin runtime index XML generating + // + iIndexing = CCSXHRuntimeIndexing::NewL(); + TInt driveListSize = DirList.Length(); + TBool dirExists = iIndexing->IndexFileExistsL(); + 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->CheckDirChangeL( 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->DeleteIndexFileL( 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->BeginIndexFileL( 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* 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 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 masterFile; + + iIndexing->GetPrivatePath( masterFile ); + masterFile.Append( aDrive ); + masterFile.Append( KFwdSlash ); + iIndexing->AppendLocaleL( masterFile ); + masterFile.Append( KMasterMetaFile ); + if(BaflUtils::FileExists( FileSession,masterFile ) ) + { +#ifdef _DEBUG + RDebug::Print(_L("index exist begin to parse! %c"), TUint( 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; + } + +TBool CCSXHHTMLContentParser::IsRedirectedL(CCSXHHelpDataBase *aDataBase, + const TDesC &aPath, TUid &aUid, TCoeContextName &aContextName) + { + RFs& FileSession = iCoeEnv->FsSession(); + TBuf redirectFile( aPath ); + redirectFile.Append( KRedirectFile ); + TBool result = EFalse; + + if ( BaflUtils::FileExists( FileSession, redirectFile ) ) + { + CCSXHXMLParseHandler_RedirectFile* XMLParser = + CCSXHXMLParseHandler_RedirectFile::NewL(iCoeEnv, aUid, aContextName); + XMLParser->SetDataBasePtr( aDataBase ); + + CleanupStack::PushL( XMLParser ); + InitializeReaderL( XMLParser ); + // ParseL is not in async + iXmlReader->ParseL( FileSession, redirectFile ); + if ( XMLParser->IsTargetPathFound() ) + { + TBuf& targetContextName = XMLParser->TargetContextName(); + if ( targetContextName.Length() <= aContextName.MaxLength() ) + { + aUid = XMLParser->TargetUid(); + aContextName = targetContextName; + result = ETrue; + } + } + CleanupStack::PopAndDestroy( XMLParser ); + ClearReader(); + } + + return result; + } + +void CCSXHHTMLContentParser::GenerateTOC2ListL(CCSXHGenericTOC1& +aGenericTOC1Object, RPointerArray* 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 lookupindexfile; + toc1->GetHelpFileL(lookupindexfile); + XMLParser->SetPath(lookupindexfile); + lookupindexfile.Append(KIndexFile); + + if(BaflUtils::FileExists(FileSession,lookupindexfile)) + iXmlReader->ParseL (FileSession,lookupindexfile); + + TBufHelpContentName(toc1->GetName()); + int toc1Count = iDuplicateHelpTopicList.Count(); + + for(int i=0;i < toc1Count;i++) + { + CCSXHHtmlTOC1* temptoc1 = iDuplicateHelpTopicList[i]; + + if(temptoc1->GetName().CompareF(HelpContentName) == 0) + { + TBuf 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 htmlFile; + topic->GetHtmlFileName(htmlFile); + return GetContentsFromFileL(htmlFile,iCoeEnv,iFeatureControl); + } + + +void CCSXHHTMLContentParser::ScanAndParseXMLfileToCreateTOC1ObjectL( + RFs& FileSession, + CDirScan* scanner, + CCSXHHelpDataBase* aDataBase, + const TInt& aDrive, + CCSXHXMLParseHandler_MetaFile* XMLParser + ) + { + CDir* entryList = NULL; + scanner->NextL(entryList); + if (!entryList) + { + return; + } + + CleanupStack::PushL(entryList); + + TInt entryCount = entryList->Count(); + TInt ROMDrive; + RFs::CharToDrive(PathInfo::RomRootPath()[0], ROMDrive); + TBuf 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)) + { + TBool isRomBased = EFalse; + TInt32 priority = XMLParser->Priority(); + + // Now we take a walk if it's application helps (priority == 0) + if ((priority != 0) + && ((aDrive == ROMDrive) || IsRomBasedContentL(FileSession, entry.iName))) + { + if (priority < KHighestPriority) + { + priority = KHighestPriority; + } + else if (priority > KLowestPriority) + { + priority = KLowestPriority; + } + + isRomBased = ETrue; + } + else + { + priority = 0; + } + + CCSXHHtmlTOC1* categoryObj = CCSXHHtmlTOC1::NewL(XMLParser->GetApplicationName(), entry.iName, aDrive, + isRomBased ? KCSXHToc2ViewID : KCSXHToc2AppHelpsViewID, priority); + if (!categoryObj->IsValid()) + { + delete categoryObj; + } + else + { + CleanupStack::PushL(categoryObj); + if (isRomBased) + { + if (aDataBase->GetMainTopics()->InsertChildWithPriority(categoryObj, EFalse)) + { + iHtmlTOC1List.AppendL(categoryObj); + } + else + { + iDuplicateHelpTopicList.AppendL(categoryObj); + } + } + else + { + if (aDataBase->GetAppHelpsTopics()->InsertChild(categoryObj, EFalse)) + { + iHtmlTOC1List.AppendL(categoryObj); + } + else + { + iDuplicateHelpTopicList.AppendL(categoryObj); + } + } + + iIndexing->RuntimeGenerateIndexL(*categoryObj, XMLParser->GetFeatureIds()); + CleanupStack::Pop(categoryObj); + } + } + } + } + } + + CleanupStack::PopAndDestroy(entryList); + } + +TBool CCSXHHTMLContentParser::IsRomBasedContentL( RFs& FileSession, const TDesC &aUid ) + { +#ifdef __WINSCW__ + return ETrue; +#endif + + TBool result = EFalse; + CDirScan* scanner=CDirScan::NewLC(FileSession); + TBuf rootDir; + rootDir.Append( 'z' ); + + if( GetHTMLContentPathForDriveL( &rootDir,iCoeEnv ) ) + { + scanner->SetScanDataL(rootDir,KEntryAttDir|KEntryAttMatchExclusive, + ESortByName|EAscending, CDirScan::EScanDownTree); + CDir* entryList = NULL; + scanner->NextL(entryList); + + if ( !entryList ) + { + CleanupStack::PopAndDestroy( scanner ); + return EFalse; + } + + TInt entryCount = entryList->Count(); + + while ( entryCount-- ) + { + TEntry entry=(*entryList)[entryCount]; + if ( ( entry.iName ).CompareC(aUid) == 0 ) + { + result = ETrue; + break; + } + } + delete entryList; + } + + CleanupStack::PopAndDestroy( scanner ); + + return result; + } + +void CCSXHHTMLContentParser::InsertHTMLToc1L( + const TDesC& aAppUidName, + const TDesC& aAppName, + const TInt& aDrive, + CCSXHHelpDataBase* aDataBase, + const TDesC& aFeatureIds, + TInt32 aPriority + ) + { + if (CheckFeatureIDL(aFeatureIds)) + { + if (!IsAppUIdPresentAlready(aAppUidName)) + { + // Now we take a walk if it's application helps (priority == 0) + CCSXHHtmlTOC1* categoryObj = CCSXHHtmlTOC1::NewL(aAppName,aAppUidName, aDrive, + aPriority == 0 ? KCSXHToc2AppHelpsViewID : KCSXHToc2ViewID, aPriority); + + if (categoryObj->IsValid()) + { + CleanupStack::PushL(categoryObj); + if (aPriority == 0) + { + if (aDataBase->GetAppHelpsTopics()->InsertChild(categoryObj, EFalse)) + { + iHtmlTOC1List.AppendL(categoryObj); + } + else + { + iDuplicateHelpTopicList.AppendL(categoryObj); + } + } + else + { + if (aDataBase->GetMainTopics()->InsertChildWithPriority(categoryObj, EFalse)) + { + iHtmlTOC1List.AppendL(categoryObj); //Keep a local copy*/ + } + else + { + iDuplicateHelpTopicList.AppendL(categoryObj); + } + } + CleanupStack::Pop(categoryObj); + } + else + { + delete categoryObj; + } + } + } + } + +HBufC8* CCSXHHTMLContentParser::GetContentsFromFileL(const TDesC& htmlFile,CCoeEnv* aCoeEnv, + RFeatureControl& aFeatureControl) + { + RFs& fileSession = aCoeEnv->FsSession(); + TInt SlashPosition = htmlFile.LocateReverse('\\'); + TBuf* CompressedFile = new (ELeave) TBuf; + 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*Fname; + TBuf *HtmlFileName = new (ELeave) TBuf; + 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* Master_kywdPath = new(ELeave) TBuf; + 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* 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* lookup = new(ELeave)TBuf; + 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::GetContextTopicL( + CCSXHHelpDataBase *aDataBase, + TUid &aUid, + TCoeContextName &aContextName + ) + { + TBuf path; + TInt32 toc1Count = iHtmlTOC1List.Count(); + TInt32 dupToc1Count = iDuplicateHelpTopicList.Count(); + CCSXHHtmlTOC1 *toc1 = NULL; + CCSXHHtmlTOC1 *temptoc1 = NULL; + TBool redirected = EFalse; + + for ( TInt32 i = 0; i < toc1Count; ++i ) + { + toc1 = iHtmlTOC1List[i]; + if ( aUid == toc1->GetAppUid() ) + { + toc1->GetHelpFileL( path ); + if ( IsRedirectedL( aDataBase, path, aUid, aContextName ) ) + { + redirected = ETrue; + } + else + { + return toc1->GetContextTopic( aContextName ); + } + break; + } + } + + if ( !redirected ) + { + for ( TInt32 i = 0; i < dupToc1Count; ++i ) + { + toc1 = iDuplicateHelpTopicList[i]; + if ( aUid == toc1->GetAppUid() ) + { + toc1->GetHelpFileL( path ); + if ( IsRedirectedL( aDataBase, path, aUid, aContextName ) ) + { + redirected = ETrue; + } + else + { + temptoc1 = GetCorrespondingTOC1FromMainArray(toc1->GetName()); + return temptoc1->GetContextTopic( aContextName ); + } + } + } + } + + if ( redirected ) + { + for ( TInt32 i = 0; i < toc1Count; ++i ) + { + toc1 = iHtmlTOC1List[i]; + if ( aUid == toc1->GetAppUid() ) + { + return toc1->GetContextTopic( aContextName ); + } + } + + for ( TInt32 i = 0; i < dupToc1Count; ++i ) + { + toc1 = iDuplicateHelpTopicList[i]; + if ( aUid == toc1->GetAppUid() ) + { + temptoc1 = GetCorrespondingTOC1FromMainArray( toc1->GetName() ); + return temptoc1->GetContextTopic( aContextName ); + } + } + } + + 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& aTOC1ObjectsArray, + const TDesC& aUrl, TBool aMainArrayList) + { + /*For URLs of form + file:://:/system/xhtml///Html name + We can have help topics for other cases, help topic objects not possible + */ + TBuf aFileUrl; + + int toc1Count = aTOC1ObjectsArray.Count(); + CCSXHHtmlTOC1* toc1,*temptoc1; + for(int j = 0; j < toc1Count; ++j) + { + toc1 = aTOC1ObjectsArray[j]; + TBuf 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& aFileName) + { + aFileName.Copy(KEmptyString); + + RFs& FileSession = coeEnv->FsSession(); + TDriveList DirList; + if( (FileSession.DriveList(DirList)= 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;iGetName().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;iGetAppUid()) + { + result = ETrue; + break; + } + } + + toc1Count = iDuplicateHelpTopicList.Count(); + for(int i=0;iGetAppUid()) + { + result = ETrue; + break; + } + } + + return result; + + } + +void CCSXHHTMLContentParser::ParseKeywdFileAndCreatekywdTOC1ObjectsL( + RPointerArray& aTOC1ObjectsArray, + CCSXHXMLParseHandler_Kywd* XMLParser, TBool bMasterKeywordFilePresent) + { + int toc1Count = aTOC1ObjectsArray.Count(); + CCSXHHtmlTOC1* toc1; + + TBuf* lookup = new(ELeave)TBuf; + 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;iAppendL(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* languageCodeArray = new(ELeave)CArrayFixFlat(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; iAt(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* languageCodeArray = new(ELeave)CArrayFixFlat(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& alanguageCodeArray) + { + //List Items + //--------------------------------------------------------- + abufferptr.Copy(KCsstext_First); + + for(TInt i=0;i FeatureId; + FeatureId.Format(KtextFormat_true_l,aSupportedFeatures[i].iUid); + //FeatureId.Append(KComma); + abufferptr.Append(FeatureId); + } + + for(TInt i=0;i 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& alanguageCodeArray) + { + //Paragraph + //--------------------------------------------------------- + abufferptr.Append(KCsstext_First); + for(TInt i=0;i FeatureId; + FeatureId.Format(KtextFormat_true_b,aSupportedFeatures[i].iUid); + //FeatureId.Append(KComma); + + abufferptr.Append(FeatureId); + } + + for(TInt i=0;i 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& alanguageCodeArray) + { + //A href + //--------------------------------------------------------- + abufferptr.Append(KCsstext_First); + for(TInt i=0;i FeatureId; + FeatureId.Format(KtextFormat_true_a,aSupportedFeatures[i].iUid); + abufferptr.Append(FeatureId); + } + + for(TInt i=0;i 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 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); + + //--------------------------------------------------------- + }