diff -r 6385c4c93049 -r 8e6fa1719340 browserui/browser/FeedsSrc/FeedsClientUtilities.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserui/browser/FeedsSrc/FeedsClientUtilities.cpp Wed Sep 01 12:31:04 2010 +0100 @@ -0,0 +1,1873 @@ +/* +* Copyright (c) 2005-2007 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: Manages the feed related views and implements the FeedsViewBridge. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "Browser.hrh" +#include "BrowserAppUi.h" +#include "CommonConstants.h" +#include "BrowserWindow.h" +#include "BrowserWindowManager.h" +#include "BrowserUIVariant.hrh" +#include "Preferences.h" +#include "BrowserGotoPane.h" +#include "BrowserAdaptiveListPopup.h" +#include "FeedsFeedView.h" +#include "FeedsFolderView.h" +#include "BrowserDialogs.h" +#include "FeedsTopicView.h" +#include "BrowserUtil.h" +#include "BrowserSpecialLoadObserver.h" + +#include "FeedsClientUtilities.h" + +#include "BrowserBmOTABinSender.h" + +// CONSTANTS +_LIT(KSupportedMimeTypes, "application/rss+xml;application/atom+xml;text/xml;application/xml"); +const TInt KLastUpdateGranularity = 10; + +const TInt KWmlSettingsAutomaticUpdatingNotSet = 32767; + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::NewL +// +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CFeedsClientUtilities* CFeedsClientUtilities::NewL(CAknViewAppUi& aAppUI, MApiProvider& aApiProvider) + { + CFeedsClientUtilities* self = new (ELeave) CFeedsClientUtilities(aAppUI, aApiProvider); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::CFeedsClientUtilities +// +// C++ default constructor. +// ----------------------------------------------------------------------------- +// +CFeedsClientUtilities::CFeedsClientUtilities(CAknViewAppUi& aAppUI, MApiProvider& aApiProvider): + iAppUI(aAppUI), iApiProvider(aApiProvider), iIsUpdatingFeed(EFalse), iWaitDialog(0), + iEnteredURL(0), iFolderView(0), iTopicView(0), iFeedView(0), + iIsConnected(EFalse), iItemIds(20), iItemStatus(20), iMimeTypes(0), + iFeedUpdateTimeIds(KLastUpdateGranularity), iFeedUpdateTimeTimestamps(KLastUpdateGranularity), + iPendingFolderItemTitle(NULL), iPendingFolderItemUrl(NULL), iExportFileName(NULL), + iSearchAgent(NULL), + iSearchOptList(NULL), + iFeedImportRequested(EFalse), + iRequestCanceled(EFalse), + iIsWaitDialogDisplayed(EFalse), + iFeedsInterface(*this,0), + iCanceledRequest(CTransaction::ENone) + { + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ConstructL +// +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ConstructL() + { + iApiProvider.Preferences().AddObserverL( this ); + + // Set up MimeTypes + iMimeTypes = HBufC::NewL( KSupportedMimeTypes().Length() + 1 ); + TPtr ptr( iMimeTypes->Des() ); + ptr.Append( KSupportedMimeTypes() ); + ptr.ZeroTerminate(); + + iWaitDialog = CFeedsWaitDialog::NewL(*this); + } + +// ----------------------------------------------------------------------------- +// CFolderItem::Search +// +// Searches for a FolderItem with the given name. If "this" +// isn't a folder it only checks whether or not it matches +// the given name. If "this" is a folder it also checks +// all embedded items. +// ----------------------------------------------------------------------------- +// +const CFeedsEntity* CFeedsClientUtilities::Search(const TDesC& aName,const CFeedsEntity& aFolder) const + { + TPtrC title; + if (aFolder.GetType() == EFolder) + { + aFolder.GetStringValue(EFolderAttributeTitle,title); + } + else + { + aFolder.GetStringValue(EFeedAttributeTitle,title); + } + if (aName.CompareF(title) == 0) + { + return &aFolder; + } + if (aFolder.GetType() == EFolder) + { + for(TInt i=0;iGetStatusCode(); + +switch (aTrans->Type()) + { + case CTransaction::EFetchRootFolderItem: + FolderItemRequestCompleted(status, CTransaction::EFetchRootFolderItem); + + break; + + case CTransaction::EWatchForChanges: + break; + + case CTransaction::EExportOPML: + case CTransaction::EImportOPML: + FolderItemRequestCompleted(status, aTrans->Type()); + break; + + case CTransaction::EAddFolderItem: + case CTransaction::EDeleteFolderItem: + case CTransaction::EChangeFolderItem: + case CTransaction::EMoveFolderItem: + case CTransaction::EMoveFolderItemTo: + case CTransaction::EUpdateFolderItem: + FolderItemRequestCompleted(status, aTrans->Type()); + break; + + case CTransaction::EChangeSettings: + break; + + case CTransaction::EFetchFeed: + FeedRequestCompleted(status); + break; + case CTransaction::EUpdateItemStatus: + break; + + default: + FolderItemRequestCompleted(status, aTrans->Type()); + break; + } +} + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::NetworkConnectionNeededL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::NetworkConnectionNeededL( + TInt* aConnectionPtr, TInt& aSockSvrHandle, + TBool& aNewConn, TApBearerType& aBearerType ) + { + iApiProvider.SpecialLoadObserver().NetworkConnectionNeededL( + aConnectionPtr, &aSockSvrHandle, &aNewConn, &aBearerType ); + //Wait dialog is shown only in the case of a new connection. + if ( aNewConn ) + { + iWaitDialog->ShowWaitDialogL(R_FEEDS_UPDATING_FEED); + iIsWaitDialogDisplayed = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::HandlePreferencesChangeL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::HandlePreferencesChangeL( + const TPreferencesEvent aEvent, + TPreferencesValues& aValues, + TBrCtlDefs::TBrCtlSettings aSettingType ) + { + // no specific TBrCtlDefs::TBrCtlSettings are defined for FeedsSettings + // so we trigger for an Unknown setting + if( (EPreferencesItemChange == aEvent || EPreferencesDeactivate == aEvent) && + (TBrCtlDefs::ESettingsUnknown == aSettingType ) ) + { + SetPreferencesToFeedL( aValues ); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SetPreferencesToFeedL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SetPreferencesToFeedL( const TPreferencesValues& aValues ) + { + if ( iIsWaitDialogDisplayed ) + { + return; + } + TFeedsServerSetting setting; + + // always set to 32767 in the case of feed level auto updating. + //setting.iAutoUpdate = KWmlSettingsAutomaticUpdatingNotSet; + setting.iAutoUpdate = EFalse; + setting.iAutoUpdateFreq = KWmlSettingsAutomaticUpdatingNotSet; + setting.iAutoUpdateWhileRoaming = aValues.iAutomaticUpdatingWhileRoaming; + + TUint32 autoUpdatingAP( 0 ); +#ifndef __WINSCW__ + if (aValues.iAutomaticUpdatingAP != KWmlNoDefaultAccessPoint) + { + autoUpdatingAP = Util::IapIdFromWapIdL( iApiProvider, aValues.iAutomaticUpdatingAP ); + } +#endif //__WINSCW__ + setting.iAutoUpdateAP = autoUpdatingAP; + + SetFeedsServerSettingsL( setting ); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::DisconnectManualUpdateConnectionL() +// +// Disconnect connection provided by client for manual update. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::DisconnectManualUpdateConnectionL() + { + if ( iIsConnected ) + { + // Ensure that the connection is available. + ConnectToServerL(EFalse); + + // Pass the updated settings to the server. + iFeedsInterface.DisconnectManualUpdateConnectionL(); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::DisconnectFeedsViewL() +// +// Disconnect connection used by FeedsView. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::DisconnectFeedsViewL() + { + if( iFeedView ) + { + iFeedView->DisconnectL(); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::LoadUrlL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::LoadUrlL( const TDesC& aUrl ) + { + + if( iApiProvider.IsPageLoaded() && + iApiProvider.Preferences().UiLocalFeatureSupported( KBrowserMultipleWindows ) && + !iApiProvider.Preferences().UiLocalFeatureSupported( KBrowserMinimalMultipleWindows )) + { + // there is already a window, so create a new one if not over the max number of windows allowed + if(iApiProvider.WindowMgr().WindowCount() == iApiProvider.WindowMgr().MaxWindowCount()) + { + // Show warning to user + TBrowserDialogs::ErrorNoteL( R_BROWSER_NOTE_MAX_WINDOWS ); + return; + } + + if(iApiProvider.WindowMgr().WindowCount() < iApiProvider.WindowMgr().MaxWindowCount()) + { + CBrowserWindow *win = iApiProvider.WindowMgr().CreateWindowL( 0, &KNullDesC ); + if (win != NULL) + { + CleanupStack::PushL( win ); + iApiProvider.WindowMgr().SwitchWindowL( win->WindowId() ); + CleanupStack::Pop(); // win + } + } + } + + iApiProvider.WindowMgr().CurrentWindow()->SetHasFeedsContent(ETrue); + iApiProvider.FetchL( aUrl ); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ShowFolderViewL +// +// Shows the folder view, loading the folder list from the FeedsServer if need be. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ShowFolderViewL(TUid aCalledFromView /*= KUidBrowserBookmarksViewId*/) + { + + if ( iIsWaitDialogDisplayed ) + { + return; + } + // Record the view from which feeds was launched. + // If this function is not called with an argument, + // its default value "KUidBrowserBookmarksViewId" is used. + // This is specified in the header FeedsClientUtilities.h + SetCalledFromView(aCalledFromView); + + // Ensure that "this" is ready for uses. + LazyInitL(EFalse); + + // Show wait dialog. + iWaitDialog->ShowWaitDialogL(R_FEEDS_OPENING_FEED); + iIsWaitDialogDisplayed = ETrue; + + // Set the view to show once the folder is ready. + iNextViewId = KUidBrowserFeedsFolderViewId; + iIsUpdatingFeed = EFalse; + + // Get the root folder. + FetchRootFolderL(); + iCurrentRequest = CTransaction::EFetchRootFolderItem; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ShowTopicViewL +// +// Shows the topic view, loading the given feed associated with the given folder item. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ShowTopicViewL(const CFeedsEntity& aFolderItem) + { + TTime timestamp; + + if ( iIsWaitDialogDisplayed ) + { + return; + } + + // Ensure that "this" is ready for uses. + LazyInitL(EFalse); + + // Show wait dialog. + timestamp = aFolderItem.GetTimeValue(EFeedAttributeTimestamp,timestamp); + if ( timestamp.Int64() == 0 ) + { + if ( iApiProvider.Connection().Connected() ) + { + iWaitDialog->ShowWaitDialogL(R_FEEDS_UPDATING_FEED); + } + } + else + { + iWaitDialog->ShowWaitDialogL(R_FEEDS_OPENING_FEED); + } + iIsWaitDialogDisplayed = ETrue; + + // Set the view to show once the feed is ready. + iNextViewId = KUidBrowserFeedsTopicViewId; + iIsUpdatingFeed = EFalse; + + // Fetch the feed. + FetchFeedL(aFolderItem); + iCurrentRequest = CTransaction::EFetchFeed; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SupportedMimeTypesL +// +// Returns the feed related mime-types supported by the bridge. This makes +// for a clean way to pass downloaded feeds content from the client to the FeedsServer +// (via CFeedsClientUtilities::HandleFeedL). +// ----------------------------------------------------------------------------- +// +TPtrC CFeedsClientUtilities::SupportedMimeTypesL() + { + return iMimeTypes->Des(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SubscribeToL +// +// Shows the folder view and subscribes to the given feed. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SubscribeToL(const TDesC& aTitle, const TDesC& aUrl) + { + SetCalledFromView(KUidBrowserContentViewId); + + // If the root folder is available then Add the feed. + if (iFeedsInterface.RootFolder() != NULL) + { + // Ensure that "this" is ready for uses. + LazyInitL( EFalse ); + CFeedsMap* temp = CFeedsMap::NewL(); + temp->SetStringAttribute(EFeedAttributeTitle,aTitle); + temp->SetStringAttribute(EFeedAttributeLink,aUrl); + temp->SetIntegerAttribute(EFeedAttributeAutoUpdateFreq,0); + + // Set the next view to show after the new add folder item is added. + iNextViewId = KUidBrowserFeedsFolderViewId; + + iFeedsInterface.AddL(EFeed,*temp, *(iFeedsInterface.RootFolder())); + + delete temp; + // Ensure the Folder View shows the root-folder when AddFolderItemL completes. + iFolderView->SetCurrentFolder(*(iFeedsInterface.RootFolder()), ETrue); + } + + // Otherwise queue the folder item until the root folder is fetched (see above). + else + { + // Ensure that "this" is ready for uses. ETrue is passed to ensure that + // the root folder will be fetched if it isn't already available. + LazyInitL( ETrue ); + + delete iPendingFolderItemTitle; + iPendingFolderItemTitle = NULL; + delete iPendingFolderItemUrl; + iPendingFolderItemUrl = NULL; + + iPendingFolderItemTitle = aTitle.AllocL(); + TRAPD(err, iPendingFolderItemUrl = aUrl.AllocL()); + if (err != KErrNone) + { + delete iPendingFolderItemTitle; + iPendingFolderItemTitle = NULL; + + User::Leave(err); + } + } + } + + + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FeedsServerSettings +// +// Returns Feeds Server related settings. +// ----------------------------------------------------------------------------- +// +TInt CFeedsClientUtilities::FeedsServerSettingsL(TFeedsServerSetting& aSetting) + { + // Ensure that the connection is available. + ConnectToServerL(EFalse); + + return iFeedsInterface.GetSettingsL(aSetting); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SetFeedsServerSettings +// +// Sets Feeds Server related settings. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SetFeedsServerSettingsL(const TFeedsServerSetting& aNewSetting) + { + // Ensure that the connection is available. + ConnectToServerL(EFalse); + + // Pass the updated settings to the server. + iFeedsInterface.SetSettingsL(aNewSetting); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SetBrowserControlSettingL +// +// Sets a Browser Control related settings. These settings are directly passed to all +// Browser Control instances used by the CFeedsViewBridge. As such see the Browser +// Control documentation for infomation about the settings. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SetBrowserControlSettingL(TUint aSetting, TUint aValue) + { + // Pass the setting to the Feed View's Browser Control. + iApiProvider.BrCtlInterface().SetBrowserSettingL(aSetting, aValue); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FolderItemRequestCompleted +// +// Called by RequestHandlerCompleted when the root FolderItem is either ready +// or an error occured. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::FolderItemRequestCompleted(TInt aStatus, CTransaction::TTransactionType aTransType/*=ENone*/) + { + TRAP_IGNORE( FolderItemRequestCompletedL(aStatus, aTransType) ); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FolderItemRequestCompletedL +// +// Called by FolderItemRequestCompleted. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::FolderItemRequestCompletedL(TInt aStatus, CTransaction::TTransactionType aTransType/*=ENone*/) + { + if (aTransType == iCanceledRequest) + { + iCanceledRequest = CTransaction::ENone; + return; + } + + iWaitDialog->Close(); + + iIsWaitDialogDisplayed = EFalse; + + // Show the view if everything went ok. + if (aStatus == KErrNone) + { + switch(aTransType) + { + case CTransaction::EExportOPML: + //launch send ui + SendOPMLFileL(); + break; + + case CTransaction::EImportOPML: + // Delete temp file here if it exists + if(iTempOPMLImportFilePath.Length() > 0) + { + RFs tempRFs; + if (tempRFs.Connect() != KErrNone) + { + break; + } + CleanupClosePushL(tempRFs); + tempRFs.Delete( iTempOPMLImportFilePath ); + tempRFs.Close(); + CleanupStack::PopAndDestroy(); // cleanup tempRFs and reset temp file import path + iTempOPMLImportFilePath = _L(""); + } + + // Again show folder view to trigger a redraw + ShowFolderViewL(); + break; + + default: + // if an import OPML was requested, do that now + if(iFeedImportRequested) + { + // clear flag + iFeedImportRequested = EFalse; + + // show wait dialog + iWaitDialog->ShowWaitDialogL(R_FEEDS_WAIT_IMPORTING_FEEDS); + iIsWaitDialogDisplayed = ETrue; + + + if(iTempOPMLImportFilePath.Length()) + { + iFeedsInterface.ImportOPMLL( iTempOPMLImportFilePath ); + } + iCurrentRequest = CTransaction::EImportOPML; + } + + // Set the updated folder + iFolderView->RootFolderChangedL(*(iFeedsInterface.RootFolder())); + + // Show it. + if (iNextViewId == KUidBrowserFeedsFolderViewId) + { + ShowFolderViewLocalL(); + } + + // If the user tried to subscribe to a feed before it was connected + // to the server then add the item now. + if (iPendingFolderItemTitle != NULL) + { + TRAPD(err, SubscribeToL(*iPendingFolderItemTitle, *iPendingFolderItemUrl)); + if (err == KErrNone) + { + delete iPendingFolderItemTitle; + iPendingFolderItemTitle = NULL; + delete iPendingFolderItemUrl; + iPendingFolderItemUrl = NULL; + } + // Don't reset next-view; iNextViewId is EFolderViewId after above SubscribeToL() call + + // Otherwise try to add the folder item next time. + } + else if(iNextViewId == KUidBrowserFeedsFolderViewId) + { + // Reset next-view. + iNextViewId = KUidBrowserNullViewId; + } + + // Reset the "last updated" cache now that a new folder list is available. + ResetFeedUpdateTime(); + } + } + // Otherwise show an error. + else + { + // If the server terminated, reconnect to it. + if (aStatus == KErrServerTerminated) + { + DisconnectFromServer(); + ConnectToServerL(); + + } + + ShowServerError(aStatus, aTransType); + + // This happens when user subscribe to a feed from content view + // If it failed, we want to show the content view. + if (aStatus == KErrAlreadyExists) + { + // Set content view as the last view id. + iApiProvider.SetLastActiveViewId( KUidBrowserContentViewId ); + + // Show the view. + // We already started switching to the feeds folder view and shut off full screen + // This will force the DoActivate on the ContentView and set back to full screen + iApiProvider.SetViewToBeActivatedIfNeededL( KUidBrowserFeedsFolderViewId ); + iApiProvider.SetViewToBeActivatedIfNeededL( KUidBrowserContentViewId ); + } + + // Reset next-view. + iNextViewId = KUidBrowserNullViewId; + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FeedRequestCompleted +// +// Called when the asynchronous request is complete. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::FeedRequestCompleted(TInt aEvent) + { + TRAP_IGNORE( FeedRequestCompletedL(aEvent) ); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FeedRequestCompletedL +// +// Called when the asynchronous request is complete. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::FeedRequestCompletedL(TInt aStatus) + { + if (CTransaction::EFetchFeed == iCanceledRequest) + { + iCanceledRequest = CTransaction::ENone; + return; + } + // Close the wait dialog. + iWaitDialog->Close(); + iIsWaitDialogDisplayed = EFalse; + + // Show the view if everything went ok. + if (aStatus == KErrNone) + { + // Extract out the intial item status -- later on, iItemStatusOrig is + // used to determine which item status' change. + RArray ignore(20); + + iItemIds.Reset(); + iItemStatus.Reset(); + iItemStatusOrig.Reset(); + + CleanupClosePushL(ignore); + ItemStatusL(iItemIds, iItemStatus, *(iFeedsInterface.Feed())); + ItemStatusL(ignore, iItemStatusOrig, *(iFeedsInterface.Feed())); + CleanupStack::PopAndDestroy(/*ignore*/); + + // update folder view for unread count + TInt unreadCount = 0; + for (TInt i = 0; i < iItemStatus.Count(); i++) + { + if ( iItemStatus[i] == EItemStatusUnread || iItemStatus[i] == EItemStatusNew ) + { + unreadCount++; + } + } + iFolderView->SetUnreadCountL( unreadCount ); + + // The method was called because of a updated feed. In general, update + // the current view to reflect the updated feed. + if (iIsUpdatingFeed) + { + if (iApiProvider.LastActiveViewId() == KUidBrowserFeedsTopicViewId) + { + iTopicView->SetCurrentFeedL(*(CurrentFeed()), 0); + } + } + + // Otherwise, this is a newly requested feed, so show the next + // view now that it is available. + else + { + if (iNextViewId == KUidBrowserFeedsFeedViewId) + { + ShowFeedViewLocalL(0); + } + else if (iNextViewId == KUidBrowserFeedsTopicViewId) + { + ShowTopicViewLocalL(0); + } + } + + // Update the feed's "last updated" value in the cache. + UpdateFeedUpdatedTimeL(*(iFeedsInterface.Feed())); + } + + // Otherwise show an error. + else + { + // If the server terminated, reconnect to it. + if (aStatus == KErrServerTerminated) + { + DisconnectFromServer(); + ConnectToServerL(); + + } + + ShowServerError(aStatus); + } + + // Reset updating feed. + iIsUpdatingFeed = EFalse; + + // Reset next-view. + iNextViewId = KUidBrowserNullViewId; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::DialogDismissedL +// +// Called when the user presses the cancel button. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::DialogDismissedL() + { + // Cancel all activities that can be cancelled. + iIsWaitDialogDisplayed = EFalse; + + + // If there is an ongoing search by the search agent, make sure + // it's cancelled and search agent destroyed + if(iSearchAgent != NULL) + { + iSearchAgent->CancelSearch(); + delete(iSearchAgent); + iSearchAgent = NULL; + } + else + { + iCanceledRequest = iCurrentRequest; + iFeedsInterface.CancelAllL(); + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FetchRootFolderL +// +// Get the root folder from the Feeds server. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::FetchRootFolderL() + { + iFeedsInterface.GetRootFolderL(); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::AddFolderItemL +// +// Add a new folder item. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::AddFolderItemL(const TDesC& aTitle, const TDesC& aUrl, + TBool aIsFolder, const CFeedsEntity& aParent, TInt aFreq) + { + + CFeedsMap* temp = CFeedsMap::NewL(); + + temp->SetStringAttribute(EFeedAttributeTitle,aTitle); + temp->SetStringAttribute(EFeedAttributeLink,aUrl); + temp->SetIntegerAttribute(EFeedAttributeAutoUpdateFreq,aFreq); + + // Set the next view to show after the new add folder item is added. + iNextViewId = KUidBrowserFeedsFolderViewId; + + iFeedsInterface.AddL(aIsFolder?EFolder:EFeed,*temp, aParent); + + delete temp; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ChangeFolderItemL +// +// Change the folder item. If this is a folder then KNullDesC should be passed +// to the aUrl argument. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ChangeFolderItemL(CFeedsEntity& aFolderItem, + const TDesC& aTitle, const TDesC& aUrl,TInt aFreq) + { + CFeedsMap* temp = CFeedsMap::NewL(); + temp->SetStringAttribute(EFeedAttributeTitle,aTitle); + temp->SetStringAttribute(EFeedAttributeLink,aUrl); + temp->SetIntegerAttribute(EFeedAttributeAutoUpdateFreq,aFreq); + // Set the next view to show after the new add folder item is added. + iNextViewId = KUidBrowserFeedsFolderViewId; + + aFolderItem.ChangeValueL(*temp); + delete temp; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::DeleteFolderItemsL +// +// Delete the folder items. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::DeleteFolderItemsL(RPointerArray& aFolderItems) + { + iFeedsInterface.DeleteL(aFolderItems); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::MoveFolderItemsToL +// +// Move the folder items to a different parent. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::MoveFolderItemsToL(RPointerArray& aFolderItems, + const CFeedsEntity& aParent) + { + iFeedsInterface.MoveToFolderL(aFolderItems, aParent); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::MoveFolderItemsL +// +// Move the folder item to a different index. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::MoveFolderItemsL(RPointerArray& aFolderItems, + TInt aIndex) + { + iFeedsInterface.MoveL(aFolderItems, aIndex); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FetchFeedL +// +// Get the given feed from the Feeds server. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::FetchFeedL(const CFeedsEntity& aFeedEntity, TBool aForceUpdate, + TBool aNoCache) + { + // Fetch the new feed. + iFeedsInterface.FetchL(aFeedEntity, aForceUpdate, aNoCache); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::UpdateFeedL +// +// Updates the feed with the given id. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::UpdateFeedL(const CFeedsEntity& aFeedEntity) + { + if(iIsWaitDialogDisplayed) + { + return; + } + // Show wait dialog iff connection is already established. + if(iApiProvider.Connection().Connected()) + { + iWaitDialog->ShowWaitDialogL(R_FEEDS_UPDATING_FEED); + iIsWaitDialogDisplayed = ETrue; + } + + iIsUpdatingFeed = ETrue; + + // Fetch the feed. + FetchFeedL(aFeedEntity, ETrue); + iCurrentRequest = CTransaction::EFetchFeed; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::UpdateFolderItemsL +// +// Updates the given feeds in the background. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::UpdateFolderItemsL(const RPointerArray& + aFolderItems) + { + if (iIsWaitDialogDisplayed) + { + return; + } + // Show wait dialog iff connection is already established. + if (iApiProvider.Connection().Connected()) + { + iWaitDialog->ShowWaitDialogL(R_FEEDS_UPDATING_FEED); + iIsWaitDialogDisplayed = ETrue; + } + + // Fetch the feeds. + iFeedsInterface.UpdateL(aFolderItems); + iCurrentRequest = CTransaction::EUpdateFolderItem; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::UpdateFolderItemsL +// +// Updates all of feeds in the background. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::UpdateFolderItemsL() + { + if (iIsWaitDialogDisplayed) + { + return; + } + + // Show wait dialog iff connection is already established. + if (iApiProvider.Connection().Connected()) + { + iWaitDialog->ShowWaitDialogL(R_FEEDS_UPDATING_ALL_WAIT_DIALOG); + iIsWaitDialogDisplayed = ETrue; + } + + // Fetch the feeds. + RPointerArray aFolderItem; + aFolderItem.Append((iFeedsInterface.RootFolder())); + + iFeedsInterface.UpdateL(aFolderItem); + iCurrentRequest = CTransaction::EUpdateFolderItem; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ImportFeeds +// +// Import feeds from OPML file +// ----------------------------------------------------------------------------- +// + +void CFeedsClientUtilities::ImportFeedsL() + { + if (iIsWaitDialogDisplayed) + { + return; + } + + // construct search agent + if(NULL != iSearchAgent) + { + delete(iSearchAgent); + iSearchAgent = NULL; + } + iSearchAgent = CFeedsFileSearchAgent::NewL(*this); + + iWaitDialog->ShowWaitDialogL(R_FEEDS_WAIT_SEARCHING_FOR_FEEDS); + iIsWaitDialogDisplayed = ETrue; + + // Start search + if(NULL != iSearchAgent) + { + iSearchAgent->StartSearchingL(); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FeedsFileSearchCompleteL +// +// Implemented from the MFeedsFileSearchAgentCallback mixin, this +// callback is called when the search for files in the filesystem has completed +// ----------------------------------------------------------------------------- +// + +void CFeedsClientUtilities::FeedsFileSearchCompleteL(TInt aCount) + { + TFileEntry * fileEntry; + TInt i; + + iWaitDialog->Close(); + iIsWaitDialogDisplayed = EFalse; + + // If nothing is found, indicate that, cleanup and quit + if(aCount == 0) + { + HBufC* note = StringLoader::LoadLC(R_FEEDS_NO_FEEDS_FOUND_ON_DEVICE); + iApiProvider.DialogsProvider().DialogAlertL(_L(""),*note); + CleanupStack::PopAndDestroy( note ); + } + else + { + // + // construct results dialog box to show search results + // + if(NULL != iSearchOptList) + { + delete(iSearchOptList); + iSearchOptList = NULL; + } + + iSearchOptList = new( ELeave ) CArrayFixFlat(aCount); + + HBufC* title = StringLoader::LoadLC(R_FEEDS_POPUP_TITLE_FEEDS_FILES_FOUND); + + // loop through the search results + for(i = 0; i < aCount; i++) + { + if(iSearchAgent) + { + // grab file found from the search agent results and add it + // as an option + fileEntry = iSearchAgent->GetFileEntry(i); + if(NULL != fileEntry) + { + TBrCtlSelectOptionData t(fileEntry->iEntry.iName, EFalse, EFalse, EFalse); + iSearchOptList->AppendL(t); + } + } + } + + TBool ret(iApiProvider.DialogsProvider().DialogSelectOptionL( *title, + ESelectTypeNone, *iSearchOptList)); + + CleanupStack::PopAndDestroy(title); + + // + // If the user selects an option, import it + // + if ( ret ) + { + for( i = 0; i < aCount; i++) + { + if( (*iSearchOptList)[i].IsSelected() ) + { + if(iSearchAgent) + { + fileEntry = iSearchAgent->GetFileEntry(i); + if(NULL != fileEntry) + { + BeginImportOPMLFeedsFileL(fileEntry->iPath); + } + } + break; + } + } + } + + } + + // destroy the search agent + delete(iSearchAgent); + iSearchAgent = NULL; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::BeginImportOPMLFeedsFileL +// +// Given a path, save it in the class, show the root folder view and set +// a flag to indicate we're importing. When the root folder is done opening, +// then begin the actual import +// ----------------------------------------------------------------------------- +// + +void CFeedsClientUtilities::BeginImportOPMLFeedsFileL( TFileName& aFilepath ) + { + // save path + iTempOPMLImportFilePath = aFilepath; + + // Switch to feeds view, setting the flag will import + // from the tempOPMLImportFilePath when the view is ready + iFeedImportRequested = ETrue; + ShowFolderViewL(); + + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ExportFeeds +// +// Export feeds to OPML file +// ----------------------------------------------------------------------------- +// + +void CFeedsClientUtilities::ExportFeedsL(RPointerArray& aFolderItems, const TDesC &aExportFileName) + { + if (iIsWaitDialogDisplayed) + { + return; + } + + iWaitDialog->ShowWaitDialogL(R_FEEDS_WAIT_PROCESSING); + iIsWaitDialogDisplayed = ETrue; + + if (iExportFileName) + { + delete iExportFileName; + iExportFileName = NULL; + } + + iExportFileName = aExportFileName.AllocL(); + iFeedsInterface.ExportFoldersL(aFolderItems, aExportFileName); + iCurrentRequest = CTransaction::EExportOPML; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ShowFolderViewLocalL +// +// Shows the folder view. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ShowFolderViewLocalL() + { + // Set this as the last view id -- this is used in ShowLastViewL. + iApiProvider.SetLastActiveViewId(KUidBrowserFeedsFolderViewId); + + // Show the view. + iApiProvider.SetViewToBeActivatedIfNeededL(KUidBrowserFeedsFolderViewId); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ShowTopicViewLocalL +// +// Shows the topic view. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ShowTopicViewLocalL(TInt aInitialItem) + { + // Set this as the last view id -- this is used in ShowLastViewL. + iApiProvider.SetLastActiveViewId(KUidBrowserFeedsTopicViewId); + + // Set the inital item. + if (iTopicView == NULL) + { + TRect rect(iAppUI.ClientRect()); + iTopicView = CFeedsTopicView::NewL( iApiProvider, rect ); + iAppUI.AddViewL( iTopicView ); // transfer ownership to CAknViewAppUi + } + + iTopicView->SetInitialItem(aInitialItem); + + // Show the view. + iApiProvider.SetViewToBeActivatedIfNeededL(KUidBrowserFeedsTopicViewId); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ShowFeedViewLocalL +// +// Shows the feed view. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ShowFeedViewLocalL(TInt aInitialItem) + { + // Set this as the last view id -- this is used in ShowLastViewL. + iApiProvider.SetLastActiveViewId(KUidBrowserFeedsFeedViewId); + + // Set the inital item. + if (iFeedView == NULL) + { + TRect rect(iAppUI.ClientRect()); + iFeedView = CFeedsFeedView::NewL( iApiProvider, rect ); + iAppUI.AddViewL( iFeedView ); // transfer ownership to CAknViewAppUi + } + + iFeedView->SetInitialItem(aInitialItem); + + // Show the view. + iApiProvider.SetViewToBeActivatedIfNeededL(KUidBrowserFeedsFeedViewId); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::CurrentRootFolder +// +// Returns the current root folder. +// ----------------------------------------------------------------------------- +// +const CFeedsEntity* CFeedsClientUtilities::CurrentRootFolder() + { + return iFeedsInterface.RootFolder(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::CurrentFeed +// +// Returns the current feed. +// ----------------------------------------------------------------------------- +// +CFeedsEntity* CFeedsClientUtilities::CurrentFeed() + { + return iFeedsInterface.Feed(); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::AddItemL +// +// Add a menu item to the given menu. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::AddItemL(CEikMenuPane& aMenuPane, TInt aCommand, + TInt aTitleId) + { + CEikMenuPaneItem::SData item; + HBufC* buf = NULL; + + buf = StringLoader::LoadLC(aTitleId); + item.iText.Copy(*buf); + CleanupStack::PopAndDestroy(buf); + buf = NULL; + + item.iCommandId = aCommand; + item.iFlags = 0; + item.iCascadeId = 0; + aMenuPane.AddMenuItemL(item); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::AddCascadeL +// +// Add a sub-menu to the given menu. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::AddCascadeL(CEikMenuPane& aMenuPane, TInt aCommand, + TInt aTitleId, TInt aCascade) + { + CEikMenuPaneItem::SData item; + HBufC* buf = NULL; + + buf = StringLoader::LoadLC(aTitleId); + item.iText.Copy(*buf); + CleanupStack::PopAndDestroy(buf); + buf = NULL; + + item.iCommandId = aCommand; + item.iFlags = 0; + item.iCascadeId = aCascade; + aMenuPane.AddMenuItemL(item); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SetItemStatus +// +// Sets the item's status (read/unread/new). +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SetItemStatusL(CFeedsEntity* aItem, TFeedItemStatus aStatus) + { + TInt ret; + CFeedsMap* temp = CFeedsMap::NewL(); + temp->SetIntegerAttribute(EItemAttributeStatus,aStatus); + ret = aItem->ChangeValueL(*temp); + delete temp; + + if (ret != KErrNone) + { + ShowServerError(ret); + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ItemStatus +// +// Returns the item's status (read/unread/new). +// ----------------------------------------------------------------------------- +// +TFeedItemStatus CFeedsClientUtilities::ItemStatus(TInt aItemId) + { + TInt pos; + TFeedItemStatus status = EItemStatusUndefined; + + if ((pos = iItemIds.Find(aItemId)) != KErrNotFound) + { + status = iItemStatus[pos]; + } + else + { + // TODO: panic + } + + return status; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ItemStatusWriteToServerL +// +// Writes the item status out to the server. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ItemStatusWriteToServerL() + { + RArray ids(20); + RArray status(20); + TInt unreadCountDelta = 0; + TInt unreadCount = 0; + + if (iItemStatus.Count() == 0) + { + return; + } + + CleanupClosePushL(ids); + CleanupClosePushL(status); + + // Build new status arrays that only contains items that changed. + for (TInt i = 0; i < iItemStatus.Count(); i++) + { + if (iItemStatus[i] != iItemStatusOrig[i]) + { + // update orig, since the old orig doesn't hold true any more + // important to do so: + // because this method will be called whenever deactivateView of FeedsView is called + iItemStatusOrig[i] = iItemStatus[i]; + + ids.AppendL(iItemIds[i]); + status.AppendL(iItemStatus[i]); + + // In current UI, status can only change from New -> Read, or Unread -> Read + if ( iItemStatus[i] == EItemStatusRead ) + { + unreadCountDelta--; + } + } + } + + // update folder view + unreadCount = iFolderView->UnreadCountChangedL( unreadCountDelta ); + + // Write the item status out to the server. + iFeedsInterface.UpdateFeedItemStatusL(ids, status, unreadCount); + CleanupStack::PopAndDestroy(/*status*/); + CleanupStack::PopAndDestroy(/*ids*/); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FaviconL +// +// Returns the Favicon to the given url or NULL if one isn't found. +// ----------------------------------------------------------------------------- +// +CGulIcon* CFeedsClientUtilities::FaviconL(const TDesC& aUrl) + { + CGulIcon* icon = NULL; + + // TODO: Do this if access to the database is too slow. + // First search the local cache. + + // If not found extract it from the Feeds View's Browser Control and add + // it to the local cache. + + // Get the favicon from the Browser Control. + icon = iApiProvider.WindowMgr().CurrentWindow()->BrCtlInterface().GetBitmapData(aUrl, TBrCtlDefs::EBitmapFavicon); + if (icon != NULL) + { + icon->SetMask(NULL); + } + + return icon; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::LazyInitL +// +// Ensures that the views and the connection to the FeedsServer are ready. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::LazyInitL(TBool aGetRootFolder) + { + // Create Views + if(iFolderView == NULL) + { + TRect rect(iAppUI.ClientRect()); + iFolderView = CFeedsFolderView::NewL( iApiProvider, rect ); + iAppUI.AddViewL( iFolderView ); // transfer ownership to CAknViewAppUi + } + + + + // Connect to the server. + ConnectToServerL(aGetRootFolder); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ShowServerError +// +// Show a server error. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ShowServerError(TInt aStatus, CTransaction::TTransactionType aRequestType/*=ENone*/) + { + TInt labelId; + + // Determine which label to use. + switch(aStatus) + { + case KErrNoMemory: + labelId = R_FEEDS_OUT_OF_MEMORY; + break; + // Few errors wont be shown as pop up dialog as they will appear in list box main pane + case KErrCorrupt: + // A pop up error note should be displayed if import is requested, + // else error will be displayed in main pane itself + if (aRequestType == CTransaction::EImportOPML) + { + labelId = R_FEEDS_MALFORMED_FEED_ERROR; + break; + } + case KErrNotSupported: + case KErrTimedOut: + case KErrBadName: + return; + + case -KErrNotSupported: + // Show the special http not supported on WINSCW error + TRAP_IGNORE(TBrowserDialogs::InfoNoteL(R_BROWSER_INFO_NOTE, R_FEEDS_HTTP_UNSUPPORTED_WINSCW)); + return; + + case KErrAlreadyExists: + labelId = R_FEEDS_NAME_ALREADY_IN_USE; + break; + + + case KErrArgument: + // A pop up error note should be displayed if import is requested, + // else error will be displayed in main pane itself + if (aRequestType == CTransaction::EImportOPML) + { + labelId = R_FEEDS_MALFORMED_FEED_ERROR; + break; + } + + case KErrNotFound: + // A pop up error note should be displayed if import is requested, + // else will be handled in default case. + if (aRequestType == CTransaction::EImportOPML) + { + labelId = R_FEEDS_FILE_NOT_FOUND_ERROR; + break; + } + default: + if (aStatus > 0) // All network errors + { + // Error will shown in listbox main pane + return; + } + + // Otherwise. + else + { + labelId = R_FEEDS_GENERAL_ERROR; + } + break; + } + + // Show the error dialog. + if (aStatus != KErrCancel) + { + TRAP_IGNORE(TBrowserDialogs::InfoNoteL(R_BROWSER_INFO_NOTE, labelId)); + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ConnectToServerL +// +// Connect to the server. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ConnectToServerL(TBool aGetRootFolder) + { + if (!iIsConnected) + { + User::LeaveIfError(iFeedsInterface.Connect()); + iIsConnected = ETrue; + } + + if (aGetRootFolder) + { + // Set this to no-view so the folder view isn't shown after it's fetched. + iNextViewId = KUidBrowserNullViewId; + + FetchRootFolderL(); + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::DisconnectFromServer +// +// Disconnect from the server. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::DisconnectFromServer() + { + if( !iIsConnected ) + { + //Nothing connected, return, this is causing crash. + return; + } + iFeedsInterface.Close(); + + iIsConnected = EFalse; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::FeedUpdatedTime +// +// Since the folder list isn't updated after it is fetched the FeedsClientUtilities +// tracks the last update times for feeds the user visits in the current session. +// This method returns the "last updated" timestamp of the given item. +// ----------------------------------------------------------------------------- +// +TTime CFeedsClientUtilities::FeedUpdatedTime(const CFeedsEntity& aItem) + { + TTime timestamp; + TInt pos; + + + // Search the cache for the feed's url. + if ((pos = iFeedUpdateTimeIds.Find(aItem.GetId())) != KErrNotFound) + { + timestamp = iFeedUpdateTimeTimestamps[pos]; + } + + // Otherwise return the item's timestamp. + else + { + aItem.GetTimeValue(EFeedAttributeTimestamp,timestamp); + } + + // Return the cached value. + return timestamp; + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ResetFeedUpdateTime +// +// Resets the "last updated" cache. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ResetFeedUpdateTime() + { + // Reset the arrays. + iFeedUpdateTimeIds.Reset(); + iFeedUpdateTimeTimestamps.Reset(); + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::UpdateFeedUpdatedTimeL +// +// Update the feed's "last updated" value in the cache. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::UpdateFeedUpdatedTimeL(const CFeedsEntity& aFeed) + { + TInt pos; + TInt err; + + // TODO: Use the feed's id instead of the url. This would require the + // packed folder to store the feed id as well. + + // Search the cache for the feed's url and if found then update the timestamp. + if ((pos = iFeedUpdateTimeIds.Find(aFeed.GetId())) != KErrNotFound) + { + TTime time; + aFeed.GetTimeValue(EFeedAttributeTimestamp,time); + iFeedUpdateTimeTimestamps[pos] = time; + } + + // Otherwise add a new slot. + else + { + User::LeaveIfError(iFeedUpdateTimeIds.Append(aFeed.GetId())); + TTime time; + aFeed.GetTimeValue(EFeedAttributeTimestamp,time); + + err = iFeedUpdateTimeTimestamps.Append(time); + + // Ensure the arrays don't get out of sync if the second append fails. + if (err != KErrNone) + { + iFeedUpdateTimeIds.Remove(iFeedUpdateTimeIds.Count() - 1); + User::LeaveIfError(err); + } + } + } + + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::InitMenuItemL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::InitMenuItemL( CEikMenuPane* aMenuPane, + TInt aCommandId, + TInt aResourceId, + TInt aCascadeId, + TInt aFlags ) + { + CEikMenuPaneItem::SData item; + item.iCommandId = aCommandId; + item.iFlags = aFlags; + item.iCascadeId = aCascadeId; + HBufC* buf = StringLoader::LoadLC( aResourceId ); + item.iText.Copy( *buf ); + CleanupStack::PopAndDestroy( buf ); // buf + buf = NULL; + + aMenuPane->AddMenuItemL( item ); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SendOPMLFileL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SendOPMLFileL( ) + { + RFs rfs; + + _LIT(KPath, "C:\\system\\temp\\"); + TBuf path(KPath); + + User::LeaveIfError(rfs.Connect()); + CleanupClosePushL(rfs); + + path.Append(*iExportFileName); + + MBmOTABinSender& sender = iApiProvider.BmOTABinSenderL(); + + sender.ResetAndDestroy(); + sender.SendOPMLFileL(path); + + CleanupStack::PopAndDestroy(/*rfs*/); + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::HandleCommandL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::HandleCommandL( TUid aViewId, TInt aCommand ) + { + switch (aCommand) + { + case EWmlCmdBackToPage: + { + iApiProvider.SetViewToReturnOnClose( aViewId ); + iApiProvider.SetViewToBeActivatedIfNeededL( KUidBrowserContentViewId ); + break; + } + + case EFeedsImport: + ImportFeedsL(); + break; + + default: + // pass common commands to app ui + iAppUI.HandleCommandL( aCommand ); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::DynInitMenuPaneL() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::DynInitMenuPaneL( + TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + + // Option menu items common to all three feeds views + if ((aResourceId == R_FEEDS_FOLDER_VIEW_MENU) || + (aResourceId == R_FEEDS_FEED_VIEW_MENU) || + (aResourceId == R_FEEDS_TOPIC_VIEW_MENU)) + { + // browser prefs + InitMenuItemL( aMenuPane, EWmlCmdPreferences, R_WMLBROWSER_SETTINGS_TITLE ); + + // Help + InitMenuItemL( aMenuPane, EAknCmdHelp, R_BROWSER_MENU_ITEM_HELP, R_FEEDS_HELP_SUBMENU ); + + // exit + InitMenuItemL( aMenuPane, EWmlCmdUserExit, R_BROWSER_MENU_ITEM_EXIT ); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::SetCalledFromView() +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::SetCalledFromView(TUid aViewId) + { + iCalledFromView = aViewId; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::CalledFromView() +// ----------------------------------------------------------------------------- +// +TUid CFeedsClientUtilities::CalledFromView() + { + return iCalledFromView; + } + +// ----------------------------------------------------------------------------- +// CFeedsClientUtilities::ItemStatusL +// +// Returns the INITIAL status of each of the items in the feed. +// The caller can then modify the values and call UpdateFeedItemStatusL +// to request the feeds server to update the feed's item status. +// ----------------------------------------------------------------------------- +// +void CFeedsClientUtilities::ItemStatusL(RArray& aItemIds, + RArray& aItemStatus, const CFeedsEntity& aFeed) const + { + TInt status; + + aItemIds.Reset(); + aItemStatus.Reset(); + + for(TInt index=0 ; index< aFeed.GetChildren().Count() ; index++) + { + CFeedsEntity *feedEntity = aFeed.GetChildren()[index]; + + feedEntity->GetIntegerValue(EItemAttributeStatus,status); + + User::LeaveIfError(aItemIds.Append(feedEntity->GetId())); + User::LeaveIfError(aItemStatus.Append((TFeedItemStatus)status)); + } + }