browserui/browser/FeedsSrc/FeedsFeedContainer.cpp
changeset 0 84ad3b177aa3
child 24 868cceedabd3
equal deleted inserted replaced
-1:000000000000 0:84ad3b177aa3
       
     1 /*
       
     2 * Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  A view to browse a given feed.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <AknNavi.h>
       
    20 #include <AknNaviDe.h>
       
    21 #include <AknTabGrp.h>
       
    22 #include <AknNaviLabel.h>
       
    23 #include <aknutils.h>
       
    24 #include <AknViewAppUi.h>
       
    25 #include <BrCtlInterface.h>
       
    26 #include <CharConv.H>
       
    27 #include <StringLoader.h>
       
    28 
       
    29 #ifdef __SERIES60_HELP
       
    30 // Context-Sensitve Help File
       
    31 #include <csxhelp/browser.hlp.hrh>
       
    32 #include "BrowserApplication.h"
       
    33 #endif // __SERIES60_HELP
       
    34 
       
    35 #include "Browser.hrh"
       
    36 #include <BrowserNG.rsg>
       
    37 #include "FeedsFeedContainer.h"
       
    38 #include "FeedsFeedView.h"
       
    39 #include "XmlEncoding.h"
       
    40 #include "ApiProvider.h"
       
    41 #include "BrowserSpecialLoadObserver.h"
       
    42 #include "Display.h"
       
    43 #include "BrowserWindowManager.h"
       
    44 #include "BrowserWindow.h"
       
    45 #include "BrowserAppUi.h"
       
    46 #include <FeedAttributes.h>
       
    47 #include <FolderAttributes.h>
       
    48 #include <FeedsEntity.h>
       
    49 
       
    50 #include "eikon.hrh"
       
    51 
       
    52 
       
    53 _LIT(KFeedsSchema, "feeds:");
       
    54 _LIT(KFeedsNavSchema, "feedsnav:");
       
    55 _LIT(KNext, "next");
       
    56 _LIT(KTemplate, "feeds_view_template.html");
       
    57 _LIT(KTokenTitle, "#Title#");
       
    58 _LIT(KTokenWebUrl, "#WebUrl#");
       
    59 _LIT(KTokenDate, "#Date#");
       
    60 _LIT(KTokenDescription, "#Description#");
       
    61 _LIT(KTokenEnclosure, "#Enclosure#");
       
    62 _LIT(KTokenShowPrev, "#ShowPrev#");
       
    63 _LIT(KTokenShowNext, "#ShowNext#");
       
    64 
       
    65 
       
    66 const TInt KDateSize = 30;          // Size of Date strings
       
    67 const TInt KTimeSize = 30;          // Size of Time strings
       
    68 
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CFeedsFeedContainer::NewL
       
    72 //
       
    73 // Two-phased constructor.
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 CFeedsFeedContainer* CFeedsFeedContainer::NewL(CFeedsFeedView* aView,
       
    77             MApiProvider& aApiProvider)
       
    78     {
       
    79     CFeedsFeedContainer* self = new (ELeave) CFeedsFeedContainer(aView, aApiProvider);
       
    80 
       
    81     CleanupStack::PushL(self);
       
    82     self->ConstructL();
       
    83     CleanupStack::Pop();
       
    84 
       
    85     return self;
       
    86     }
       
    87 
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CFeedsFeedContainer::CFeedsFeedContainer
       
    91 //
       
    92 // C++ default constructor.
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 CFeedsFeedContainer::CFeedsFeedContainer(CFeedsFeedView* aView,
       
    96                              MApiProvider& aApiProvider ) :
       
    97     iView( aView ),
       
    98     iApiProvider( aApiProvider ),
       
    99     iBrowserControl(0)
       
   100     {
       
   101     }
       
   102 
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // CFeedsFeedContainer::ConstructL
       
   106 //
       
   107 // Symbian 2nd phase constructor can leave.
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 void CFeedsFeedContainer::ConstructL()
       
   111     {
       
   112     EnsureTemplateL(KTemplate);
       
   113     LoadTemplateL(KTemplate);
       
   114 
       
   115     CreateWindowL();
       
   116     SetMopParent( iView );
       
   117     //SetRect(aRect);
       
   118     ActivateL();
       
   119 
       
   120     TRect rect(Position(), Size());
       
   121 
       
   122     iBrowserControl = CreateBrowserControlL(this, rect,
       
   123             TBrCtlDefs::ECapabilityDisplayScrollBar | TBrCtlDefs::ECapabilityLoadHttpFw,
       
   124             TBrCtlDefs::ECommandIdBase, NULL,  NULL, this, NULL, NULL, NULL, NULL);
       
   125     }
       
   126 
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CFeedsFeedContainer::~CFeedsFeedContainer
       
   130 //
       
   131 // Deconstructor.
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 CFeedsFeedContainer::~CFeedsFeedContainer()
       
   135     {
       
   136     delete iTemplate;
       
   137     delete iNaviPaneTabsGroup;
       
   138     delete iBrowserControl;
       
   139     }
       
   140 
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CFeedsFeedContainer::OfferKeyEventL
       
   144 //
       
   145 // Handles key event.
       
   146 // -----------------------------------------------------------------------------
       
   147 //
       
   148 TKeyResponse CFeedsFeedContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
       
   149     {
       
   150 
       
   151     TKeyResponse  response = EKeyWasConsumed;
       
   152 
       
   153     if (aType == EEventKey)
       
   154         {
       
   155         switch (aKeyEvent.iCode)
       
   156             {
       
   157             case EKeyLeftUpArrow:     // Northwest
       
   158             case EStdKeyDevice10:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   159             case EKeyLeftArrow:       // West
       
   160             case EKeyLeftDownArrow:   // Southwest
       
   161             case EStdKeyDevice13:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   162                     {
       
   163                     ShowPrevItemL();
       
   164                     }
       
   165                 return response;
       
   166 
       
   167             case EKeyRightUpArrow:    // Northeast
       
   168             case EStdKeyDevice11:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   169             case EKeyRightArrow:       // East
       
   170             case EKeyRightDownArrow:  // Southeast
       
   171             case EStdKeyDevice12:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   172                     {
       
   173                     ShowNextItemL();
       
   174                     }
       
   175                 return response;
       
   176 
       
   177             }
       
   178         }
       
   179 
       
   180     response = iBrowserControl->OfferKeyEventL(aKeyEvent, aType);
       
   181 
       
   182     // now "simulate" another key event for proper handling of middle-softkey
       
   183     if ( (aKeyEvent.iScanCode == EStdKeyDevice3) && (aType == EEventKeyDown) )
       
   184         {
       
   185         TKeyEvent keyEvent;
       
   186         keyEvent.iCode = 0xf845;
       
   187         keyEvent.iModifiers = 1;
       
   188         keyEvent.iRepeats = 0;
       
   189         keyEvent.iCode = EKeyDevice3;
       
   190         keyEvent.iScanCode = EStdKeyDevice3;
       
   191         response = iBrowserControl->OfferKeyEventL( keyEvent, EEventKey );
       
   192     }
       
   193     return response;
       
   194     }
       
   195 
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 // CFeedsFeedContainer::GetHelpContext
       
   199 //
       
   200 // Get help context for the control.
       
   201 // -----------------------------------------------------------------------------
       
   202 //
       
   203 #ifdef __SERIES60_HELP
       
   204 void CFeedsFeedContainer::GetHelpContext(TCoeHelpContext& aContext) const
       
   205     {
       
   206     // This must be the Browser's uid becasue the help texts are under Browser topics.
       
   207     aContext.iMajor = KUidBrowserApplication;
       
   208     aContext.iContext = KOSS_HLP_RSS_ARTICLE;
       
   209     }
       
   210 #endif // __SERIES60_HELP
       
   211 
       
   212 
       
   213 // -----------------------------------------------------------------------------
       
   214 // CFeedsFeedContainer::MakeVisible
       
   215 //
       
   216 // Sets this control as visible or invisible.
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 void CFeedsFeedContainer::MakeVisible(TBool aVisible)
       
   220     {
       
   221     if (iBrowserControl)
       
   222         {
       
   223         iBrowserControl->MakeVisible(aVisible);
       
   224         }
       
   225 
       
   226     CCoeControl::MakeVisible(aVisible);
       
   227     }
       
   228 
       
   229 
       
   230 // -----------------------------------------------------------------------------
       
   231 // CFeedsFeedContainer::SizeChanged
       
   232 //
       
   233 // Called by framework when the view size is changed.
       
   234 // -----------------------------------------------------------------------------
       
   235 //
       
   236 void CFeedsFeedContainer::SizeChanged()
       
   237     {
       
   238     if (iBrowserControl)
       
   239         {
       
   240         iBrowserControl->SetRect(Rect());
       
   241         }
       
   242     }
       
   243 
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // CFeedsFeedContainer::HandleResourceChange
       
   247 //
       
   248 // Called by the framework when a display resource changes (i.e. skin or layout).
       
   249 // -----------------------------------------------------------------------------
       
   250 //
       
   251 void CFeedsFeedContainer::HandleResourceChange(TInt aType)
       
   252     {
       
   253     CCoeControl::HandleResourceChange(aType);
       
   254     iBrowserControl->HandleResourceChange(aType);
       
   255 
       
   256     if (aType == KEikDynamicLayoutVariantSwitch)
       
   257         {
       
   258         TRect  rect;
       
   259 
       
   260         if (AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, rect))
       
   261             {
       
   262             SetRect(rect);
       
   263             }
       
   264         }
       
   265     }
       
   266 
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CFeedsFeedContainer::CountComponentControls
       
   270 //
       
   271 // Returns number of components.
       
   272 // -----------------------------------------------------------------------------
       
   273 //
       
   274 TInt CFeedsFeedContainer::CountComponentControls() const
       
   275     {
       
   276     TInt ctrls = 0;
       
   277     if ( iBrowserControl )
       
   278         {
       
   279         ctrls++;// Brctl
       
   280         }
       
   281     return ctrls;
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // CFeedsFeedContainer::NetworkConnectionNeededL
       
   286 //
       
   287 // Request to create a network connection.
       
   288 // -----------------------------------------------------------------------------
       
   289 //
       
   290 void CFeedsFeedContainer::NetworkConnectionNeededL(TInt* aConnectionPtr,
       
   291         TInt* aSockSvrHandle, TBool* aNewConn, TApBearerType* aBearerType)
       
   292     {
       
   293     iApiProvider.SpecialLoadObserver().NetworkConnectionNeededL(aConnectionPtr, aSockSvrHandle,
       
   294             aNewConn, aBearerType);
       
   295     }
       
   296 
       
   297 
       
   298 // -----------------------------------------------------------------------------
       
   299 // CFeedsFeedContainer::HandleRequestL
       
   300 //
       
   301 // Request the host applicaion to handle non-http request.
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 TBool CFeedsFeedContainer::HandleRequestL(RArray<TUint>* aTypeArray, CDesCArrayFlat* aDesArray)
       
   305     {
       
   306     HBufC*  url = NULL;
       
   307     TBool   handled = ETrue;
       
   308 
       
   309     // The 2 arrays must be in sync. Each element in iTypeArray
       
   310     // identifies the type of the corresponding element in iDesArray.
       
   311     if (aTypeArray->Count() != aDesArray->Count())
       
   312         {
       
   313         User::Leave(KErrArgument);
       
   314         }
       
   315 
       
   316     // Get the url.
       
   317     for (TInt i = 0; i < aTypeArray->Count(); i++)
       
   318         {
       
   319         if ((*aTypeArray)[i] == EParamRequestUrl)
       
   320             {
       
   321             url = HBufC::NewLC((*aDesArray)[i].Length());
       
   322             url->Des().Copy((*aDesArray)[i]);
       
   323             break;
       
   324             }
       
   325         }
       
   326 
       
   327     // Leave if the url wasn't found.
       
   328     if (url == NULL)
       
   329         {
       
   330         User::Leave(KErrArgument);
       
   331         }
       
   332 
       
   333     // Handle the "feeds:" schema
       
   334     if (url->Find(KFeedsSchema) == 0)
       
   335         {
       
   336         // Extract the real url from the "feed" url.
       
   337         TPtrC  loadUrl(url->Ptr() + KFeedsSchema().Length(),
       
   338                 url->Length() - KFeedsSchema().Length());
       
   339 
       
   340         // Handle the "feeds_nav:" schema.
       
   341         if (loadUrl.Find(KFeedsNavSchema) == 0)
       
   342             {
       
   343             // Get the direction
       
   344             TPtrC  dir(loadUrl.Ptr() + KFeedsNavSchema().Length(),
       
   345                     loadUrl.Length() - KFeedsNavSchema().Length());
       
   346 
       
   347             if (dir.FindF(KNext) == 0)
       
   348                 {
       
   349                 ShowNextItemL();
       
   350                 }
       
   351             else
       
   352                 {
       
   353                 ShowPrevItemL();
       
   354                 }
       
   355             }
       
   356         else
       
   357             {
       
   358             // Otherwise dispatch the url to the client.
       
   359             iApiProvider.FeedsClientUtilities().LoadUrlL(loadUrl);
       
   360             }
       
   361         }
       
   362     // Otherwise, send request to SchemeHandler through default BrCtlSpecialLoadObserver
       
   363     else
       
   364         {
       
   365         handled = iApiProvider.SpecialLoadObserver().HandleRequestL( aTypeArray, aDesArray );
       
   366         }
       
   367 
       
   368     CleanupStack::PopAndDestroy(url);
       
   369     return handled;
       
   370     }
       
   371 
       
   372 
       
   373 // -----------------------------------------------------------------------------
       
   374 // CFeedsFeedContainer::HandleDownloadL
       
   375 //
       
   376 // Called when the browser control wants the host application (us) to handle
       
   377 // downloaded content
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 TBool CFeedsFeedContainer::HandleDownloadL(RArray<TUint>* aTypeArray,
       
   381         CDesCArrayFlat* aDesArray)
       
   382     {
       
   383     HBufC*  url = NULL;
       
   384     TBool   handled = EFalse;
       
   385 
       
   386     //
       
   387     // Pass first to the main special load observer to be handled.
       
   388     // If it's not handled, continue here
       
   389     //
       
   390     handled = iApiProvider.SpecialLoadObserver().HandleDownloadL( aTypeArray, aDesArray );
       
   391 
       
   392     if (!handled)
       
   393         {
       
   394         // The 2 arrays must be in sync. Each element in iTypeArray
       
   395         // identifies the type of the corresponding element in iDesArray.
       
   396         if (aTypeArray->Count() != aDesArray->Count())
       
   397             {
       
   398             User::Leave(KErrArgument);
       
   399             }
       
   400 
       
   401         // Get the url.
       
   402         for (TInt i = 0; i < aTypeArray->Count(); i++)
       
   403             {
       
   404             if ((*aTypeArray)[i] == EParamRequestUrl)
       
   405                 {
       
   406                 url = HBufC::NewLC((*aDesArray)[i].Length());
       
   407                 url->Des().Copy((*aDesArray)[i]);
       
   408                 break;
       
   409                 }
       
   410             }
       
   411 
       
   412         TPtrC pUrl(url->Des());
       
   413 
       
   414         // Leave if the url wasn't found.
       
   415         if (url == NULL)
       
   416             {
       
   417             User::Leave(KErrArgument);
       
   418             }
       
   419         else
       
   420             {
       
   421             // Otherwise dispatch the url to the client.
       
   422             iApiProvider.FeedsClientUtilities().SubscribeToL(KNullDesC, pUrl);
       
   423             handled = ETrue;
       
   424             }
       
   425 
       
   426         CleanupStack::PopAndDestroy(url);
       
   427         }
       
   428     return handled;
       
   429     }
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CFeedsFeedContainer::ComponentControl
       
   433 //
       
   434 // Returns pointer to particular component.
       
   435 // -----------------------------------------------------------------------------
       
   436 //
       
   437 CCoeControl* CFeedsFeedContainer::ComponentControl(TInt aIndex) const
       
   438     {
       
   439     CCoeControl *ctrl = NULL;
       
   440 
       
   441     switch (aIndex)
       
   442         {
       
   443         case 0:
       
   444             {
       
   445             ctrl = iBrowserControl;
       
   446             break;
       
   447             }
       
   448 
       
   449         default:
       
   450             break;
       
   451         }
       
   452 
       
   453     return ctrl;
       
   454     }
       
   455 
       
   456 
       
   457 // -----------------------------------------------------------------------------
       
   458 // CFeedsFeedContainer::SetCurrentFeedL
       
   459 //
       
   460 // Sets the current feed
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 void CFeedsFeedContainer::SetCurrentFeedL(CFeedsEntity& aFeed, TInt aInitialItem)
       
   464     {
       
   465     iFeed = &aFeed;
       
   466     iCurrentItem = aInitialItem;
       
   467 
       
   468     // Update the view.
       
   469     if (iView->iContainerOnStack)
       
   470         {
       
   471         // Only do this if it's view is active.
       
   472         TPtrC title;
       
   473         iFeed->GetStringValue(EFeedAttributeTitle,title);
       
   474         if (title.Length() > 0)
       
   475             {
       
   476             iApiProvider.Display().SetTitleL( title );
       
   477             }
       
   478         else
       
   479             {
       
   480             iApiProvider.Display().SetTitleL( KNullDesC );
       
   481             }
       
   482         }
       
   483 
       
   484     ShowFeedItemL();
       
   485     }
       
   486 
       
   487 
       
   488 // -----------------------------------------------------------------------------
       
   489 // CFeedsFeedContainer::GetItemUrl
       
   490 //
       
   491 // Returns the current item's url.
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 const TDesC& CFeedsFeedContainer::GetItemUrl()
       
   495     {
       
   496     iFeed->GetChildren()[iCurrentItem]->GetStringValue(EItemAttributeLink,iUrl);
       
   497     return iUrl;
       
   498     }
       
   499 
       
   500 
       
   501 // -----------------------------------------------------------------------------
       
   502 // CFeedsFeedContainer::CurrentItem
       
   503 //
       
   504 // Returns the index of the current item.
       
   505 // -----------------------------------------------------------------------------
       
   506 //
       
   507 TInt CFeedsFeedContainer::CurrentItem()
       
   508     {
       
   509     return iCurrentItem;
       
   510     }
       
   511 
       
   512 // -----------------------------------------------------------------------------
       
   513 // CFeedsFeedContainer::ItemCount
       
   514 //
       
   515 // Returns the number of items.
       
   516 // -----------------------------------------------------------------------------
       
   517 TInt CFeedsFeedContainer::ItemCount() const
       
   518     {
       
   519     return iFeed->GetChildren().Count();
       
   520     }
       
   521 
       
   522 // -----------------------------------------------------------------------------
       
   523 // CFeedsFeedContainer::ShowNextItemL
       
   524 //
       
   525 // Shows the next item if possible.
       
   526 // -----------------------------------------------------------------------------
       
   527 //
       
   528 void CFeedsFeedContainer::ShowNextItemL()
       
   529     {
       
   530     if (iFeed->GetChildren().Count() <= 1)
       
   531         {
       
   532         return;
       
   533         }
       
   534 
       
   535     if ((iCurrentItem + 1) < iFeed->GetChildren().Count())
       
   536         {
       
   537         iCurrentItem++;
       
   538         }
       
   539     else
       
   540         {
       
   541         iCurrentItem = 0;
       
   542         }
       
   543 
       
   544     ShowFeedItemL();
       
   545     }
       
   546 
       
   547 
       
   548 // -----------------------------------------------------------------------------
       
   549 // CFeedsFeedContainer::ShowPrevItemL
       
   550 //
       
   551 // Shows the prev item if possible.
       
   552 // -----------------------------------------------------------------------------
       
   553 //
       
   554 void CFeedsFeedContainer::ShowPrevItemL()
       
   555     {
       
   556     if (iFeed->GetChildren().Count() <= 1)
       
   557         {
       
   558         return;
       
   559         }
       
   560 
       
   561     if ((iCurrentItem - 1) >= 0)
       
   562         {
       
   563         iCurrentItem--;
       
   564         }
       
   565     else
       
   566         {
       
   567         iCurrentItem = iFeed->GetChildren().Count() - 1;
       
   568         }
       
   569 
       
   570     ShowFeedItemL();
       
   571     }
       
   572 
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // CFeedsFeedContainer::Clear
       
   576 //
       
   577 // Clears the navigation pane.
       
   578 // -----------------------------------------------------------------------------
       
   579 //
       
   580 void CFeedsFeedContainer::ClearNavigationPane()
       
   581     {
       
   582     delete iNaviPaneTabsGroup;
       
   583     iNaviPaneTabsGroup = NULL;
       
   584     }
       
   585 
       
   586 
       
   587 // -----------------------------------------------------------------------------
       
   588 // CFeedsFeedContainer::UpdateNavigationPaneL
       
   589 //
       
   590 // Handles the changes needed to the Navigation Pane.
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 void CFeedsFeedContainer::UpdateNavigationPaneL()
       
   594     {
       
   595     const TInt KTabId = 88888;
       
   596     const TInt KMaxNaviText = 25;   // format is "<int>/<int>".
       
   597     _LIT(KFormat, "%d/%d");
       
   598 
       
   599     CAknNavigationControlContainer*  naviPane = NULL;
       
   600     TBuf<KMaxNaviText>               buf;
       
   601     CAknTabGroup*                    tabGroup = NULL;
       
   602     TInt                             itemCount = 0;
       
   603 
       
   604     if (iFeed)
       
   605         {
       
   606         itemCount = iFeed->GetChildren().Count();
       
   607         }
       
   608 
       
   609     // Get the navigation sub-pane.
       
   610     CAknViewAppUi*  appUi;
       
   611     TUid            uid;
       
   612 
       
   613     // Get the title sub-pane.
       
   614     appUi = static_cast<CAknViewAppUi*>(CCoeEnv::Static()->AppUi());
       
   615 
       
   616     uid.iUid = EEikStatusPaneUidNavi;
       
   617 
       
   618     CEikStatusPaneBase::TPaneCapabilities subPane = appUi->StatusPane()->
       
   619             PaneCapabilities(uid);
       
   620 
       
   621     // Set the title if the pane belongs to the app.
       
   622     if (subPane.IsPresent() && subPane.IsAppOwned())
       
   623         {
       
   624         naviPane = (CAknNavigationControlContainer*) appUi->StatusPane()->ControlL(uid);
       
   625         }
       
   626     else
       
   627         {
       
   628         User::Leave(KErrNotSupported);
       
   629         }
       
   630 
       
   631     // Ensure the tab group was created.
       
   632     if (!iNaviPaneTabsGroup)
       
   633         {
       
   634         iNaviPaneTabsGroup = naviPane->CreateTabGroupL();
       
   635         }
       
   636 
       
   637     // Format Navi Pane text "index/count" style.
       
   638     buf.Format(KFormat, iCurrentItem + 1, itemCount);
       
   639 
       
   640     // Update the tab-group.
       
   641     tabGroup = static_cast<CAknTabGroup*>(iNaviPaneTabsGroup->DecoratedControl());
       
   642 
       
   643     // Already created, replacd the tab.
       
   644     if (tabGroup->TabCount() != NULL)
       
   645         {
       
   646         tabGroup->ReplaceTabL(KTabId, buf);
       
   647         }
       
   648 
       
   649     // Otherwise add the tab.
       
   650     else
       
   651         {
       
   652         tabGroup->AddTabL(KTabId, buf);
       
   653         }
       
   654 
       
   655     tabGroup->SetTabFixedWidthL(EAknTabWidthWithOneTab);
       
   656     tabGroup->SetActiveTabById(KTabId);
       
   657 
       
   658     // If not yet pushed, this will do the push; if already there, this brings
       
   659     // it to top and draws.
       
   660     naviPane->PushL(*iNaviPaneTabsGroup);
       
   661     }
       
   662 
       
   663 
       
   664 // -----------------------------------------------------------------------------
       
   665 // CFeedsFeedContainer::ShowFeedItemL
       
   666 //
       
   667 // Shows the given feed item.
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 void CFeedsFeedContainer::ShowFeedItemL()
       
   671     {
       
   672     _LIT(KSchema, "data:");
       
   673     _LIT8(KType, "text/html");
       
   674 
       
   675     const TInt   KInt64Length = 25;
       
   676 
       
   677     HBufC*        link = NULL;
       
   678     HBufC*        htmlTemplate = NULL;
       
   679     HBufC*        enclosureStr = NULL;
       
   680     TDataType     datatype(KType);
       
   681     TUid          uid;
       
   682     CFeedsEntity*  item = iFeed->GetChildren()[iCurrentItem];
       
   683     HBufC*        enclosure = NULL;
       
   684     TInt          enclosureLen = 0;
       
   685 
       
   686     // Mark the item as read.
       
   687     iApiProvider.FeedsClientUtilities().SetItemStatusL(iFeed->GetChildren()[iCurrentItem], EItemStatusRead);
       
   688 
       
   689     // Load the localized strings.
       
   690     enclosureStr = StringLoader::LoadLC(R_FEEDS_ENCLOSURE);
       
   691 
       
   692     // Convert the item's UTC timestamp into a localized string.
       
   693     TBuf<KDateSize + KTimeSize + 1>  timestamp;
       
   694     TBuf<KTimeSize>  temp;
       
   695     TTime ts;
       
   696 
       
   697     item->GetTimeValue(EItemAttributeTimestamp,ts);
       
   698 
       
   699     // Translate from UTC to local time.
       
   700     TTime                 local;
       
   701     TTime                 utc;
       
   702     TTimeIntervalSeconds  delta;
       
   703 
       
   704     local.HomeTime();
       
   705     utc.UniversalTime();
       
   706     utc.SecondsFrom(local, delta);
       
   707     ts -= delta;
       
   708 
       
   709     // Create the localized time string.
       
   710     //Set time
       
   711     HBufC* timeFormat = iEikonEnv->AllocReadResourceLC( R_QTN_TIME_USUAL_WITH_ZERO );
       
   712     ts.FormatL( timestamp, *timeFormat );
       
   713     CleanupStack::PopAndDestroy( timeFormat );//timeFormat
       
   714     //
       
   715     timestamp.Append(_L("  "));
       
   716     //Set date
       
   717     HBufC* dateFormat = iEikonEnv->AllocReadResourceLC( R_QTN_DATE_USUAL_WITH_ZERO );
       
   718     ts.FormatL( temp, *dateFormat );
       
   719     CleanupStack::PopAndDestroy( dateFormat );//dateFormat
       
   720     //
       
   721     timestamp.Append(temp);
       
   722 
       
   723     // Create the enclosure string, which is a a series of the following string.
       
   724     // <div><a href="theUrl">Enclosure[theContentType]: theSize MB</a></div>
       
   725     _LIT(KEnclosureMarkup, "<div><a href=\"%S\">%S[%S MB]: %S</a></div>");
       
   726 
       
   727     TBuf16<KInt64Length>  size;
       
   728     TInt64                sizeInt;
       
   729     TReal64               sizeReal;
       
   730     TRealFormat           format;
       
   731     TPtrC                 url;
       
   732     TPtrC                 contentType;
       
   733     TPtrC                 len;
       
   734     TPtrC                 title;
       
   735     TPtrC                 desc;
       
   736 
       
   737     format.iType = KRealFormatFixed;
       
   738     format.iPlaces = 2;
       
   739 
       
   740     // Determine how large the enclosure string needs to be.
       
   741     for (TInt i = 0; i < item->GetChildren().Count(); i++)
       
   742         {
       
   743         CFeedsEntity* en = item->GetChildren()[i];
       
   744 
       
   745         en->GetStringValue(EEnclosureAttributeContentType,contentType);
       
   746         en->GetStringValue(EEnclosureAttributeSize,len);
       
   747         en->GetStringValue(EEnclosureAttributeLink,url);
       
   748         en->GetStringValue(EEnclosureAttributeTitle,title);
       
   749         TLex16 lex(len);
       
   750         // Convert the enclosure size to mega-bytes.
       
   751         lex.Val(sizeInt);
       
   752         sizeReal = sizeInt / 1000000.0;
       
   753 
       
   754         size.Zero();
       
   755         size.AppendNum(sizeReal, format);
       
   756 
       
   757         enclosureLen += KEnclosureMarkup().Length();
       
   758         enclosureLen += url.Length();
       
   759         enclosureLen += enclosureStr->Length();
       
   760         enclosureLen += size.Length();
       
   761         enclosureLen += contentType.Length();
       
   762         }
       
   763 
       
   764     // Allocate the enclosure string.
       
   765     enclosure = HBufC::NewLC(enclosureLen);
       
   766 
       
   767     // Construct the enclosure string.
       
   768     for (TInt i = 0; i < item->GetChildren().Count(); i++)
       
   769         {
       
   770         CFeedsEntity* en = item->GetChildren()[i];
       
   771 
       
   772         en->GetStringValue(EEnclosureAttributeContentType,contentType);
       
   773         en->GetStringValue(EEnclosureAttributeSize,len);
       
   774         en->GetStringValue(EEnclosureAttributeLink,url);
       
   775         en->GetStringValue(EEnclosureAttributeTitle,title);
       
   776         TLex16             lex(len);
       
   777 
       
   778         // Convert the enclosure size to mega-bytes.
       
   779         lex.Val(sizeInt);
       
   780         sizeReal = sizeInt / 1000000.0;
       
   781 
       
   782         size.Zero();
       
   783         size.AppendNum(sizeReal, format);
       
   784 
       
   785         enclosure->Des().AppendFormat(KEnclosureMarkup, &(url), enclosureStr,
       
   786                 &size, &(contentType));
       
   787         }
       
   788 
       
   789     // Load and prepare the html template.
       
   790     item->GetStringValue(EItemAttributeTitle,title);
       
   791     item->GetStringValue(EItemAttributeDescription,desc);
       
   792     item->GetStringValue(EItemAttributeLink,url);
       
   793 
       
   794     htmlTemplate = ResolveTemplateL(title, timestamp, desc,
       
   795             url, *enclosure);
       
   796 
       
   797 
       
   798     CleanupStack::PushL(htmlTemplate);
       
   799     iFeed->GetStringValue(EFeedAttributeTitle,title);
       
   800     // Load the htmlTemplate in the browser control.
       
   801     uid.iUid = KCharacterSetIdentifierUcs2;
       
   802 
       
   803     link = HBufC::NewLC(KSchema().Length() + title.Length());
       
   804     link->Des().Copy(KSchema);
       
   805     link->Des().Append(title);
       
   806 
       
   807     TPtrC8  ptr((const TUint8*) htmlTemplate->Ptr(), htmlTemplate->Size());
       
   808     iBrowserControl->LoadDataL(*link, ptr, datatype, uid);
       
   809 
       
   810     CleanupStack::PopAndDestroy(link);
       
   811     CleanupStack::PopAndDestroy(htmlTemplate);
       
   812     CleanupStack::PopAndDestroy(enclosure);
       
   813     CleanupStack::PopAndDestroy(enclosureStr);
       
   814 
       
   815     // Update the nav-pane.
       
   816     UpdateNavigationPaneL();
       
   817     }
       
   818 
       
   819 
       
   820 // -----------------------------------------------------------------------------
       
   821 // CFeedsFeedContainer::LoadTemplateL
       
   822 //
       
   823 // Loads the template html file.
       
   824 // -----------------------------------------------------------------------------
       
   825 //
       
   826 void CFeedsFeedContainer::LoadTemplateL(const TDesC& aTemplateName)
       
   827     {
       
   828     RFs                 rfs;
       
   829     RFile               file;
       
   830     TInt                size;
       
   831     TBuf<KMaxFileName>  path;
       
   832     TUint               encoding;
       
   833     HBufC8*             buff;
       
   834     CXmlEncoding*       xmlEncoding = NULL;
       
   835     TInt                loc;
       
   836 
       
   837     // Build the path to the file and open the file.
       
   838     User::LeaveIfError(rfs.Connect());
       
   839     CleanupClosePushL(rfs);
       
   840 
       
   841     path.Append(_L("\\"));
       
   842     path.Append(aTemplateName);
       
   843 
       
   844     User::LeaveIfError(file.Open(rfs, path, EFileRead));
       
   845     CleanupClosePushL(file);
       
   846 
       
   847     // Read the file into the buffer.
       
   848     User::LeaveIfError(file.Size(size));
       
   849 
       
   850     buff = HBufC8::NewL(size);
       
   851     CleanupStack::PushL(buff);
       
   852 
       
   853     TPtr8  ptr((TUint8*) buff->Ptr(), size);
       
   854     User::LeaveIfError(file.Read(ptr, size));
       
   855 
       
   856     // Convert the buffer to ucs2 and clean up.
       
   857     xmlEncoding = CXmlEncoding::NewL();
       
   858     CleanupStack::PushL(xmlEncoding);
       
   859 
       
   860     if (!xmlEncoding->DetermineCharEncodingL(ptr, KNullDesC, encoding))
       
   861         {
       
   862         User::Leave(KErrCorrupt);
       
   863         }
       
   864 
       
   865     iTemplate = xmlEncoding->ConvertToUcs2L(encoding, ptr);
       
   866 
       
   867     CleanupStack::PopAndDestroy(xmlEncoding);
       
   868     CleanupStack::PopAndDestroy(buff);
       
   869     CleanupStack::PopAndDestroy(/*file*/);
       
   870     CleanupStack::PopAndDestroy(/*rfs*/);
       
   871 
       
   872     // Count the number of token.  These counts are used in ResolveTemplate
       
   873     // to determine how big the resolved buffer should be.
       
   874     TPtrC  findPtr;
       
   875 
       
   876     iTitleCount = 0;
       
   877     iWebUrlCount = 0;
       
   878     iDateCount = 0;
       
   879     iDescriptionCount = 0;
       
   880     iEnclosureCount = 0;
       
   881     iShowPrevCount = 0;
       
   882     iShowNextCount = 0;
       
   883 
       
   884     findPtr.Set(*iTemplate);
       
   885     while ((loc = findPtr.Find(KTokenTitle())) != KErrNotFound)
       
   886         {
       
   887         findPtr.Set(findPtr.Mid(loc + KTokenTitle().Length()));
       
   888         iTitleCount++;
       
   889         }
       
   890 
       
   891     findPtr.Set(*iTemplate);
       
   892     while ((loc = findPtr.Find(KTokenWebUrl())) != KErrNotFound)
       
   893         {
       
   894         findPtr.Set(findPtr.Mid(loc + KTokenWebUrl().Length()));
       
   895         iWebUrlCount++;
       
   896         }
       
   897 
       
   898     findPtr.Set(*iTemplate);
       
   899     while ((loc = findPtr.Find(KTokenDate())) != KErrNotFound)
       
   900         {
       
   901         findPtr.Set(findPtr.Mid(loc + KTokenDate().Length()));
       
   902         iDateCount++;
       
   903         }
       
   904 
       
   905     findPtr.Set(*iTemplate);
       
   906     while ((loc = findPtr.Find(KTokenDescription())) != KErrNotFound)
       
   907         {
       
   908         findPtr.Set(findPtr.Mid(loc + KTokenDescription().Length()));
       
   909         iDescriptionCount++;
       
   910         }
       
   911 
       
   912     findPtr.Set(*iTemplate);
       
   913     while ((loc = findPtr.Find((KTokenEnclosure))) != KErrNotFound)
       
   914         {
       
   915         findPtr.Set(findPtr.Mid(loc + KTokenEnclosure().Length()));
       
   916         iEnclosureCount++;
       
   917         }
       
   918 
       
   919     findPtr.Set(*iTemplate);
       
   920     while ((loc = findPtr.Find((KTokenShowPrev))) != KErrNotFound)
       
   921         {
       
   922         findPtr.Set(findPtr.Mid(loc + KTokenShowPrev().Length()));
       
   923         iShowPrevCount++;
       
   924         }
       
   925 
       
   926     findPtr.Set(*iTemplate);
       
   927     while ((loc = findPtr.Find((KTokenShowNext))) != KErrNotFound)
       
   928         {
       
   929         findPtr.Set(findPtr.Mid(loc + KTokenShowNext().Length()));
       
   930         iShowNextCount++;
       
   931         }
       
   932     }
       
   933 
       
   934 
       
   935 // -----------------------------------------------------------------------------
       
   936 // CFeedsFeedContainer::ResolveTemplateL
       
   937 //
       
   938 // Loads and resolves the tokens in the template html file.
       
   939 // -----------------------------------------------------------------------------
       
   940 //
       
   941 HBufC* CFeedsFeedContainer::ResolveTemplateL(const TDesC& aTitle,
       
   942         const TDesC& aTimestamp, const TDesC& aDescription, const TDesC& aUrl,
       
   943         const TDesC& aEnclosure)
       
   944     {
       
   945     HBufC*  ucs2Buff;
       
   946     TInt    loc;
       
   947 
       
   948     // Create and init the resolved buffer.
       
   949     ucs2Buff = HBufC::NewLC(iTemplate->Length() + (aTitle.Length() * iTitleCount) +
       
   950             (aTimestamp.Length() * iDateCount) + (aDescription.Length() * iDescriptionCount) +
       
   951             (aUrl.Length() * iWebUrlCount) +
       
   952             (aEnclosure.Length() * iEnclosureCount) + iShowPrevCount + iShowNextCount);
       
   953 
       
   954     ucs2Buff->Des().Copy(*iTemplate);
       
   955 
       
   956     // Resolve the tokens.
       
   957     TPtr  ucs2Ptr(ucs2Buff->Des());
       
   958 
       
   959     // Replace the title tokens.
       
   960     while ((loc = ucs2Ptr.Find(KTokenTitle())) != KErrNotFound)
       
   961         {
       
   962         ucs2Ptr.Replace(loc, KTokenTitle().Length(), aTitle);
       
   963         }
       
   964 
       
   965     // Replace the url tokens.
       
   966     while ((loc = ucs2Ptr.Find(KTokenWebUrl())) != KErrNotFound)
       
   967         {
       
   968         ucs2Ptr.Replace(loc, KTokenWebUrl().Length(), aUrl);
       
   969         }
       
   970 
       
   971     // Replace the date tokens.
       
   972     while ((loc = ucs2Ptr.Find(KTokenDate())) != KErrNotFound)
       
   973         {
       
   974         ucs2Ptr.Replace(loc, KTokenDate().Length(), aTimestamp);
       
   975         }
       
   976 
       
   977     // Replace the description tokens.
       
   978     while ((loc = ucs2Ptr.Find(KTokenDescription())) != KErrNotFound)
       
   979         {
       
   980         ucs2Ptr.Replace(loc, KTokenDescription().Length(), aDescription);
       
   981         }
       
   982 
       
   983     // Replace the enclosure tokens.
       
   984     while ((loc = ucs2Ptr.Find(KTokenEnclosure())) != KErrNotFound)
       
   985         {
       
   986         ucs2Ptr.Replace(loc, KTokenEnclosure().Length(), aEnclosure);
       
   987         }
       
   988 
       
   989     CleanupStack::Pop(ucs2Buff);
       
   990     return ucs2Buff;
       
   991     }
       
   992 
       
   993 
       
   994 // -----------------------------------------------------------------------------
       
   995 // CFeedsFeedContainer::EnsureTemplateL
       
   996 //
       
   997 // If need be copy the template from ROM.
       
   998 // -----------------------------------------------------------------------------
       
   999 //
       
  1000 void CFeedsFeedContainer::EnsureTemplateL(const TDesC& aName)
       
  1001     {
       
  1002     TInt                err;
       
  1003     RFs                 defaultRfs;
       
  1004     TUint               attValue = 0;
       
  1005     TBuf<KMaxFileName>  path;
       
  1006 
       
  1007     // Open a connection to the working drive.
       
  1008     User::LeaveIfError(defaultRfs.Connect());
       
  1009     CleanupClosePushL(defaultRfs);
       
  1010     User::LeaveIfError(defaultRfs.SetSessionPath(_L("c:\\")));
       
  1011 
       
  1012     // Build the path to the file.
       
  1013     path.Append(_L("\\"));
       
  1014     path.Append(aName);
       
  1015 
       
  1016     // Test whether or not the folder file is present.
       
  1017     err = defaultRfs.Att(path, attValue);
       
  1018 
       
  1019     // The file is there, just return.
       
  1020     if (err == KErrNone)
       
  1021         {
       
  1022         CleanupStack::PopAndDestroy(/*defaultRfs*/);
       
  1023         return;
       
  1024         }
       
  1025 
       
  1026     // If the file is missing copy it from ROM.
       
  1027     if ((err == KErrNotFound) || (err == KErrPathNotFound))
       
  1028         {
       
  1029         RFs      romRfs;
       
  1030         RFile    file;
       
  1031         RFile    romFile;
       
  1032         TInt     size;
       
  1033         HBufC8*  buffer = NULL;
       
  1034 
       
  1035         // Open an rfs for the z drive.
       
  1036         User::LeaveIfError(romRfs.Connect());
       
  1037         CleanupClosePushL(romRfs);
       
  1038         User::LeaveIfError(romRfs.SetSessionPath(_L("z:\\")));
       
  1039 
       
  1040         // Create the destination file.
       
  1041         User::LeaveIfError(file.Create(defaultRfs, path, EFileWrite));
       
  1042         CleanupClosePushL(file);
       
  1043 
       
  1044         // Open the source file.
       
  1045         User::LeaveIfError(romFile.Open(romRfs, path, EFileRead));
       
  1046         CleanupClosePushL(romFile);
       
  1047 
       
  1048         // Copy the file.
       
  1049         User::LeaveIfError(romFile.Size(size));
       
  1050         buffer = HBufC8::NewLC(size);
       
  1051         TPtr8 bufferPtr(buffer->Des());
       
  1052 
       
  1053         User::LeaveIfError(romFile.Read(bufferPtr, size));
       
  1054         User::LeaveIfError(file.Write(bufferPtr, size));
       
  1055 
       
  1056         // Clean up
       
  1057         CleanupStack::PopAndDestroy(buffer);
       
  1058         CleanupStack::PopAndDestroy(/*romFile*/);
       
  1059         CleanupStack::PopAndDestroy(/*file*/);
       
  1060         CleanupStack::PopAndDestroy(/*romRfs*/);
       
  1061         CleanupStack::PopAndDestroy(/*defaultRfs*/);
       
  1062         }
       
  1063     }
       
  1064 
       
  1065 // ---------------------------------------------------------
       
  1066 // CFeedsFeedContainer::ExtractBrCtlParam()
       
  1067 // ---------------------------------------------------------
       
  1068 //
       
  1069 TPtrC CFeedsFeedContainer::ExtractBrCtlParam
       
  1070     ( TUint aParamTypeToFind,
       
  1071       RArray<TUint>* aTypeArray,
       
  1072       CDesCArrayFlat* aDesArray,
       
  1073       TBool& aParamFound ) const
       
  1074     {
       
  1075     // initialize output parameter
       
  1076     aParamFound = EFalse;
       
  1077     TPtrC16 retParamValue;
       
  1078 
       
  1079     for ( TInt j = 0; j < aTypeArray->Count(); j++ )
       
  1080         {
       
  1081         const TUint paramType = (*aTypeArray)[j];
       
  1082         if ( aParamTypeToFind == paramType )
       
  1083             {
       
  1084             // That's we need
       
  1085             retParamValue.Set( aDesArray->MdcaPoint(j) );
       
  1086             aParamFound = ETrue; // Indicate it in the out param
       
  1087             break; // break the loop - we found it
       
  1088             }
       
  1089         }
       
  1090     return retParamValue;
       
  1091     }