# HG changeset patch # User Sebastian Brannstrom # Date 1289656476 0 # Node ID 9c56bf58569693440f0d33bdbb29ef8bac2c12cb # Parent 1cae65a87b5e1e7a34e60c53679fdcbfc05fe03e Catching up with 5th edition diff -r 1cae65a87b5e -r 9c56bf585696 application/data/PodcastClient_common.rls --- a/application/data/PodcastClient_common.rls Sat Oct 23 17:30:22 2010 +0100 +++ b/application/data/PodcastClient_common.rls Sat Nov 13 13:54:36 2010 +0000 @@ -23,4 +23,4 @@ rls_string STRING_r_caption "Podcatcher" rls_string STRING_r_short_caption "Podcatcher" -rls_string STRING_r_about_text_s60 "Podcatcher 0.90(%d)\n© 2007-2010 Sebastian Brannstrom, Lars Persson, Anders Fridlund, EmbedDev AB" +rls_string STRING_r_about_text_s60 "Podcatcher 1.00(%d)\n© 2007-2010 Sebastian Brannstrom, Lars Persson, Anders Fridlund, EmbedDev AB" diff -r 1cae65a87b5e -r 9c56bf585696 application/data/PodcastClient_spanish.rls --- a/application/data/PodcastClient_spanish.rls Sat Oct 23 17:30:22 2010 +0100 +++ b/application/data/PodcastClient_spanish.rls Sat Nov 13 13:54:36 2010 +0000 @@ -1,3 +1,4 @@ +CHARACTER_SET UTF8 /* * Copyright (c) 2007-2010 Sebastian Brannstrom, Lars Persson, EmbedDev AB * @@ -30,7 +31,7 @@ // CBA buttons rls_string STRING_r_cba_options "Opciones" -rls_string STRING_r_cba_hide "Occultar" +rls_string STRING_r_cba_hide "Ocultar" rls_string STRING_r_cba_cancel "Cancelar" // Tab titles @@ -39,22 +40,22 @@ rls_string STRING_r_tabgroup_queue_counter "(%d) Cola" // Question dialogs -rls_string STRING_r_add_feed_prompt "Introduzca términos de búsqueda o dirección de la fuente" -rls_string STRING_r_edit_feed_prompt "Dirección de la fuente" -rls_string STRING_r_add_feed_title_prompt "Título de la fuente" -rls_string STRING_r_remove_feed_prompt "¿Borrar fuente '%S'?" -rls_string STRING_r_enable_downloads_prompt "Hay capítulos en la cola de descarga. ¿Quieres descargarlos ahora?" -rls_string STRING_r_update_new_feed_prompt "¿Quieres actualizar la fuente ahora?" -rls_string STRING_r_delete_show_prompt "¿Borrar el capítulo '%S'?" -rls_string STRING_r_podcast_connection_error "Fallo de conexión. Compruebe que la configuración de red es correcta." -rls_string STRING_r_exit_shows_downloading "Hay capítulos descargando. ¿Quiere salir?" +rls_string STRING_r_add_feed_prompt "Introduzca términos de búsqueda o dirección de la fuente" +rls_string STRING_r_edit_feed_prompt "Dirección de la fuente" +rls_string STRING_r_add_feed_title_prompt "Título de la fuente" +rls_string STRING_r_remove_feed_prompt "¿Borrar fuente '%S'?" +rls_string STRING_r_enable_downloads_prompt "Hay capítulos en la cola de descarga. ¿Quieres descargarlos ahora?" +rls_string STRING_r_update_new_feed_prompt "¿Quieres actualizar la fuente ahora?" +rls_string STRING_r_delete_show_prompt "¿Borrar el capítulo '%S'?" +rls_string STRING_r_podcast_connection_error "Fallo de conexión. Compruebe que la configuración de red es correcta." +rls_string STRING_r_exit_shows_downloading "Hay capítulos descargando. ¿Quiere salir?" // Settings view -rls_string STRING_r_podcast_settings_title "Configuración" +rls_string STRING_r_podcast_settings_title "Configuración" rls_string STRING_r_podcast_setting_showdir "Carpeta de Podcast" -rls_string STRING_r_podcast_setting_autoupdate "Actualización automática" -rls_string STRING_r_podcast_setting_autodownload "Descarga automática" -rls_string STRING_r_podcast_setting_connection "Conexión" +rls_string STRING_r_podcast_setting_autoupdate "Actualización automática" +rls_string STRING_r_podcast_setting_autodownload "Descarga automática" +rls_string STRING_r_podcast_setting_connection "Conexión" rls_string STRING_r_podcast_setting_default "Usar predeterminada" rls_string STRING_r_podcast_setting_alwaysask "Preguntar siempre" rls_string STRING_r_podcast_setting_useiap "Seleccion el punto de acceso" @@ -64,46 +65,46 @@ rls_string STRING_r_on "Activar" rls_string STRING_r_off "Desactivar" rls_string STRING_r_podcast_setting_reset_db "Reiniciar libreria" -rls_string STRING_r_podcast_setting_reset_db_query "¿Reiniciar Libreria? Toda la información será borrada!" +rls_string STRING_r_podcast_setting_reset_db_query "¿Reiniciar Libreria? Toda la información será borrada!" // Choicelist for autodownload rls_string STRING_podcast_autoupdate_option1 "Desactivado" rls_string STRING_podcast_autoupdate_option2 "Cada hora" -rls_string STRING_podcast_autoupdate_option3 "Cuatro veces al día" -rls_string STRING_podcast_autoupdate_option4 "Dos veces al día" -rls_string STRING_podcast_autoupdate_option5 "Cada día" +rls_string STRING_podcast_autoupdate_option3 "Cuatro veces al día" +rls_string STRING_podcast_autoupdate_option4 "Dos veces al día" +rls_string STRING_podcast_autoupdate_option5 "Cada día" // Feed import/export rls_string STRING_r_view_import_feeds_title "Seleccione el fichero OPML" rls_string STRING_r_enter_filename "Nombre de Fichero" rls_string STRING_r_view_export_feeds_title "Seleccione carpeta" rls_string STRING_r_view_export_feeds_softkey "Seleccionar" -rls_string STRING_import_feed_success "%d fuentes importadas. ¿Quiere actualizar todas las fuentes ahora?" -rls_string STRING_import_feed_failure "Improtación de fuente fallida" +rls_string STRING_import_feed_success "%d fuentes importadas. ¿Quiere actualizar todas las fuentes ahora?" +rls_string STRING_import_feed_failure "Improtación de fuente fallida" rls_string STRING_export_feed_success "%d fuentes exportadas" -rls_string STRING_export_feed_failure "Exportación de fuente fallida" +rls_string STRING_export_feed_failure "Exportación de fuente fallida" rls_string STRING_r_importing "Importando" rls_string STRING_r_exporting "Exportando" // Listbox empty strings rls_string STRING_r_podcast_empty_queue "(cola vacia)" -rls_string STRING_r_podcast_empty_list "(no hay capítulos)" +rls_string STRING_r_podcast_empty_list "(no hay capítulos)" rls_string STRING_r_podcast_no_feeds "(no hay fuentes)" rls_string STRING_r_podcast_empty_search "(no hay resultados)" rls_string STRING_r_podcast_empty_list_updating "(actualizando...)" // Feed view -rls_string STRING_r_add_feed_title "Añadir fuente" +rls_string STRING_r_add_feed_title "Añadir fuente" rls_string STRING_r_edit_feed_title "Editar fuente" -rls_string STRING_r_cancel_update_all_feeds_cmd "Cancelar actualización" +rls_string STRING_r_cancel_update_all_feeds_cmd "Cancelar actualización" rls_string STRING_r_cancel_update_all_feeds_short_cmd "Cancelar" rls_string STRING_r_podcast_feeds_status_format "%d nuevo(s)" rls_string STRING_r_podcast_shows_never_updated "Nunca fue actualizado" -rls_string STRING_r_view_add_feed_cmd "Añadir fuente" -rls_string STRING_r_view_add_feed_cmd_short "Añadir" +rls_string STRING_r_view_add_feed_cmd "Añadir fuente" +rls_string STRING_r_view_add_feed_cmd_short "Añadir" rls_string STRING_r_view_edit_feed_cmd "Editar fuente" rls_string STRING_r_view_edit_feed_cmd_short "Editar" rls_string STRING_r_view_delete_feed_cmd "Borrar fuente" @@ -115,17 +116,17 @@ rls_string STRING_r_podcast_feeds_is_updating "Actualizando..." // Add/edit feed -rls_string STRING_add_feed_query "¿Añadir fuente '%S'?" -rls_string STRING_add_feed_success "Fuente añadida. Actualizar ahora?" -rls_string STRING_add_feed_error "No pude añadir fuente" -rls_string STRING_r_add_feed_replace "Todos los capítulos disponibles seran borrados! ¿Desea continuar?" // shown when changing an existing feed URL -rls_string STRING_r_add_feed_exists "La dirección propuesta esta usada por otra fuente" // shown when adding or changing a feed to a URL that already exists +rls_string STRING_add_feed_query "¿Añadir fuente '%S'?" +rls_string STRING_add_feed_success "Fuente añadida. Actualizar ahora?" +rls_string STRING_add_feed_error "No pude añadir fuente" +rls_string STRING_r_add_feed_replace "Todos los capítulos disponibles seran borrados! ¿Desea continuar?" // shown when changing an existing feed URL +rls_string STRING_r_add_feed_exists "La dirección propuesta esta usada por otra fuente" // shown when adding or changing a feed to a URL that already exists // Feed searching rls_string STRING_r_search_noresults "No hay resultados" rls_string STRING_r_searching "Buscando" -rls_string STRING_r_search_results "Resulstados de la búsqueda" +rls_string STRING_r_search_results "Resulstados de la búsqueda" // Show view @@ -133,8 +134,8 @@ rls_string STRING_r_view_mark_as_unplayed_cmd_short "Marcar nuevo (*)" rls_string STRING_r_view_download_show_cmd "Descargar" rls_string STRING_r_view_delete_show_cmd "Borrar" -rls_string STRING_r_view_show_info_cmd "Información (#)" -rls_string STRING_r_error_playback_failed "No se pudo reproducir el capítulo" +rls_string STRING_r_view_show_info_cmd "Información (#)" +rls_string STRING_r_error_playback_failed "No se pudo reproducir el capítulo" // Download queue operations rls_string STRING_r_suspend_download_cmd "Suspender" @@ -143,7 +144,7 @@ rls_string STRING_r_view_resume_downloads_cmd "Continuar la descarga" rls_string STRING_r_view_remove_all_downloads_cmd_short "Borrar" rls_string STRING_r_view_remove_all_downloads_cmd "Borrar la cola de descarga" -rls_string STRING_r_clear_query "¿Quiere borrar la cola?" +rls_string STRING_r_clear_query "¿Quiere borrar la cola?" rls_string STRING_r_view_remove_download_short_cmd "Borrar" rls_string STRING_r_view_remove_download_cmd "Borrar descarga" @@ -151,12 +152,15 @@ rls_string STRING_r_view_move_down_short_cmd "Move down" rls_string STRING_r_error_notfound "Error: Servidor no fue hallado" -rls_string STRING_r_error_invalid_address "Error: La conexión fallo" +rls_string STRING_r_error_invalid_address "Error: La conexión fallo" rls_string STRING_r_error_general "Error: Error general %d" rls_string STRING_r_error_http "Error: error HTTP %d" rls_string STRING_r_error_disk_full "Error: No espacio en el disco" - -rls_string STRING_r_view_feed_feed_menu "Manage feeds" +rls_string STRING_r_add_url_or_search "Add feed" +rls_string STRING_r_add_url "Enter URL" +rls_string STRING_r_add_search "Search for feed" +rls_string STRING_r_search_feed_prompt "Enter search terms:" +rls_string STRING_r_view_feed_feed_menu "Administrar fuentes" rls_string STRING_r_view_shows_show_menu "Show" rls_string STRING_r_view_queue_show_menu "Queue" diff -r 1cae65a87b5e -r 9c56bf585696 application/data/PodcastQueueView.ra --- a/application/data/PodcastQueueView.ra Sat Oct 23 17:30:22 2010 +0100 +++ b/application/data/PodcastQueueView.ra Sat Nov 13 13:54:36 2010 +0000 @@ -19,7 +19,7 @@ RESOURCE AVKON_VIEW r_podcast_queueview { menubar = r_podcast_queueview_menubar; - cba = R_AVKON_SOFTKEYS_OPTIONS_BACK; + cba = r_podcast_cba; } RESOURCE MENU_BAR r_podcast_queueview_menubar diff -r 1cae65a87b5e -r 9c56bf585696 application/inc/PodcastFeedView.h --- a/application/inc/PodcastFeedView.h Sat Oct 23 17:30:22 2010 +0100 +++ b/application/inc/PodcastFeedView.h Sat Nov 13 13:54:36 2010 +0000 @@ -39,9 +39,13 @@ static CPodcastFeedView* NewLC(CPodcastModel& aPodcastModel); ~CPodcastFeedView(); void UpdateItemL(TInt aIndex); + void UpdateItemsComplete(); void CheckResumeDownloadL(); TBool ViewingShows(); - + + void CheckConfirmExit(); + void ShowItem(TUint aUid); + protected: void ConstructL(); CPodcastFeedView(CPodcastModel& aPodcastModel); @@ -112,10 +116,11 @@ void HandleUpdateFeedL(); void GetFeedErrorText(TDes &aErrorMessage, TInt aErrorCode); void OpmlParsingCompleteL(TInt aError, TUint aNumFeedsImported); - + void LoadIcons(); + void DisplayFeedInfoDialogL(); private: CPodcastModel& iPodcastModel; - TBool iUpdatingRunning; + TUint iFeedUpdating; HBufC* iFeedsFormat; HBufC* iNeverUpdated; CPodcastFeedViewUpdater* iUpdater; @@ -123,6 +128,7 @@ TOpmlState iOpmlState; TBool iViewingShows; RArray iFeedIdForIconArray; + TBool iListingFirstTime; }; #endif // PODCASTFEEDVIEWH diff -r 1cae65a87b5e -r 9c56bf585696 application/inc/PodcastListView.h --- a/application/inc/PodcastListView.h Sat Oct 23 17:30:22 2010 +0100 +++ b/application/inc/PodcastListView.h Sat Nov 13 13:54:36 2010 +0000 @@ -31,13 +31,10 @@ class CEikFormattedCellListBox; -class MKeyEventListener { +class MContainerListener { public: virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) = 0; -}; - -class MPointerListener { -public: +virtual void SizeChanged() = 0; virtual void PointerEventL(const TPointerEvent& aPointerEvent) = 0; }; @@ -52,29 +49,32 @@ CCoeControl* ComponentControl( TInt aIndex ) const; void HandleResourceChange(TInt aType); virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType); - void SetKeyEventListener(MKeyEventListener *aKeyEventListener); - void SetPointerListener(MPointerListener *aPointerListener); - + void SetContainerListener(MContainerListener *aContainerListener); + void SetListboxObserver(MEikListBoxObserver *aObserver); CEikFormattedCellListBox* Listbox(); + void SetListboxIcons(CArrayPtr< CGulIcon >* aIcons); + CArrayPtr* ListboxIcons(); + void SetListboxTextArrays(CDesCArray* aPortraitArray, CDesCArray* aLandscapeArray); + void SetEmptyText(const TDesC &aText); void ScrollToVisible(); void Draw(const TRect& aRect) const; - - CEikFormattedCellListBox * iListbox; protected: TTypeUid::Ptr MopSupplyObject( TTypeUid aId ); virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent); private: - MKeyEventListener* iKeyEventListener; - MPointerListener* iPointerListener; + CEikFormattedCellListBox * iListbox; + MContainerListener* iContainerListener; + CAknsBasicBackgroundControlContext* iBgContext; }; -class CPodcastListView : public CAknView, public MPointerListener, -public MProgressDialogCallback, public MKeyEventListener +class CPodcastListView : public CAknView, public MContainerListener, +public MEikListBoxObserver, +public MProgressDialogCallback { public: ~CPodcastListView(); @@ -133,6 +133,8 @@ // from MKeyEventListener virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType); + virtual void SizeChanged() {}; + void ResetContainer(); // from MPointerListener void PointerEventL(const TPointerEvent& aPointerEvent); diff -r 1cae65a87b5e -r 9c56bf585696 application/inc/PodcastQueueView.h --- a/application/inc/PodcastQueueView.h Sat Oct 23 17:30:22 2010 +0100 +++ b/application/inc/PodcastQueueView.h Sat Nov 13 13:54:36 2010 +0000 @@ -78,7 +78,6 @@ private: TBool iDontUpdateList; - }; #endif diff -r 1cae65a87b5e -r 9c56bf585696 application/inc/PodcastShowsView.h --- a/application/inc/PodcastShowsView.h Sat Oct 23 17:30:22 2010 +0100 +++ b/application/inc/PodcastShowsView.h Sat Nov 13 13:54:36 2010 +0000 @@ -95,7 +95,7 @@ void GetShowIcons(CShowInfo* aShowInfo, TInt& aIconIndex); void CreateIconsL(); -private: +protected: void DisplayShowInfoDialogL(); void HandleSetShowPlayedL(TBool aPlayed); void HandleDeleteShowL(); @@ -104,7 +104,7 @@ void HandleDeleteShow(); void UpdateViewTitleL(); void GetShowErrorText(TDes &aErrorMessage, TInt aErrorCode); - + protected: CPodcastModel& iPodcastModel; diff -r 1cae65a87b5e -r 9c56bf585696 application/inc/buildno.h --- a/application/inc/buildno.h Sat Oct 23 17:30:22 2010 +0100 +++ b/application/inc/buildno.h Sat Nov 13 13:54:36 2010 +0000 @@ -1,2 +1,2 @@ // Build number generated by increment_buildno.py, do not edit manually -#define BUILD_NO 6 \ No newline at end of file +#define BUILD_NO 1 \ No newline at end of file diff -r 1cae65a87b5e -r 9c56bf585696 application/sis/buildno.txt --- a/application/sis/buildno.txt Sat Oct 23 17:30:22 2010 +0100 +++ b/application/sis/buildno.txt Sat Nov 13 13:54:36 2010 +0000 @@ -1,1 +1,1 @@ -6 \ No newline at end of file +1 \ No newline at end of file diff -r 1cae65a87b5e -r 9c56bf585696 application/sis/podcatcher_udeb.pkg --- a/application/sis/podcatcher_udeb.pkg Sat Oct 23 17:30:22 2010 +0100 +++ b/application/sis/podcatcher_udeb.pkg Sat Nov 13 13:54:36 2010 +0000 @@ -1,7 +1,7 @@ &EN,SP :"Symbian Foundation" %{"Podcatcher","Podcatcher"} -#{"Podcatcher","Podcatcher"},(0xA0009D00), 0, 90, 6, TYPE=SA +#{"Podcatcher","Podcatcher"},(0xA0009D00), 0, 90, 1, TYPE=SA ;Supports S60 3rd edition [0x101F7961], 0, 0, 0, {"Series60ProductID","Series60ProductID"} diff -r 1cae65a87b5e -r 9c56bf585696 application/sis/podcatcher_urel.pkg --- a/application/sis/podcatcher_urel.pkg Sat Oct 23 17:30:22 2010 +0100 +++ b/application/sis/podcatcher_urel.pkg Sat Nov 13 13:54:36 2010 +0000 @@ -1,7 +1,7 @@ &EN :"Symbian Foundation" %{"Podcatcher"} -#{"Podcatcher"},(0xA0009D00), 1, 00, 6, TYPE=SA +#{"Podcatcher"},(0xA0009D00), 1, 00, 1, TYPE=SA ;Supports S60 3rd edition [0x101F7961], 0, 0, 0, {"Series60ProductID"} diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastAppui.cpp --- a/application/src/PodcastAppui.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastAppui.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -32,6 +32,7 @@ #include #include #include +#include "Podcast.mbg" const TUint KDelayLaunch = 1000; @@ -122,7 +123,7 @@ { case EAknSoftkeyExit: { - Exit(); + iFeedView->CheckConfirmExit(); break; } case EEikCmdExit: diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastFeedView.cpp --- a/application/src/PodcastFeedView.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastFeedView.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -35,6 +35,7 @@ #include #include #include "Podcatcher.pan" +#include const TInt KMaxFeedNameLength = 100; const TInt KMaxUnplayedFeedsLength =64; @@ -104,11 +105,8 @@ // Append the feed icon to icon array icons->AppendL( CGulIcon::NewL( bitmap, mask ) ); CleanupStack::Pop(2); // bitmap, mask - iListContainer->Listbox()->ItemDrawer()->FormattedCellData()->SetIconArrayL( icons ); + iListContainer->SetListboxIcons( icons ); CleanupStack::Pop(icons); // icons - - iListContainer->Listbox()->SetListBoxObserver(this); - iUpdater = CPodcastFeedViewUpdater::NewL(*this); DP("CPodcastFeedView::ConstructL END"); } @@ -156,6 +154,10 @@ } } +void CPodcastFeedView::UpdateItemsComplete() + { + } + TUid CPodcastFeedView::Id() const { return KUidPodcastFeedViewID; @@ -165,6 +167,7 @@ TUid aCustomMessageId, const TDesC8& aCustomMessage) { + DP("CPodcastFeedView::DoActivateL BEGIN"); CPodcastListView::DoActivateL(aPrevViewId, aCustomMessageId, aCustomMessage); if (aPrevViewId.iViewUid == KUidPodcastShowsViewID) @@ -175,10 +178,26 @@ UpdateListboxItemsL(); + // when we receive a UID argument, this comes from search view after + // a new feed has been added + if (aCustomMessageId.iUid != 0) + { + TUint feedUid = aCustomMessageId.iUid; + ShowItem(feedUid); + TBuf message; + iEikonEnv->ReadResourceL(message, R_ADD_FEED_SUCCESS); + if(ShowQueryMessageL(message)) + { + iPodcastModel.FeedEngine().UpdateFeedL(feedUid); + } + } + if (iFirstActivateAfterLaunch) { iFirstActivateAfterLaunch = EFalse; } + + DP("CPodcastFeedView::DoActivateL END"); } void CPodcastFeedView::DoDeactivate() @@ -190,7 +209,7 @@ void CPodcastFeedView::HandleListBoxEventL(CEikListBox* /* aListBox */, TListBoxEvent aEventType) { - DP("CPodcastFeedView::HandleListBoxEventL BEGIN"); +// DP("CPodcastFeedView::HandleListBoxEventL BEGIN"); switch(aEventType) { @@ -213,18 +232,19 @@ default: break; } - DP("CPodcastFeedView::HandleListBoxEventL END"); +// DP("CPodcastFeedView::HandleListBoxEventL END"); } void CPodcastFeedView::FeedUpdateAllCompleteL(TFeedState /*aState*/) { - iUpdatingRunning = EFalse; + DP("FeedUpdateAllCompleteL"); + iFeedUpdating = 0; } void CPodcastFeedView::FeedDownloadStartedL(TFeedState /*aState*/, TUint aFeedUid) { // Update status text - iUpdatingRunning = ETrue; + iFeedUpdating = aFeedUid; UpdateFeedInfoStatusL(aFeedUid, ETrue); } @@ -250,6 +270,7 @@ void CPodcastFeedView::UpdateFeedInfoStatusL(TUint aFeedUid, TBool aIsUpdating) { + DP("CPodcastFeedView::UpdateFeedInfoStatusL BEGIN"); const RFeedInfoArray& feeds = iPodcastModel.FeedEngine().GetSortedFeeds(); // Find the index for the feed i both the feed-array and the listbox @@ -296,10 +317,12 @@ { iListContainer->Listbox()->DrawItem(k); } + DP("CPodcastFeedView::UpdateFeedInfoStatusL END"); } void CPodcastFeedView::FormatFeedInfoListBoxItemL(CFeedInfo& aFeedInfo, TBool aIsUpdating) { + DP("CPodcastFeedView::FormatFeedInfoListBoxItemL BEGIN"); TBuf updatedDate; TBuf unplayedShows; TUint unplayedCount = 0; @@ -349,8 +372,9 @@ updatedDate.Zero(); } } - CArrayPtr* icons = iListContainer->Listbox()->ItemDrawer()->FormattedCellData()->IconArray(); + iconIndex = iFeedIdForIconArray.Find(aFeedInfo.Uid()); + DP1(" iconIndex = %d", iconIndex); if(iconIndex == KErrNotFound && aFeedInfo.FeedIcon() != NULL && aFeedInfo.ImageFileName().Length() > 0 && aFeedInfo.FeedIcon()->SizeInPixels().iHeight > 0 && aFeedInfo.FeedIcon()->SizeInPixels().iWidth > 0) @@ -360,7 +384,10 @@ CFbsBitmap* bmpCopy = new (ELeave) CFbsBitmap; CleanupStack::PushL(bmpCopy); bmpCopy->Duplicate(aFeedInfo.FeedIcon()->Handle()); - icons->AppendL( CGulIcon::NewL(bmpCopy, NULL)); + CArrayPtr* icons = iListContainer->ListboxIcons(); + + icons->AppendL( CGulIcon::NewL(AknIconUtils::CreateIconL(bmpCopy), NULL)); + iFeedIdForIconArray.Append(aFeedInfo.Uid()); CleanupStack::Pop(bmpCopy); iconIndex = icons->Count()-1; @@ -373,8 +400,9 @@ if (unplayedShows.Length() > 0 && updatedDate.Length() > 0) { unplayedShows.Insert(0,_L(", ")); } - + iListboxFormatbuffer.Format(KFeedFormat(), iconIndex, &(aFeedInfo.Title()), &updatedDate, &unplayedShows); + DP("CPodcastFeedView::FormatFeedInfoListBoxItemL END"); } void CPodcastFeedView::ImageOperationCompleteL(TInt aError, TUint aHandle, CPodcastModel& /*aPodcastModel*/) @@ -385,7 +413,8 @@ } void CPodcastFeedView::UpdateFeedInfoDataL(CFeedInfo* aFeedInfo, TInt aIndex, TBool aIsUpdating ) - { + { + DP("CPodcastFeedView::UpdateFeedInfoDataL BEGIN"); TListItemProperties itemProps; itemProps.SetDimmed(aIsUpdating); FormatFeedInfoListBoxItemL(*aFeedInfo, aIsUpdating); @@ -403,7 +432,8 @@ iItemArray->InsertL(aIndex, iListboxFormatbuffer); } } - iListContainer->Listbox()->ItemDrawer()->SetPropertiesL(aIndex, itemProps); + //iListContainer->Listbox()->ItemDrawer()->SetPropertiesL(aIndex, itemProps); + DP("CPodcastFeedView::UpdateFeedInfoDataL END"); } @@ -470,9 +500,6 @@ switch(aCommand) { - case EPodcastHide: - AppUi()->HandleCommandL(EEikCmdExit); - break; case EPodcastAddFeed: HandleAddFeedL(); break; @@ -499,35 +526,13 @@ }break; case EPodcastCancelUpdateAllFeeds: { - if(iUpdatingRunning) + if(iFeedUpdating) { iPodcastModel.FeedEngine().CancelUpdateAllFeeds(); } }break; - case EAknSoftkeyExit: - { - RShowInfoArray dlQueue; - iPodcastModel.ShowEngine().GetShowsDownloadingL(dlQueue); - TUint queueCount = dlQueue.Count(); - dlQueue.ResetAndDestroy(); - dlQueue.Close(); - - if (queueCount > 0 && !iPodcastModel.SettingsEngine().DownloadSuspended()) - { - TBuf message; - iEikonEnv->ReadResourceL(message, R_EXIT_SHOWS_DOWNLOADING); - if(ShowQueryMessageL(message)) - { - // pass it on to AppUi, which will exit for us - CPodcastListView::HandleCommandL(aCommand); - } - } - else - { - // nothing in queue, or downloading suspended - CPodcastListView::HandleCommandL(aCommand); - } - } + case EPodcastShowInfo: + DisplayFeedInfoDialogL(); break; default: CPodcastListView::HandleCommandL(aCommand); @@ -537,6 +542,24 @@ DP("CPodcastFeedView::HandleCommandL END"); } +void CPodcastFeedView::DisplayFeedInfoDialogL() + { + const RFeedInfoArray* sortedItems = NULL; + TInt index = iListContainer->Listbox()->CurrentItemIndex(); + sortedItems = &iPodcastModel.FeedEngine().GetSortedFeeds(); + + if(index >= 0 && index < sortedItems->Count()) + { + CFeedInfo *info = (*sortedItems)[index]; + HBufC* description = info->Description().AllocL(); + HBufC* title = info->Title().AllocL(); + CAknMessageQueryDialog* note = new ( ELeave ) CAknMessageQueryDialog( description, title ); + + note->PrepareLC( R_SHOW_INFO_NOTE ); // Adds to CleanupStack + note->RunLD(); + } + } + void CPodcastFeedView::HandleAddFeedL() { TInt selection; @@ -567,6 +590,22 @@ CleanupStack::PopAndDestroy( array ); } +void CPodcastFeedView::ShowItem(TUint aUid) + { + TInt listIndex = -1; + for (TUint i=0;iListbox()->ScrollToMakeItemVisible(listIndex); + + } + void CPodcastFeedView::HandleAddFeedUrlL() { TBuf url; @@ -599,10 +638,7 @@ iEikonEnv->ReadResourceL(message, R_ADD_FEED_SUCCESS); if(ShowQueryMessageL(message)) { - CFeedInfo *info = iPodcastModel.FeedEngine().GetFeedInfoByUid(newFeedInfo->Uid()); - - iPodcastModel.SetActiveFeedInfo(info); - AppUi()->ActivateLocalViewL(KUidPodcastShowsViewID, TUid::Uid(0), KNullDesC8()); + ShowItem(newFeedInfo->Uid()); iPodcastModel.FeedEngine().UpdateFeedL(newFeedInfo->Uid()); } } @@ -626,6 +662,7 @@ HBufC* prompt = iEikonEnv->AllocReadResourceLC(R_PODCAST_SEARCHFEED_PROMPT); dlg->SetPromptL(*prompt); + dlg->SetPredictiveTextInputPermitted(ETrue); CleanupStack::PopAndDestroy(prompt); if(dlg->RunLD()) @@ -951,14 +988,37 @@ { if(aResourceId == R_PODCAST_FEEDVIEW_MENU) { - aMenuPane->SetItemDimmed(EPodcastUpdateAllFeeds, iUpdatingRunning); - aMenuPane->SetItemDimmed(EPodcastCancelUpdateAllFeeds, !iUpdatingRunning); - aMenuPane->SetItemDimmed(EPodcastSettings, iUpdatingRunning); - aMenuPane->SetItemDimmed(EPodcastFeedFeedMenu, iUpdatingRunning); + aMenuPane->SetItemDimmed(EPodcastUpdateAllFeeds, iFeedUpdating); + aMenuPane->SetItemDimmed(EPodcastCancelUpdateAllFeeds, !iFeedUpdating); + aMenuPane->SetItemDimmed(EPodcastSettings, iFeedUpdating); + aMenuPane->SetItemDimmed(EPodcastFeedFeedMenu, iFeedUpdating); // aMenuPane->SetItemDimmed(EPodcastImportExportFeeds, iUpdatingRunning); } } +void CPodcastFeedView::CheckConfirmExit() + { + DP("CPodcastFeedView::CheckConfirmExit"); + RShowInfoArray showsDownloading; + iPodcastModel.ShowEngine().GetShowsDownloadingL(showsDownloading); + TUint count = showsDownloading.Count(); + showsDownloading.ResetAndDestroy(); + showsDownloading.Close(); + + if (count > 0 && !iPodcastModel.SettingsEngine().DownloadSuspended()) + { + TBuf<256> msg; + iEikonEnv->ReadResourceL(msg, R_EXIT_SHOWS_DOWNLOADING); + + if (!ShowQueryMessageL(msg)) + { + return; + } + } + + AppUi()->Exit(); + } + TKeyResponse CPodcastFeedView::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) { if (aType == EEventKey) diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastFeedViewUpdater.cpp --- a/application/src/PodcastFeedViewUpdater.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastFeedViewUpdater.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -73,6 +73,7 @@ else { StopUpdate(); + iPodcastFeedView.UpdateItemsComplete(); } } diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastListView.cpp --- a/application/src/PodcastListView.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastListView.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "buildno.h" @@ -38,22 +40,23 @@ { } -void CPodcastListContainer::SetKeyEventListener(MKeyEventListener *aKeyEventListener) +void CPodcastListContainer::SetContainerListener(MContainerListener *aContainerListener) { - iKeyEventListener = aKeyEventListener; + iContainerListener = aContainerListener; } TKeyResponse CPodcastListContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) { TKeyResponse response = iListbox->OfferKeyEventL(aKeyEvent, aType); - if (iKeyEventListener) - iKeyEventListener->OfferKeyEventL(aKeyEvent, aType); + if (iContainerListener) + iContainerListener->OfferKeyEventL(aKeyEvent, aType); return response; } void CPodcastListContainer::ConstructL( const TRect& aRect, TInt aListboxFlags ) { + DP("CPodcastListContainer::ConstructL BEGIN"); CreateWindowL(); iBgContext = @@ -75,9 +78,13 @@ iListbox->SetSize(aRect.Size()); iListbox->MakeVisible(ETrue); MakeVisible(EFalse); - + + // Set the windows size + SetRect( aRect ); + // Activate the window, which makes it ready to be drawn ActivateL(); + DP("CPodcastListContainer::ConstructL END"); } TInt CPodcastListContainer::CountComponentControls() const @@ -139,6 +146,26 @@ return iListbox; } +void CPodcastListContainer::SetListboxObserver(MEikListBoxObserver *aObserver) + { + iListbox->SetListBoxObserver(aObserver); + } + +void CPodcastListContainer::SetListboxIcons(CArrayPtr< CGulIcon >* aIcons) +{ + iListbox->ItemDrawer()->ColumnData()->SetIconArray(aIcons); +} + +CArrayPtr* CPodcastListContainer::ListboxIcons() + { + return iListbox->ItemDrawer()->FormattedCellData()->IconArray(); + } + +void CPodcastListContainer::SetListboxTextArrays(CDesCArray* aPortraitArray, CDesCArray* aLandscapeArray) + { + iListbox->Model()->SetOwnershipType(ELbmDoesNotOwnItemArray); + iListbox->Model()->SetItemTextArray(aPortraitArray); + } CPodcastListContainer::~CPodcastListContainer() { @@ -146,6 +173,10 @@ delete iBgContext; } +void CPodcastListContainer::SetEmptyText(const TDesC &aText) + { + iListbox->View()->SetListEmptyTextL(aText); + } void CPodcastListContainer::Draw(const TRect& aRect) const { @@ -168,20 +199,13 @@ void CPodcastListContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent) { - if (iPointerListener) - iPointerListener->PointerEventL(aPointerEvent); + if (iContainerListener) + iContainerListener->PointerEventL(aPointerEvent); // Call base class HandlePointerEventL() if not a long tap CCoeControl::HandlePointerEventL(aPointerEvent); } - -void CPodcastListContainer::SetPointerListener(MPointerListener *aPointerListener) - { - iPointerListener = aPointerListener; - } - - CPodcastListView::CPodcastListView() { } @@ -189,16 +213,20 @@ void CPodcastListView::ConstructL() { DP("CPodcastListView::ConstructL BEGIN"); + iListContainer = new (ELeave) CPodcastListContainer; - iListContainer->ConstructL(ClientRect(), iListboxFlags); + TRect rect = ClientRect(); + + iListContainer->ConstructL(rect, iListboxFlags); iListContainer->SetMopParent(this); iListContainer->ActivateL(); + iItemArray = new (ELeave)CDesCArrayFlat(KDefaultGran); iListContainer->Listbox()->Model()->SetItemTextArray(iItemArray); iListContainer->Listbox()->Model()->SetOwnershipType(ELbmDoesNotOwnItemArray); - iListContainer->SetPointerListener(this); - iListContainer->SetKeyEventListener(this); + iListContainer->SetContainerListener(this); + iListContainer->SetListboxObserver(this); DP("CPodcastListView::ConstructL END"); } @@ -215,11 +243,7 @@ { DP2("CPodcastListView::HandleStatusPaneSizeChange(), width=%d, height=%d", ClientRect().Width(), ClientRect().Height()); - if ( iListContainer ) - { - iListContainer->SetRect( ClientRect() ); - } - + HandleViewRectChange(); } @@ -281,12 +305,9 @@ DP1("CPodcastListView::HandleCommandL=%d", aCommand); switch(aCommand) { - case EAknSoftkeyExit: - case EEikCmdExit: - { - AppUi()->Exit(); - break; - } + case EPodcastHide: + AppUi()->HandleCommandL(EEikCmdExit); + break; case EAknSoftkeyBack: { AppUi()->ActivateViewL(iPreviousView); @@ -323,7 +344,7 @@ void CPodcastListView::SetEmptyTextL(TInt aResourceId) { HBufC* emptyText = iEikonEnv->AllocReadResourceLC(aResourceId); - iListContainer->Listbox()->View()->SetListEmptyTextL(*emptyText); + iListContainer->SetEmptyText(*emptyText); CleanupStack::PopAndDestroy(emptyText); } diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastQueueView.cpp --- a/application/src/PodcastQueueView.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastQueueView.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -61,8 +61,6 @@ CPodcastListView::ConstructL(); CreateIconsL(); - - iListContainer->Listbox()->SetListBoxObserver(this); iPodcastModel.FeedEngine().AddObserver(this); iPodcastModel.ShowEngine().AddObserver(this); @@ -142,6 +140,7 @@ void CPodcastQueueView::UpdateListboxItemsL() { + DP("CPodcastQueueView::UpdateListboxItemsL BEGIN"); if (iListContainer->IsVisible() && !iDontUpdateList) { TListItemProperties itemProps; @@ -208,6 +207,7 @@ } } } + DP("CPodcastQueueView::UpdateListboxItemsL END"); } /** @@ -314,6 +314,11 @@ UpdateListboxItemsL(); } break; + case EPodcastShowInfo: + { + DisplayShowInfoDialogL(); + } + break; default: CPodcastListView::HandleCommandL(aCommand); break; diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastSearchView.cpp --- a/application/src/PodcastSearchView.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastSearchView.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -82,10 +83,8 @@ icons->AppendL( CGulIcon::NewL( bitmap, mask ) ); CleanupStack::Pop(2); // bitmap, mask - iListContainer->Listbox()->ItemDrawer()->FormattedCellData()->SetIconArrayL( icons ); + iListContainer->SetListboxIcons(icons); CleanupStack::Pop(icons); // icons - - iListContainer->Listbox()->SetListBoxObserver(this); SetEmptyTextL(R_PODCAST_EMPTY_SEARCH); } @@ -106,16 +105,25 @@ { CPodcastListView::DoActivateL(aPrevViewId, aCustomMessageId, aCustomMessage); iPreviousView = TVwsViewId(KUidPodcast, KUidPodcastFeedViewID); + + HBufC* text = iEikonEnv->AllocReadResourceLC(R_SEARCH_RESULTS); + + CAknTitlePane* titlePane = static_cast + ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) ); - ((CPodcastAppUi*)AppUi())->NaviSetTextL(R_SEARCH_RESULTS); - + titlePane->SetTextL(*text , ETrue ); + CleanupStack::PopAndDestroy(text); UpdateListboxItemsL(); } void CPodcastSearchView::DoDeactivate() { CPodcastListView::DoDeactivate(); - TRAP_IGNORE(((CPodcastAppUi*)AppUi())->NaviShowTabGroupL()); + + CAknTitlePane* titlePane = static_cast + ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) ); + + titlePane->SetTextToDefaultL(); } @@ -212,18 +220,12 @@ TBool added = iPodcastModel.FeedEngine().AddFeedL(*newInfo); if (added) - { - // ask if user wants to update it now - TBuf message; - iEikonEnv->ReadResourceL(message, R_ADD_FEED_SUCCESS); - if(ShowQueryMessageL(message)) - { - CFeedInfo *info = iPodcastModel.FeedEngine().GetFeedInfoByUid(newInfo->Uid()); - - iPodcastModel.SetActiveFeedInfo(info); - AppUi()->ActivateLocalViewL(KUidPodcastShowsViewID, TUid::Uid(0), KNullDesC8()); - iPodcastModel.FeedEngine().UpdateFeedL(info->Uid()); - } + { + // this is a bit of a hack, first we activate the feeds view normally + AppUi()->ActivateLocalViewL(KUidPodcastFeedViewID, TUid::Uid(0), KNullDesC8); + // and then we send the UID of the recently added feed back to feed view for updating + // this is needed so the update? query comes on top of feed view, not search view + AppUi()->ActivateLocalViewL(KUidPodcastFeedViewID, TUid::Uid(newInfo->Uid()), KNullDesC8); } else { diff -r 1cae65a87b5e -r 9c56bf585696 application/src/PodcastShowsView.cpp --- a/application/src/PodcastShowsView.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/application/src/PodcastShowsView.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -105,14 +105,11 @@ void CPodcastShowsView::ConstructL() { - DP("CPodcastShowsView::ConstructL BEGIN"); BaseConstructL(R_PODCAST_SHOWSVIEW); CPodcastListView::ConstructL(); CreateIconsL(); - - iListContainer->Listbox()->SetListBoxObserver(this); - + iPodcastModel.FeedEngine().AddObserver(this); iPodcastModel.ShowEngine().AddObserver(this); @@ -143,7 +140,8 @@ pos+=2; } - iListContainer->Listbox()->ItemDrawer()->FormattedCellData()->SetIconArrayL(icons); + //iListContainer->Listbox()->ItemDrawer()->FormattedCellData()->SetIconArrayL(icons); + iListContainer->SetListboxIcons(icons); CleanupStack::Pop(icons); // icons } @@ -173,7 +171,9 @@ break; case 106: case '#': - HandleCommandL(EPodcastShowInfo); + if (activeShow->DownloadState() == ENotDownloaded) { + HandleCommandL(EPodcastDownloadShow); + } break; case EKeyBackspace: case EKeyDelete: @@ -486,6 +486,7 @@ void CPodcastShowsView::UpdateListboxItemsL() { + DP("CPodcastShowsView::UpdateListboxItemsL BEGIN"); if (iListContainer->IsVisible()) { TListItemProperties itemProps; @@ -552,6 +553,7 @@ } } } + DP("CPodcastShowsView::UpdateListboxItemsL END"); } /** diff -r 1cae65a87b5e -r 9c56bf585696 engine/inc/FeedEngine.h --- a/engine/inc/FeedEngine.h Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/inc/FeedEngine.h Sat Nov 13 13:54:36 2010 +0000 @@ -131,7 +131,7 @@ TUint DBGetFeedCountL(); void DBUpdateFeedL(const CFeedInfo& aItem); void DBGetStatsByFeedL(TUint aFeedUid, TUint &aNumShows, TUint &aNumUnplayed); - + void DBEnsureFileSizeFieldExists(); private: CHttpClient* iFeedClient; diff -r 1cae65a87b5e -r 9c56bf585696 engine/inc/FeedInfo.h --- a/engine/inc/FeedInfo.h Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/inc/FeedInfo.h Sat Nov 13 13:54:36 2010 +0000 @@ -70,7 +70,10 @@ IMPORT_C CFbsBitmap* FeedIcon() const; IMPORT_C void SetFeedIcon(CFbsBitmap* aBitmapToClone); - + + IMPORT_C TInt FeedFileSize() const; + IMPORT_C void SetFeedFileSize(TInt aSize); + private: CFeedInfo(); void ConstructL(); @@ -88,6 +91,7 @@ TBool iCustomTitle; TInt iLastError; CFbsBitmap* iFeedIcon; + TInt iFeedSize; }; typedef RPointerArray RFeedInfoArray; diff -r 1cae65a87b5e -r 9c56bf585696 engine/inc/FeedParser.h --- a/engine/inc/FeedParser.h Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/inc/FeedParser.h Sat Nov 13 13:54:36 2010 +0000 @@ -35,6 +35,7 @@ _LIT(KTagChannel, "channel"); _LIT(KTagEnclosure, "enclosure"); _LIT(KTagPubDate, "pubDate"); +_LIT(KTagGuid, "guid"); _LIT(KTagLastBuildDate, "lastBuildDate"); _LIT(KTagHref, "href"); @@ -52,7 +53,8 @@ EStateItemLink, EStateItemEnclosure, EStateItemDescription, - EStateItemPubDate + EStateItemPubDate, + EStateItemGuid }; enum TEncoding { @@ -93,12 +95,13 @@ CFeedInfo *iActiveFeed; TBuf iBuffer; - + TUint iUid; TUint iMaxItems; TUint iItemsParsed; TBool iStoppedParsing; TEncoding iEncoding; RFs& iRfs; + TInt iFileSize; }; #endif diff -r 1cae65a87b5e -r 9c56bf585696 engine/inc/HttpClient.h --- a/engine/inc/HttpClient.h Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/inc/HttpClient.h Sat Nov 13 13:54:36 2010 +0000 @@ -54,7 +54,7 @@ void DoGetAfterConnectL(); private: RHTTPSession iSession; - TBool iWaitingForGet; + TBool iWaitingForGet; // whether to run the Get after successfull connect TBool iIsActive; RHTTPTransaction iTrans; CHttpEventHandler* iHandler; diff -r 1cae65a87b5e -r 9c56bf585696 engine/inc/Podcatcher.pan --- a/engine/inc/Podcatcher.pan Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/inc/Podcatcher.pan Sat Nov 13 13:54:36 2010 +0000 @@ -24,7 +24,8 @@ EPodcatcherPanicDB = 1, EPodcatcherPanicAlreadyActive, EPodcatcherPanicFeedEngineState, - EPodcatcherPanicFeedView + EPodcatcherPanicFeedView, + EPodcatcherDownloadDrive }; diff -r 1cae65a87b5e -r 9c56bf585696 engine/inc/ShowEngine.h --- a/engine/inc/ShowEngine.h Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/inc/ShowEngine.h Sat Nov 13 13:54:36 2010 +0000 @@ -147,7 +147,7 @@ CPodcastModel& iPodcastModel; // observers that will receive callbacks - RArray iObservers; + RArray iObservers; // The show we are currently downloading CShowInfo* iShowDownloading; diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/FeedEngine.cpp --- a/engine/src/FeedEngine.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/FeedEngine.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -53,6 +53,8 @@ TInt err = KErrNone; TInt feedCount = 0; + DBEnsureFileSizeFieldExists(); + TRAP(err, feedCount = DBGetFeedCountL()); if (err == KErrNone && feedCount > 0) { @@ -101,6 +103,7 @@ CFeedEngine::~CFeedEngine() { + DP("~CFeedEngine BEGIN"); iObservers.Close(); iFeedsUpdating.Close(); @@ -112,6 +115,7 @@ delete iOpmlParser; // delete iRepository; + DP("~CFeedEngine END"); } /** @@ -299,6 +303,7 @@ void CFeedEngine::NewShowL(CShowInfo& aItem) { + DP1("CFeedEngine::NewShowL BEGIN, aItem.Title()=%S", &aItem.Title()); HBufC* description = HBufC::NewLC(KMaxDescriptionLength); TPtr ptr(description->Des()); ptr.Copy(aItem.Description()); @@ -325,6 +330,7 @@ } showsAdded++; + DP("CFeedEngine::NewShowL END"); } void CFeedEngine::GetFeedImageL(CFeedInfo *aFeedInfo) @@ -341,6 +347,11 @@ TFileName fileName; PodcastUtils::FileNameFromUrl(aFeedInfo->ImageUrl(), fileName); + fileName.Trim(); + + if (fileName.Length() == 0) + User::Leave(KErrNotFound); + relPath.Append(fileName); PodcastUtils::EnsureProperPathName(relPath); @@ -401,10 +412,10 @@ descPtr.Copy(aItem.Description()); PodcastUtils::SQLEncode(descPtr); - _LIT(KSqlStatement, "insert into feeds (url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror) values (\"%S\",\"%S\", \"%S\", \"%S\", \"%S\", \"%S\", \"%Ld\", \"%Ld\", \"%u\", \"%u\", \"%u\", \"%d\")"); + _LIT(KSqlStatement, "insert into feeds (url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror, filesize) values (\"%S\",\"%S\", \"%S\", \"%S\", \"%S\", \"%S\", \"%Ld\", \"%Ld\", \"%u\", \"%u\", \"%u\", \"%d\", \"%d\")"); iSqlBuffer.Format(KSqlStatement, &aItem.Url(), titleBuf, descBuf, &aItem.ImageUrl(), &aItem.ImageFileName(), &aItem.Link(), - aItem.BuildDate().Int64(), aItem.LastUpdated().Int64(), aItem.Uid(), EAudioPodcast, aItem.CustomTitle(), aItem.LastError()); + aItem.BuildDate().Int64(), aItem.LastUpdated().Int64(), aItem.Uid(), EAudioPodcast, aItem.CustomTitle(), aItem.LastError(), aItem.FeedFileSize()); CleanupStack::PopAndDestroy(descBuf); CleanupStack::PopAndDestroy(titleBuf); @@ -514,11 +525,10 @@ TPtr descPtr(descBuf->Des()); descPtr.Copy(aItem.Description()); PodcastUtils::SQLEncode(descPtr); - - _LIT(KSqlStatement, "update feeds set url=\"%S\", title=\"%S\", description=\"%S\", imageurl=\"%S\", imagefile=\"%S\", link=\"%S\", built=\"%Lu\", lastupdated=\"%Lu\", feedtype=\"%u\", customtitle=\"%u\", lasterror=\"%d\" where uid=\"%u\""); + _LIT(KSqlStatement, "update feeds set url=\"%S\", title=\"%S\", description=\"%S\", imageurl=\"%S\", imagefile=\"%S\", link=\"%S\", built=\"%Lu\", lastupdated=\"%Lu\", feedtype=\"%u\", customtitle=\"%u\", lasterror=\"%d\", filesize=\"%d\" where uid=\"%u\""); iSqlBuffer.Format(KSqlStatement, &aItem.Url(), titleBuf, descBuf, &aItem.ImageUrl(), &aItem.ImageFileName(), &aItem.Link(), - aItem.BuildDate().Int64(), aItem.LastUpdated().Int64(), EAudioPodcast, aItem.CustomTitle(), aItem.LastError(), aItem.Uid()); + aItem.BuildDate().Int64(), aItem.LastUpdated().Int64(), EAudioPodcast, aItem.CustomTitle(), aItem.LastError(), aItem.FeedFileSize(), aItem.Uid()); CleanupStack::PopAndDestroy(descBuf); CleanupStack::PopAndDestroy(titleBuf); @@ -721,6 +731,25 @@ void CFeedEngine::DownloadInfo(CHttpClient* /*aHttpClient */, int /*aTotalBytes*/) { + + } + +void CFeedEngine::DBEnsureFileSizeFieldExists() + { + DP("DBEnsureFileSizeFieldExists BEGIN"); + sqlite3_stmt *st; + int rc = sqlite3_prepare_v2(&iDB,"alter table feeds add column filesize int" , -1, &st, (const char**) NULL); + DP1(" rc=%d", rc); + + if( rc==SQLITE_OK ) + { + Cleanup_sqlite3_finalize_PushL(st); + rc = sqlite3_step(st); + DP1(" rc=%d", rc); + CleanupStack::PopAndDestroy(); // st + } + + DP("DBEnsureFileSizeFieldExists END"); } EXPORT_C void CFeedEngine::ImportFeedsL(const TDesC& aFile) @@ -939,7 +968,7 @@ iSortedFeeds.Reset(); CFeedInfo *feedInfo = NULL; - _LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror from feeds"); + _LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror, filesize from feeds"); iSqlBuffer.Format(KSqlStatement); sqlite3_stmt *st; @@ -981,7 +1010,7 @@ const void *linkz = sqlite3_column_text16(st, 5); TPtrC16 link((const TUint16*)linkz); - feedInfo->SetDescriptionL(link); + feedInfo->SetLinkL(link); sqlite3_int64 built = sqlite3_column_int64(st, 6); TTime buildtime(built); @@ -999,7 +1028,10 @@ sqlite3_int64 lasterror = sqlite3_column_int(st, 11); feedInfo->SetLastError(lasterror); - + + TInt filesize = sqlite3_column_int(st, 12); + feedInfo->SetFeedFileSize(filesize); + TLinearOrder sortOrder( CFeedEngine::CompareFeedsByTitle); iSortedFeeds.InsertInOrder(feedInfo, sortOrder); @@ -1022,7 +1054,7 @@ { DP("CFeedEngine::DBGetFeedInfoByUid BEGIN"); CFeedInfo *feedInfo = NULL; - _LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror from feeds where uid=%u"); + _LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror, filesize from feeds where uid=%u"); iSqlBuffer.Format(KSqlStatement, aFeedUid); sqlite3_stmt *st; @@ -1055,11 +1087,11 @@ const void *imagefilez = sqlite3_column_text16(st, 4); TPtrC16 imagefile((const TUint16*)imagefilez); - feedInfo->SetDescriptionL(imagefile); + feedInfo->SetImageFileNameL(imagefile, &iPodcastModel); const void *linkz = sqlite3_column_text16(st, 5); TPtrC16 link((const TUint16*)linkz); - feedInfo->SetDescriptionL(link); + feedInfo->SetLinkL(link); sqlite3_int64 built = sqlite3_column_int64(st, 6); TTime buildtime(built); @@ -1076,7 +1108,10 @@ TInt lasterror = sqlite3_column_int(st, 11); feedInfo->SetLastError(lasterror); - + + TInt filesize = sqlite3_column_int(st, 12); + feedInfo->SetFeedFileSize(filesize); + CleanupStack::Pop(feedInfo); } else diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/FeedInfo.cpp --- a/engine/src/FeedInfo.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/FeedInfo.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -225,7 +225,7 @@ { // If this fails, no reason to worry iFeedIcon = new CFbsBitmap(); - TRAP_IGNORE(aPodcastModel->ImageHandler().LoadFileAndScaleL(FeedIcon(), ImageFileName(), TSize(44,44), *this, Uid())); + TRAP_IGNORE(aPodcastModel->ImageHandler().LoadFileAndScaleL(FeedIcon(), ImageFileName(), TSize(128,128), *this, Uid())); } DP("CFeedInfo::SetImageFileNameL END"); } @@ -279,3 +279,15 @@ aPodcastModel.FeedEngine().NotifyFeedUpdateComplete(this->iUid, KErrNone); } } + + +EXPORT_C TInt CFeedInfo::FeedFileSize() const + { + return iFeedSize; + } + +EXPORT_C void CFeedInfo::SetFeedFileSize(TInt aSize) + { + iFeedSize = aSize; + } + diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/FeedParser.cpp --- a/engine/src/FeedParser.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/FeedParser.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -24,6 +24,7 @@ #include #include #include +#include #include "debug.h" #include "podcastutils.h" @@ -54,6 +55,10 @@ iStoppedParsing = EFalse; iEncoding = ELatin1; + TEntry entry; + User::LeaveIfError(iRfs.Entry(feedFileName, entry)); + iFileSize = entry.iSize; + ParseL(*parser, iRfs, feedFileName); CleanupStack::PopAndDestroy(parser); @@ -159,6 +164,7 @@ } break; case EStateItem: + iUid = 0; // if (str.CompareF(KTagTitle) == 0) { iFeedState=EStateItemTitle; @@ -197,6 +203,9 @@ } else if (str.CompareF(KTagPubDate) == 0) { //DP("LastBuildDate BEGIN"); iFeedState = EStateItemPubDate; + // <channel> <item> <guid> + } else if (str.CompareF(KTagGuid) == 0) { + iFeedState = EStateItemGuid; } break; default: @@ -245,18 +254,21 @@ TBuf8<128> temp; temp.Copy(iBuffer); + DP2("iFileSize=%d, iActiveFeed->FeedFileSize()=%d", iFileSize, iActiveFeed->FeedFileSize()); + TRAPD(parseError, internetDate.SetDateL(temp)); if(parseError == KErrNone) { if (TTime(internetDate.DateTime()) > iActiveFeed->BuildDate()) { DP("Successfully parsed build date"); iActiveFeed->SetBuildDate(TTime(internetDate.DateTime())); - } else { + } else if (iFileSize == iActiveFeed->FeedFileSize()){ DP("*** Nothing new, aborting parsing"); iStoppedParsing = ETrue; } } else { DP("Failed to parse last build date"); } + iActiveFeed->SetFeedFileSize(iFileSize); iFeedState = EStateChannel; } break; @@ -273,9 +285,7 @@ case EStateItem: if (str.CompareF(KTagItem) == 0) { - // check if we have a valid pubdate - if (iActiveShow->PubDate().Int64() == 0) { // set pubDate to present time @@ -292,6 +302,10 @@ iActiveShow->SetPubDate(now); } + if (iUid) + { + iActiveShow->SetUid(iUid); + } iCallbacks.NewShowL(*iActiveShow); @@ -302,11 +316,11 @@ iItemsParsed++; DP2("iItemsParsed: %d, iMaxItems: %d", iItemsParsed, iMaxItems); -// if (iItemsParsed >= iMaxItems) -// { -// iStoppedParsing = ETrue; -// DP("*** Too many items, aborting parsing"); -// } + if (iItemsParsed >= iMaxItems) + { + iStoppedParsing = ETrue; + DP("*** Too many items, aborting parsing"); + } iFeedState=EStateChannel; } @@ -314,57 +328,64 @@ case EStateItemPubDate: DP1("PubDate END: iBuffer='%S'", &iBuffer); if (str.CompareF(KTagPubDate) == 0) { - // hack for feeds that don't always write day as two digits - TChar five(iBuffer[5]); - TChar six(iBuffer[6]); + DP1("iBuffer.Length()=%d", iBuffer.Length()); - if (five.IsDigit() && !six.IsDigit()) { - TBuf<KMaxStringBuffer> fix; - fix.Copy(iBuffer.Left(4)); - fix.Append(_L(" 0")); - fix.Append(iBuffer.Mid(5)); - iBuffer.Copy(fix); - } - // end hack + if (iBuffer.Length() > 6) + { + // hack for feeds that don't always write day as two digits + TChar five(iBuffer[5]); + TChar six(iBuffer[6]); + + if (five.IsDigit() && !six.IsDigit()) { + TBuf<KMaxStringBuffer> fix; + fix.Copy(iBuffer.Left(4)); + fix.Append(_L(" 0")); + fix.Append(iBuffer.Mid(5)); + iBuffer.Copy(fix); + } + // end hack + } - // hack for feeds that write out months in full - - if (iBuffer[11] != ' ') { - TPtrC midPtr = iBuffer.Mid(8); + if (iBuffer.Length() > 11) + { + // hack for feeds that write out months in full - int spacePos = midPtr.Find(_L(" ")); - - if (spacePos != KErrNotFound) { - //DP1("Month: %S", &midPtr.Left(spacePos)); + if (iBuffer[11] != ' ') { + TPtrC midPtr = iBuffer.Mid(8); + + int spacePos = midPtr.Find(_L(" ")); - TBuf16<KBufferLength> newBuffer; - newBuffer.Copy(iBuffer.Left(11)); - newBuffer.Append(_L(" ")); - newBuffer.Append(iBuffer.Mid(11+spacePos)); - //DP1("newBuffer: %S", &newBuffer); - iBuffer.Copy(newBuffer); + if (spacePos != KErrNotFound) { + //DP1("Month: %S", &midPtr.Left(spacePos)); + + TBuf16<KBufferLength> newBuffer; + newBuffer.Copy(iBuffer.Left(11)); + newBuffer.Append(_L(" ")); + newBuffer.Append(iBuffer.Mid(11+spacePos)); + //DP1("newBuffer: %S", &newBuffer); + iBuffer.Copy(newBuffer); + } } - } - - // hack for feeds that write days and months as UPPERCASE - TChar one(iBuffer[1]); - TChar two(iBuffer[2]); - TChar nine(iBuffer[9]); - TChar ten(iBuffer[10]); + + // hack for feeds that write days and months as UPPERCASE + TChar one(iBuffer[1]); + TChar two(iBuffer[2]); + TChar nine(iBuffer[9]); + TChar ten(iBuffer[10]); + + one.LowerCase(); + two.LowerCase(); + nine.LowerCase(); + ten.LowerCase(); + + iBuffer[1] = one; + iBuffer[2] = two; + iBuffer[9] = nine; + iBuffer[10] = ten; + } - one.LowerCase(); - two.LowerCase(); - nine.LowerCase(); - ten.LowerCase(); - - iBuffer[1] = one; - iBuffer[2] = two; - iBuffer[9] = nine; - iBuffer[10] = ten; - TBuf8<128> temp; temp.Copy(iBuffer); - TInternetDate internetDate; TRAPD(parseError, internetDate.SetDateL(temp)); if(parseError == KErrNone) { @@ -386,6 +407,10 @@ } iFeedState=EStateItem; break; + case EStateItemGuid: + iUid = DefaultHash::Des16(iBuffer); + iFeedState=EStateItem; + break; case EStateItemTitle: //DP1("title: %S", &iBuffer); iActiveShow->SetTitleL(iBuffer); diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/HttpClient.cpp --- a/engine/src/HttpClient.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/HttpClient.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -19,7 +19,7 @@ const TInt KTempBufferSize = 100; CHttpClient::~CHttpClient() - { + { if (iHandler) { iHandler->CloseSaveFile(); @@ -111,6 +111,8 @@ void CHttpClient::ConnectCompleteL(TInt aErrorCode) { + DP1("CHttpClient::ConnectCompleteL BEGIN, aErrorCode=%d", aErrorCode); + DP1(" iWaitingForGet=%d", iWaitingForGet); if(iWaitingForGet) { iWaitingForGet = EFalse; @@ -124,16 +126,16 @@ TInt connPtr = REINTERPRET_CAST(TInt, &iPodcastModel.ConnectionEngine().Connection()); connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable()), THTTPHdrVal(connPtr)); - iPodcastModel.SetProxyUsageIfNeededL(iSession); - DoGetAfterConnectL(); + DoGetAfterConnectL(); } else { ClientRequestCompleteL(KErrCouldNotConnect); iSession.Close(); } - } + } + DP("CHttpClient::ConnectCompleteL END"); } void CHttpClient::Disconnected() @@ -144,6 +146,7 @@ void CHttpClient::DoGetAfterConnectL() { + DP("CHttpClient::DoGetAfterConnectL BEGIN"); // since nothing should be downloading now. Delete the handler if (iHandler) { @@ -158,7 +161,7 @@ TBuf8<KTempBufferSize> rangeText; if (iResumeEnabled && iPodcastModel.FsSession().Entry(iCurrentFileName, entry) == KErrNone) { - DP1("Found file, with size=%d", entry.iSize); + DP1(" Found file, with size=%d", entry.iSize); // file exists, so we should probably resume rangeText.Format(_L8("bytes=%d-"), (entry.iSize-KByteOverlap > 0 ? entry.iSize-KByteOverlap : 0)); iHandler->SetSaveFileName(iCurrentFileName, ETrue); @@ -179,7 +182,7 @@ SetHeaderL(hdr, HTTP::EAccept, KAccept); TBuf<KTempBufferSize> range16; range16.Copy(rangeText); - DP1("range text: %S", &range16); + DP1(" range text: %S", &range16); if (rangeText.Length() > 0) { SetHeaderL(hdr, HTTP::ERange, rangeText); } @@ -187,11 +190,12 @@ // submit the transaction iTrans.SubmitL(); iIsActive = ETrue; - DP("CHttpClient::Get END"); + DP("CHttpClient::DoGetAfterConnectL END"); } TBool CHttpClient::GetL(const TDesC& aUrl, const TDesC& aFileName, TBool aSilent) { DP("CHttpClient::Get START"); + DP2("Getting '%S' to '%S'", &aUrl, &aFileName); if (iIsActive) { @@ -215,17 +219,18 @@ iSilentGet = aSilent; iCurrentFileName.Copy(aFileName); - iWaitingForGet = ETrue; if (iTransactionCount == 0) { DP("CHttpClient::GetL\t*** Opening HTTP session ***"); iSession.Close(); iSession.OpenL(); + iWaitingForGet = ETrue; ConnectHttpSessionL(); } else { + iWaitingForGet = EFalse; DoGetAfterConnectL(); } return ETrue; @@ -257,9 +262,10 @@ } void CHttpClient::ClientRequestCompleteL(TInt aErrorCode) { + DP1("CHttpClient::ClientRequestCompleteL BEGIN, aErrorCode=%d", aErrorCode); iIsActive = EFalse; iObserver.CompleteL(this, aErrorCode); - DP("CHttpClient::ClientRequestCompleteL"); + DP1(" iTransactionCount=%d", iTransactionCount); if(iTransactionCount>0) { iTransactionCount--; @@ -272,4 +278,5 @@ iSession.Close(); } } + DP("CHttpClient::ClientRequestCompleteL END"); } diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/HttpEventHandler.cpp --- a/engine/src/HttpEventHandler.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/HttpEventHandler.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -23,6 +23,7 @@ #include "HttpEventHandler.h" #include "bautils.h" #include "Httpclient.h" +#include "Podcatcher.pan" const TInt64 KMinDiskSpace = 1024 * 1024; // at least 1 MB must remain @@ -61,6 +62,7 @@ void CHttpEventHandler::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent) { + //DP1("CHttpEventHandler::MHFRunL, aEvent.iStatus=%d", aEvent.iStatus); switch (aEvent.iStatus) { case THTTPEvent::EGotResponseHeaders: @@ -258,6 +260,7 @@ switch(fName[0]) { case 'C': + case '\\': iDriveNo = EDriveC; break; case 'E': @@ -270,7 +273,7 @@ iDriveNo = EDriveG; break; default: - iDriveNo = -1; + Panic(EPodcatcherDownloadDrive); break; } DP1("iDriveNo set to %d", iDriveNo); @@ -431,6 +434,7 @@ void CHttpEventHandler::CloseSaveFile() { + DP("CHttpEventHandler::CloseSaveFile BEGIN"); if(iRespBody != NULL) { if(iRespBodyFile.SubSessionHandle() != 0) @@ -441,5 +445,6 @@ iRespBodyFile.Close(); } } + DP("CHttpEventHandler::CloseSaveFile BEGIN"); } diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/PodcastModel.cpp --- a/engine/src/PodcastModel.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/PodcastModel.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -304,7 +304,14 @@ dbTemplate.Copy(iSettingsEngine->PrivatePath()); dbTemplate.Append(KDBTemplateFileName); + DP1("Copy template DB from: %S", &dbTemplate); + DP1("Copy template DB to: %S", &dbFileName); + BaflUtils::CopyFile(iFsSession, dbTemplate,dbFileName); + + // important to set this file to not be read only if copying from Z: + iFsSession.SetAtt(dbFileName, 0, KEntryAttReadOnly); + iIsFirstStartup = ETrue; DP("CPodcastModel::ResetDB END"); } diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/PodcastUtils.cpp --- a/engine/src/PodcastUtils.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/PodcastUtils.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -73,18 +73,16 @@ { return; } - - DP(" miscellaneous"); // miscellaneous cleanup + DP(" miscellaneous cleanup"); const TChar KLineBreak(CEditableText::ELineBreak); _LIT(KNewLine, "\n"); _LIT(KNewLineWindows, "\r\n"); ReplaceString(str, KNewLine, KNullDesC); ReplaceString(str, KNewLineWindows, KNullDesC); - DP(" strip HTML"); // strip out HTML tags - + DP(" strip out HTML tags"); TInt startPos = str.Locate('<'); TInt endPos = str.Locate('>'); HBufC* tmpBuf = HBufC::NewLC(KMaxDescriptionLength); @@ -116,8 +114,8 @@ endPos = str.Locate('>'); } +// change HTML encoded chars to unicode DP(" change HTML encoded chars to unicode"); -// change HTML encoded chars to unicode startPos = str.Locate('&'); endPos = str.Locate(';'); while (startPos != KErrNotFound && endPos != KErrNotFound && endPos > startPos) @@ -207,20 +205,17 @@ CleanupStack::PopAndDestroy(tmpBuf); - DP(" trim"); if(str.Length()>1) { - DP1("str.Length() ==%d", str.Length()); // chop away newlines at start - while (str.Length() && (str[0] == KLineBreak)) { - DP("mid"); + DP(" chop away newlines at start"); + while (str.Length() > 0 && (str[0] == KLineBreak)) { str = str.Mid(1); } // chop away newlines at end - - while (str.Length() && (str[str.Length()-1] == KLineBreak)) { - DP("left"); + DP(" chop away newlines at end"); + while (str.Length() > 0 && (str[str.Length()-1] == KLineBreak)) { str = str.Left(str.Length()-1); } diff -r 1cae65a87b5e -r 9c56bf585696 engine/src/ShowEngine.cpp --- a/engine/src/ShowEngine.cpp Sat Oct 23 17:30:22 2010 +0100 +++ b/engine/src/ShowEngine.cpp Sat Nov 13 13:54:36 2010 +0000 @@ -162,7 +162,7 @@ void CShowEngine::Progress(CHttpClient* /*aHttpClient */, TInt aBytes, TInt aTotalBytes) { - iShowDownloading->SetShowSize(aTotalBytes); + //iShowDownloading->SetShowSize(aTotalBytes); TRAP_IGNORE(NotifyShowDownloadUpdatedL(aBytes, aTotalBytes)); } @@ -190,13 +190,25 @@ TFileName fileName; PodcastUtils::FileNameFromUrl(info->Url(), fileName); - TFileName extension; - extension.Copy(fileName.Mid(fileName.LocateReverse('.'))); - DP1("extension=%S", &extension); - TFileName newFilename; - newFilename.Format(_L("%u%S"), info->Uid(), &extension); - DP1("newFilename=%S", &newFilename); + + TInt periodPos = fileName.LocateReverse('.'); + + if (periodPos != -1) + { + // file extension (most likely) found + TFileName extension; + extension.Copy(fileName.Mid(periodPos)); + DP1("extension=%S", &extension); + + newFilename.Format(_L("%u%S"), info->Uid(), &extension); + DP1("newFilename=%S", &newFilename); + } + else + { + // no extension found, we'll have to rely on magic numbers + newFilename.Format(_L("%u"), info->Uid()); + } relPath.Append(newFilename); PodcastUtils::EnsureProperPathName(relPath); @@ -248,7 +260,8 @@ { if (iShowDownloading != NULL) { - DP2("CShowEngine::CompleteL file=%S, aError=%d", &iShowDownloading->FileName(), aError); + DP2("CShowEngine::CompleteL file=%S, aError=%d", &iShowDownloading->FileName(), aError); + if(aError != KErrCouldNotConnect) { if(aError == KErrDisconnected && iPodcastModel.SettingsEngine().DownloadSuspended()) @@ -274,6 +287,14 @@ { iShowDownloading->SetShowType(EVideoPodcast); } + + // setting file size + TEntry entry; + TInt err = iPodcastModel.FsSession().Entry(iShowDownloading->FileName(), entry); + if (err == KErrNone) + { + iShowDownloading->SetShowSize(entry.iSize); + } iShowDownloading->SetDownloadState(EDownloaded); DBUpdateShowL(*iShowDownloading); @@ -286,8 +307,16 @@ } else { + if (aError == HTTPStatus::ERequestedRangeNotSatisfiable) + { + DP("ERequestedRangeNotSatisfiable, resetting download"); + // file size got messed up, so delete downloaded file an re-queue + BaflUtils::DeleteFile(iPodcastModel.FsSession(),iShowDownloading->FileName()); + iShowDownloading->SetDownloadState(EQueued); + DBUpdateShowL(*iShowDownloading); + } // 400 and 500 series errors are serious errors on which probably another download will fail - if(aError >= HTTPStatus::EBadRequest && aError <= HTTPStatus::EBadRequest+200) + else if (aError>= HTTPStatus::EBadRequest && aError <= HTTPStatus::EBadRequest+200) { iShowDownloading->SetDownloadState(EFailedDownload); DBUpdateShowL(*iShowDownloading);