diff -r 6385c4c93049 -r 8e6fa1719340 browserui/browser/FeedsSrc/FeedsFeedContainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserui/browser/FeedsSrc/FeedsFeedContainer.cpp Wed Sep 01 12:31:04 2010 +0100 @@ -0,0 +1,1131 @@ +/* +* Copyright (c) 2005-2008 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: A view to browse a given feed. +* +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __SERIES60_HELP +// Context-Sensitve Help File +#include +#include "BrowserApplication.h" +#endif // __SERIES60_HELP + +#include "Browser.hrh" +#include +#include "FeedsFeedContainer.h" +#include "FeedsFeedView.h" +#include +#include "ApiProvider.h" +#include "BrowserSpecialLoadObserver.h" +#include "Display.h" +#include "BrowserWindowManager.h" +#include "BrowserWindow.h" +#include "BrowserAppUi.h" +#include +#include +#include +#include + +#include "eikon.hrh" + + +_LIT(KFeedsSchema, "feeds:"); +_LIT(KFeedsNavSchema, "feedsnav:"); +_LIT(KNext, "next"); +_LIT(KTemplate, "feeds_view_template.html"); +_LIT(KTokenTitle, "#Title#"); +_LIT(KTokenWebUrl, "#WebUrl#"); +_LIT(KTokenDate, "#Date#"); +_LIT(KTokenDescription, "#Description#"); +_LIT(KTokenEnclosure, "#Enclosure#"); +_LIT(KTokenShowPrev, "#ShowPrev#"); +_LIT(KTokenShowNext, "#ShowNext#"); +_LIT(KTokenTextDir, "#dir#"); +_LIT(KLTRTextDir, "\"ltr\""); +_LIT(KRTLTextDir, "\"rtl\""); + +const TInt KDateSize = 30; // Size of Date strings +const TInt KTimeSize = 30; // Size of Time strings + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::NewL +// +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CFeedsFeedContainer* CFeedsFeedContainer::NewL(CFeedsFeedView* aView, + MApiProvider& aApiProvider) + { + CFeedsFeedContainer* self = new (ELeave) CFeedsFeedContainer(aView, aApiProvider); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::CFeedsFeedContainer +// +// C++ default constructor. +// ----------------------------------------------------------------------------- +// +CFeedsFeedContainer::CFeedsFeedContainer(CFeedsFeedView* aView, + MApiProvider& aApiProvider ) : + iView( aView ), + iApiProvider( aApiProvider ), + iBrowserControl(0) + { + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ConstructL +// +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::ConstructL() + { + EnsureTemplateL(KTemplate); + LoadTemplateL(KTemplate); + + CreateWindowL(); + SetMopParent( iView ); + //SetRect(aRect); + ActivateL(); + + TRect rect(Position(), Size()); + + iBrowserControl = CreateBrowserControlL(this, rect, + TBrCtlDefs::ECapabilityDisplayScrollBar | TBrCtlDefs::ECapabilityLoadHttpFw, + TBrCtlDefs::ECommandIdBase, NULL, NULL, this, NULL, NULL, NULL, NULL); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::~CFeedsFeedContainer +// +// Deconstructor. +// ----------------------------------------------------------------------------- +// +CFeedsFeedContainer::~CFeedsFeedContainer() + { + delete iTemplate; + delete iNaviPaneTabsGroup; + delete iBrowserControl; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::OfferKeyEventL +// +// Handles key event. +// ----------------------------------------------------------------------------- +// +TKeyResponse CFeedsFeedContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) + { + + TKeyResponse response = EKeyWasConsumed; + + if (aType == EEventKey) + { + switch (aKeyEvent.iCode) + { + case EKeyLeftUpArrow: // Northwest + case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyLeftArrow: // West + case EKeyLeftDownArrow: // Southwest + case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge + { + ShowPrevItemL(); + } + return response; + + case EKeyRightUpArrow: // Northeast + case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyRightArrow: // East + case EKeyRightDownArrow: // Southeast + case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge + { + ShowNextItemL(); + } + return response; + + } + } + + response = iBrowserControl->OfferKeyEventL(aKeyEvent, aType); + if(iBrowserControl->FocusedElementType() != TBrCtlDefs::EElementAnchor && iView->Toolbar() ) + { + iView->Toolbar()->SetItemDimmed(EFeedsSeeFullStory, ETrue, ETrue); + } + else + { + iView->Toolbar()->SetItemDimmed(EFeedsSeeFullStory, EFalse, ETrue); + } + // now "simulate" another key event for proper handling of middle-softkey + if ( (aKeyEvent.iScanCode == EStdKeyDevice3) && (aType == EEventKeyDown) ) + { + TKeyEvent keyEvent; + keyEvent.iCode = 0xf845; + keyEvent.iModifiers = 1; + keyEvent.iRepeats = 0; + keyEvent.iCode = EKeyDevice3; + keyEvent.iScanCode = EStdKeyDevice3; + response = iBrowserControl->OfferKeyEventL( keyEvent, EEventKey ); + } + return response; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::GetHelpContext +// +// Get help context for the control. +// ----------------------------------------------------------------------------- +// +#ifdef __SERIES60_HELP +void CFeedsFeedContainer::GetHelpContext(TCoeHelpContext& aContext) const + { + // This must be the Browser's uid becasue the help texts are under Browser topics. + aContext.iMajor = KUidBrowserApplication; + aContext.iContext = KOSS_HLP_RSS_ARTICLE; + } +#endif // __SERIES60_HELP + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::MakeVisible +// +// Sets this control as visible or invisible. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::MakeVisible(TBool aVisible) + { + if (iBrowserControl) + { + iBrowserControl->MakeVisible(aVisible); + } + + CCoeControl::MakeVisible(aVisible); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::SizeChanged +// +// Called by framework when the view size is changed. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::SizeChanged() + { + if (iBrowserControl) + { + iBrowserControl->SetRect(Rect()); + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::HandleResourceChange +// +// Called by the framework when a display resource changes (i.e. skin or layout). +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::HandleResourceChange(TInt aType) + { + CCoeControl::HandleResourceChange(aType); + iBrowserControl->HandleResourceChange(aType); + + if (aType == KEikDynamicLayoutVariantSwitch) + { + TRect rect; + + if (AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, rect)) + { + SetRect(rect); + } + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::CountComponentControls +// +// Returns number of components. +// ----------------------------------------------------------------------------- +// +TInt CFeedsFeedContainer::CountComponentControls() const + { + TInt ctrls = 0; + if ( iBrowserControl ) + { + ctrls++;// Brctl + } + return ctrls; + } + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::NetworkConnectionNeededL +// +// Request to create a network connection. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::NetworkConnectionNeededL(TInt* aConnectionPtr, + TInt* aSockSvrHandle, TBool* aNewConn, TApBearerType* aBearerType) + { + iApiProvider.SpecialLoadObserver().NetworkConnectionNeededL(aConnectionPtr, aSockSvrHandle, + aNewConn, aBearerType); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::HandleRequestL +// +// Request the host applicaion to handle non-http request. +// ----------------------------------------------------------------------------- +// +TBool CFeedsFeedContainer::HandleRequestL(RArray* aTypeArray, CDesCArrayFlat* aDesArray) + { + HBufC* url = NULL; + TBool handled = ETrue; + + // The 2 arrays must be in sync. Each element in iTypeArray + // identifies the type of the corresponding element in iDesArray. + if (aTypeArray->Count() != aDesArray->Count()) + { + User::Leave(KErrArgument); + } + + // Get the url. + for (TInt i = 0; i < aTypeArray->Count(); i++) + { + if ((*aTypeArray)[i] == EParamRequestUrl) + { + url = HBufC::NewLC((*aDesArray)[i].Length()); + url->Des().Copy((*aDesArray)[i]); + break; + } + } + + // Leave if the url wasn't found. + if (url == NULL) + { + User::Leave(KErrArgument); + } + + // Handle the "feeds:" schema + if (url->Find(KFeedsSchema) == 0) + { + // Extract the real url from the "feed" url. + TPtrC loadUrl(url->Ptr() + KFeedsSchema().Length(), + url->Length() - KFeedsSchema().Length()); + + // Handle the "feeds_nav:" schema. + if (loadUrl.Find(KFeedsNavSchema) == 0) + { + // Get the direction + TPtrC dir(loadUrl.Ptr() + KFeedsNavSchema().Length(), + loadUrl.Length() - KFeedsNavSchema().Length()); + + if (dir.FindF(KNext) == 0) + { + ShowNextItemL(); + } + else + { + ShowPrevItemL(); + } + } + else + { + // Otherwise dispatch the url to the client. + iApiProvider.FeedsClientUtilities().LoadUrlL(loadUrl); + } + } + // Otherwise, send request to SchemeHandler through default BrCtlSpecialLoadObserver + else + { + handled = iApiProvider.SpecialLoadObserver().HandleRequestL( aTypeArray, aDesArray ); + } + + CleanupStack::PopAndDestroy(url); + return handled; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::HandleDownloadL +// +// Called when the browser control wants the host application (us) to handle +// downloaded content +// ----------------------------------------------------------------------------- +// +TBool CFeedsFeedContainer::HandleDownloadL(RArray* aTypeArray, + CDesCArrayFlat* aDesArray) + { + HBufC* url = NULL; + TBool handled = EFalse; + + // + // Pass first to the main special load observer to be handled. + // If it's not handled, continue here + // + handled = iApiProvider.SpecialLoadObserver().HandleDownloadL( aTypeArray, aDesArray ); + + if (!handled) + { + // The 2 arrays must be in sync. Each element in iTypeArray + // identifies the type of the corresponding element in iDesArray. + if (aTypeArray->Count() != aDesArray->Count()) + { + User::Leave(KErrArgument); + } + + // Get the url. + for (TInt i = 0; i < aTypeArray->Count(); i++) + { + if ((*aTypeArray)[i] == EParamRequestUrl) + { + url = HBufC::NewLC((*aDesArray)[i].Length()); + url->Des().Copy((*aDesArray)[i]); + break; + } + } + + TPtrC pUrl(url->Des()); + + // Leave if the url wasn't found. + if (url == NULL) + { + User::Leave(KErrArgument); + } + else + { + // Otherwise dispatch the url to the client. + iApiProvider.FeedsClientUtilities().SubscribeToL(KNullDesC, pUrl); + handled = ETrue; + } + + CleanupStack::PopAndDestroy(url); + } + return handled; + } + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ComponentControl +// +// Returns pointer to particular component. +// ----------------------------------------------------------------------------- +// +CCoeControl* CFeedsFeedContainer::ComponentControl(TInt aIndex) const + { + CCoeControl *ctrl = NULL; + + switch (aIndex) + { + case 0: + { + ctrl = iBrowserControl; + break; + } + + default: + break; + } + + return ctrl; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::SetCurrentFeedL +// +// Sets the current feed +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::SetCurrentFeedL(CFeedsEntity& aFeed, TInt aInitialItem) + { + iFeed = &aFeed; + iCurrentItem = aInitialItem; + + // Update the view. + if (iView->iContainerOnStack) + { + // Only do this if it's view is active. + TPtrC title; + iFeed->GetStringValue(EFeedAttributeTitle,title); + if (title.Length() > 0) + { + iApiProvider.Display().SetTitleL( title ); + } + else + { + iApiProvider.Display().SetTitleL( KNullDesC ); + } + } + + ShowFeedItemL(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::GetItemUrl +// +// Returns the current item's url. +// ----------------------------------------------------------------------------- +// +const TDesC& CFeedsFeedContainer::GetItemUrl() + { + iFeed->GetChildren()[iCurrentItem]->GetStringValue(EItemAttributeLink,iUrl); + return iUrl; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::CurrentItem +// +// Returns the index of the current item. +// ----------------------------------------------------------------------------- +// +TInt CFeedsFeedContainer::CurrentItem() + { + return iCurrentItem; + } + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ItemCount +// +// Returns the number of items. +// ----------------------------------------------------------------------------- +TInt CFeedsFeedContainer::ItemCount() const + { + return iFeed->GetChildren().Count(); + } + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ShowNextItemL +// +// Shows the next item if possible. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::ShowNextItemL() + { + if (iFeed->GetChildren().Count() <= 1) + { + return; + } + + if ((iCurrentItem + 1) < iFeed->GetChildren().Count()) + { + iCurrentItem++; + } + else + { + iCurrentItem = 0; + } + if (iView->Toolbar()) + iView->Toolbar()->SetItemDimmed(EFeedsSeeFullStory, EFalse, ETrue); + ShowFeedItemL(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ShowPrevItemL +// +// Shows the prev item if possible. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::ShowPrevItemL() + { + if (iFeed->GetChildren().Count() <= 1) + { + return; + } + + if ((iCurrentItem - 1) >= 0) + { + iCurrentItem--; + } + else + { + iCurrentItem = iFeed->GetChildren().Count() - 1; + } + if (iView->Toolbar()) + iView->Toolbar()->SetItemDimmed(EFeedsSeeFullStory, EFalse, ETrue); + ShowFeedItemL(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::Clear +// +// Clears the navigation pane. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::ClearNavigationPane() + { + delete iNaviPaneTabsGroup; + iNaviPaneTabsGroup = NULL; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::UpdateNavigationPaneL +// +// Handles the changes needed to the Navigation Pane. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::UpdateNavigationPaneL() + { + const TInt KTabId = 88888; + const TInt KMaxNaviText = 25; // format is "/". + _LIT(KFormat, "%d/%d"); + + CAknNavigationControlContainer* naviPane = NULL; + TBuf buf; + CAknTabGroup* tabGroup = NULL; + TInt itemCount = 0; + + if (iFeed) + { + itemCount = iFeed->GetChildren().Count(); + } + + // Get the navigation sub-pane. + CAknViewAppUi* appUi; + TUid uid; + + // Get the title sub-pane. + appUi = static_cast(CCoeEnv::Static()->AppUi()); + + uid.iUid = EEikStatusPaneUidNavi; + + CEikStatusPaneBase::TPaneCapabilities subPane = appUi->StatusPane()-> + PaneCapabilities(uid); + + // Set the title if the pane belongs to the app. + if (subPane.IsPresent() && subPane.IsAppOwned()) + { + naviPane = (CAknNavigationControlContainer*) appUi->StatusPane()->ControlL(uid); + } + else + { + User::Leave(KErrNotSupported); + } + + // Ensure the tab group was created. + if (!iNaviPaneTabsGroup) + { + iNaviPaneTabsGroup = naviPane->CreateTabGroupL(); + } + + // Format Navi Pane text "index/count" style. + buf.Format(KFormat, iCurrentItem + 1, itemCount); + + // Update the tab-group. + tabGroup = static_cast(iNaviPaneTabsGroup->DecoratedControl()); + + // Already created, replacd the tab. + if (tabGroup->TabCount() != NULL) + { + tabGroup->ReplaceTabL(KTabId, buf); + } + + // Otherwise add the tab. + else + { + tabGroup->AddTabL(KTabId, buf); + } + + tabGroup->SetTabFixedWidthL(EAknTabWidthWithOneTab); + tabGroup->SetActiveTabById(KTabId); + + // If not yet pushed, this will do the push; if already there, this brings + // it to top and draws. + naviPane->PushL(*iNaviPaneTabsGroup); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ShowFeedItemL +// +// Shows the given feed item. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::ShowFeedItemL() + { + _LIT(KSchema, "data:"); + _LIT8(KType, "text/html"); + + const TInt KInt64Length = 25; + + HBufC* link = NULL; + HBufC* htmlTemplate = NULL; + HBufC* enclosureStr = NULL; + TDataType datatype(KType); + TUid uid; + CFeedsEntity* item = iFeed->GetChildren()[iCurrentItem]; + HBufC* enclosure = NULL; + TInt enclosureLen = 0; + + // Mark the item as read. + iApiProvider.FeedsClientUtilities().SetItemStatusL(iFeed->GetChildren()[iCurrentItem], EItemStatusRead); + + // Load the localized strings. + enclosureStr = StringLoader::LoadLC(R_FEEDS_ENCLOSURE); + + // Convert the item's UTC timestamp into a localized string. + TBuf timestamp; + TBuf temp; + TTime ts; + + item->GetTimeValue(EItemAttributeTimestamp,ts); + + // Translate from UTC to local time. + TTime local; + TTime utc; + TTimeIntervalSeconds delta; + + local.HomeTime(); + utc.UniversalTime(); + utc.SecondsFrom(local, delta); + ts -= delta; + + // Create the localized time string. + //Set time + HBufC* timeFormat = iEikonEnv->AllocReadResourceLC( R_QTN_TIME_USUAL_WITH_ZERO ); + ts.FormatL( timestamp, *timeFormat ); + CleanupStack::PopAndDestroy( timeFormat );//timeFormat + // + timestamp.Append(_L(" ")); + //Set date + HBufC* dateFormat = iEikonEnv->AllocReadResourceLC( R_QTN_DATE_USUAL_WITH_ZERO ); + ts.FormatL( temp, *dateFormat ); + CleanupStack::PopAndDestroy( dateFormat );//dateFormat + // + timestamp.Append(temp); + + // Create the enclosure string, which is a a series of the following string. + // + _LIT(KEnclosureMarkup, ""); + + TBuf16 size; + TInt64 sizeInt; + TReal64 sizeReal; + TRealFormat format; + TPtrC url; + TPtrC contentType; + TPtrC len; + TPtrC title; + TPtrC desc; + + format.iType = KRealFormatFixed; + format.iPlaces = 2; + + // Determine how large the enclosure string needs to be. + for (TInt i = 0; i < item->GetChildren().Count(); i++) + { + CFeedsEntity* en = item->GetChildren()[i]; + + en->GetStringValue(EEnclosureAttributeContentType,contentType); + en->GetStringValue(EEnclosureAttributeSize,len); + en->GetStringValue(EEnclosureAttributeLink,url); + en->GetStringValue(EEnclosureAttributeTitle,title); + TLex16 lex(len); + // Convert the enclosure size to mega-bytes. + lex.Val(sizeInt); + sizeReal = sizeInt / 1000000.0; + + size.Zero(); + size.AppendNum(sizeReal, format); + + enclosureLen += KEnclosureMarkup().Length(); + enclosureLen += url.Length(); + enclosureLen += enclosureStr->Length(); + enclosureLen += size.Length(); + enclosureLen += contentType.Length(); + } + + // Allocate the enclosure string. + enclosure = HBufC::NewLC(enclosureLen); + + // Construct the enclosure string. + for (TInt i = 0; i < item->GetChildren().Count(); i++) + { + CFeedsEntity* en = item->GetChildren()[i]; + + en->GetStringValue(EEnclosureAttributeContentType,contentType); + en->GetStringValue(EEnclosureAttributeSize,len); + en->GetStringValue(EEnclosureAttributeLink,url); + en->GetStringValue(EEnclosureAttributeTitle,title); + TLex16 lex(len); + + // Convert the enclosure size to mega-bytes. + lex.Val(sizeInt); + sizeReal = sizeInt / 1000000.0; + + size.Zero(); + size.AppendNum(sizeReal, format); + + enclosure->Des().AppendFormat(KEnclosureMarkup, &(url), enclosureStr, + &size, &(contentType)); + } + + // Load and prepare the html template. + item->GetStringValue(EItemAttributeTitle,title); + item->GetStringValue(EItemAttributeDescription,desc); + item->GetStringValue(EItemAttributeLink,url); + + htmlTemplate = ResolveTemplateL(title, timestamp, desc, + url, *enclosure); + + + CleanupStack::PushL(htmlTemplate); + iFeed->GetStringValue(EFeedAttributeTitle,title); + // Load the htmlTemplate in the browser control. + uid.iUid = KCharacterSetIdentifierUcs2; + + link = HBufC::NewLC(KSchema().Length() + title.Length()); + link->Des().Copy(KSchema); + link->Des().Append(title); + + TPtrC8 ptr((const TUint8*) htmlTemplate->Ptr(), htmlTemplate->Size()); + iBrowserControl->LoadDataL(*link, ptr, datatype, uid); + + CleanupStack::PopAndDestroy(link); + CleanupStack::PopAndDestroy(htmlTemplate); + CleanupStack::PopAndDestroy(enclosure); + CleanupStack::PopAndDestroy(enclosureStr); + + // Update the nav-pane. + UpdateNavigationPaneL(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::LoadTemplateL +// +// Loads the template html file. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::LoadTemplateL(const TDesC& aTemplateName) + { + RFs rfs; + RFile file; + TInt size; + TBuf path; + TUint encoding; + HBufC8* buff; + CXmlEncoding* xmlEncoding = NULL; + TInt loc; + + // Build the path to the file and open the file. + User::LeaveIfError(rfs.Connect()); + CleanupClosePushL(rfs); + + path.Append(_L("\\")); + path.Append(aTemplateName); + + User::LeaveIfError(file.Open(rfs, path, EFileRead)); + CleanupClosePushL(file); + + // Read the file into the buffer. + User::LeaveIfError(file.Size(size)); + + buff = HBufC8::NewL(size); + CleanupStack::PushL(buff); + + TPtr8 ptr((TUint8*) buff->Ptr(), size); + User::LeaveIfError(file.Read(ptr, size)); + + // Convert the buffer to ucs2 and clean up. + xmlEncoding = CXmlEncoding::NewL(); + CleanupStack::PushL(xmlEncoding); + + if (!xmlEncoding->DetermineCharEncodingL(ptr, KNullDesC, encoding)) + { + User::Leave(KErrCorrupt); + } + + iTemplate = xmlEncoding->ConvertToUcs2L(encoding, ptr); + + CleanupStack::PopAndDestroy(xmlEncoding); + CleanupStack::PopAndDestroy(buff); + CleanupStack::PopAndDestroy(/*file*/); + CleanupStack::PopAndDestroy(/*rfs*/); + + // Count the number of token. These counts are used in ResolveTemplate + // to determine how big the resolved buffer should be. + TPtrC findPtr; + + iTitleCount = 0; + iWebUrlCount = 0; + iDateCount = 0; + iDescriptionCount = 0; + iEnclosureCount = 0; + iShowPrevCount = 0; + iShowNextCount = 0; + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find(KTokenTitle())) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenTitle().Length())); + iTitleCount++; + } + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find(KTokenWebUrl())) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenWebUrl().Length())); + iWebUrlCount++; + } + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find(KTokenDate())) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenDate().Length())); + iDateCount++; + } + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find(KTokenDescription())) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenDescription().Length())); + iDescriptionCount++; + } + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find((KTokenEnclosure))) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenEnclosure().Length())); + iEnclosureCount++; + } + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find((KTokenShowPrev))) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenShowPrev().Length())); + iShowPrevCount++; + } + + findPtr.Set(*iTemplate); + while ((loc = findPtr.Find((KTokenShowNext))) != KErrNotFound) + { + findPtr.Set(findPtr.Mid(loc + KTokenShowNext().Length())); + iShowNextCount++; + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::ResolveTemplateL +// +// Loads and resolves the tokens in the template html file. +// ----------------------------------------------------------------------------- +// +HBufC* CFeedsFeedContainer::ResolveTemplateL(const TDesC& aTitle, + const TDesC& aTimestamp, const TDesC& aDescription, const TDesC& aUrl, + const TDesC& aEnclosure) + { + HBufC* ucs2Buff; + TInt loc; + + // Create and init the resolved buffer. + ucs2Buff = HBufC::NewLC(iTemplate->Length() + (aTitle.Length() * iTitleCount) + + (aTimestamp.Length() * iDateCount) + (aDescription.Length() * iDescriptionCount) + + (aUrl.Length() * iWebUrlCount) + + (aEnclosure.Length() * iEnclosureCount) + iShowPrevCount + iShowNextCount); + + ucs2Buff->Des().Copy(*iTemplate); + + // Resolve the tokens. + TPtr ucs2Ptr(ucs2Buff->Des()); + + // Add the text direction information here + TBool found(EFalse); + TBidiText::TDirectionality dir = TBidiText::TextDirectionality(aTitle, &found); + TBuf<5> textDirection; + if ( dir == TBidiText::ERightToLeft ) + { + textDirection.Copy(KRTLTextDir); + } + else + { + textDirection.Copy(KLTRTextDir); + } + + // replace the text direction string + if ((loc = ucs2Ptr.Find(KTokenTextDir())) != KErrNotFound) + { + ucs2Ptr.Replace(loc, textDirection.Length(), textDirection); + } + + // Replace the title tokens. + while ((loc = ucs2Ptr.Find(KTokenTitle())) != KErrNotFound) + { + ucs2Ptr.Replace(loc, KTokenTitle().Length(), aTitle); + } + + // Replace the url tokens. + while ((loc = ucs2Ptr.Find(KTokenWebUrl())) != KErrNotFound) + { + ucs2Ptr.Replace(loc, KTokenWebUrl().Length(), aUrl); + } + + // Replace the date tokens. + while ((loc = ucs2Ptr.Find(KTokenDate())) != KErrNotFound) + { + ucs2Ptr.Replace(loc, KTokenDate().Length(), aTimestamp); + } + + // Replace the description tokens. + while ((loc = ucs2Ptr.Find(KTokenDescription())) != KErrNotFound) + { + ucs2Ptr.Replace(loc, KTokenDescription().Length(), aDescription); + } + + // Replace the enclosure tokens. + while ((loc = ucs2Ptr.Find(KTokenEnclosure())) != KErrNotFound) + { + ucs2Ptr.Replace(loc, KTokenEnclosure().Length(), aEnclosure); + } + + CleanupStack::Pop(ucs2Buff); + return ucs2Buff; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFeedContainer::EnsureTemplateL +// +// If need be copy the template from ROM. +// ----------------------------------------------------------------------------- +// +void CFeedsFeedContainer::EnsureTemplateL(const TDesC& aName) + { + TInt err; + RFs defaultRfs; + TUint attValue = 0; + TBuf path; + + // Open a connection to the working drive. + User::LeaveIfError(defaultRfs.Connect()); + CleanupClosePushL(defaultRfs); + User::LeaveIfError(defaultRfs.SetSessionPath(_L("c:\\"))); + + // Build the path to the file. + path.Append(_L("\\")); + path.Append(aName); + + // Test whether or not the folder file is present. + err = defaultRfs.Att(path, attValue); + + // The file is there, just return. + if (err == KErrNone) + { + CleanupStack::PopAndDestroy(/*defaultRfs*/); + return; + } + + // If the file is missing copy it from ROM. + if ((err == KErrNotFound) || (err == KErrPathNotFound)) + { + RFs romRfs; + RFile file; + RFile romFile; + TInt size; + HBufC8* buffer = NULL; + + // Open an rfs for the z drive. + User::LeaveIfError(romRfs.Connect()); + CleanupClosePushL(romRfs); + User::LeaveIfError(romRfs.SetSessionPath(_L("z:\\"))); + + // Create the destination file. + User::LeaveIfError(file.Create(defaultRfs, path, EFileWrite)); + CleanupClosePushL(file); + + // Open the source file. + User::LeaveIfError(romFile.Open(romRfs, path, EFileRead)); + CleanupClosePushL(romFile); + + // Copy the file. + User::LeaveIfError(romFile.Size(size)); + buffer = HBufC8::NewLC(size); + TPtr8 bufferPtr(buffer->Des()); + + User::LeaveIfError(romFile.Read(bufferPtr, size)); + User::LeaveIfError(file.Write(bufferPtr, size)); + + // Clean up + CleanupStack::PopAndDestroy(buffer); + CleanupStack::PopAndDestroy(/*romFile*/); + CleanupStack::PopAndDestroy(/*file*/); + CleanupStack::PopAndDestroy(/*romRfs*/); + CleanupStack::PopAndDestroy(/*defaultRfs*/); + } + } + +// --------------------------------------------------------- +// CFeedsFeedContainer::ExtractBrCtlParam() +// --------------------------------------------------------- +// +TPtrC CFeedsFeedContainer::ExtractBrCtlParam + ( TUint aParamTypeToFind, + RArray* aTypeArray, + CDesCArrayFlat* aDesArray, + TBool& aParamFound ) const + { + // initialize output parameter + aParamFound = EFalse; + TPtrC16 retParamValue; + + for ( TInt j = 0; j < aTypeArray->Count(); j++ ) + { + const TUint paramType = (*aTypeArray)[j]; + if ( aParamTypeToFind == paramType ) + { + // That's we need + retParamValue.Set( aDesArray->MdcaPoint(j) ); + aParamFound = ETrue; // Indicate it in the out param + break; // break the loop - we found it + } + } + return retParamValue; + } + +void CFeedsFeedContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + iBrowserControl->HandlePointerEventL(aPointerEvent); + if(iBrowserControl->FocusedElementType()!= TBrCtlDefs::EElementAnchor && iView->Toolbar() ) + { + iView->Toolbar()->SetItemDimmed(EFeedsSeeFullStory, ETrue, ETrue); + } + }