diff -r 14979e23cb5e -r 3de6c4cf6b67 mpxplugins/viewplugins/views/waitnotedialog/src/mpxscanningdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxplugins/viewplugins/views/waitnotedialog/src/mpxscanningdialog.cpp Wed Sep 01 12:32:02 2010 +0100 @@ -0,0 +1,562 @@ +/* +* Copyright (c) Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Wait note dialog for scanning +* +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpxscanningdialog.h" + + +// --------------------------------------------------------------------------- +// Default Constructor +// --------------------------------------------------------------------------- +// +CMPXScanningWaitDialog::CMPXScanningWaitDialog( MMPXWaitNoteObserver* aObs, + TWaitNoteType aType ) : + CMPXWaitNoteDialog( aObs, aType ) + { + iNumItemsAdded = 0; + iTotalNewTracks = 0; + iInitialCount = 0; + isCollectionDBChanged = EFalse; + iAsyncEvent = ECmdIdle; + iRefreshEnd = EFalse; + + } + + +// --------------------------------------------------------------------------- +// 2nd Phased constructor +// --------------------------------------------------------------------------- +// +void CMPXScanningWaitDialog::ConstructL() + { + MPX_DEBUG1("CMPXScanningWaitDialog::ConstructL <---"); + BaseConstructL(); + + TCallBack callback( CMPXScanningWaitDialog::AsyncCallHarvesterEventL, this ); + iAsyncCallBack = new (ELeave) CAsyncCallBack( CActive::EPriorityHigh ); + iAsyncCallBack->Set( callback ); + MPX_DEBUG1("CMPXScanningWaitDialog::ConstructL --->"); + } + + +// --------------------------------------------------------------------------- +// Two Phased constructor +// --------------------------------------------------------------------------- +// +CMPXScanningWaitDialog* CMPXScanningWaitDialog::NewL( MMPXWaitNoteObserver* aObs, + TWaitNoteType aType ) + { + CMPXScanningWaitDialog* self = new(ELeave)CMPXScanningWaitDialog( aObs, + aType ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Virtual destructor +// --------------------------------------------------------------------------- +// +CMPXScanningWaitDialog::~CMPXScanningWaitDialog() + { + if( iHarvesterUtil ) + { + iHarvesterUtil->Close(); + } + iHarvesterUtil = NULL; + delete iAsyncCallBack; + iAsyncCallBack = NULL; + } + +// --------------------------------------------------------------------------- +// CMPXScanningWaitDialog::PreNoteDisplayHandleL() +// --------------------------------------------------------------------------- +// +void CMPXScanningWaitDialog::PreNoteDisplayHandleL() + { + // CBA + SetCBAL( R_MPX_WAITNOTE_SOFTKEYS_EMPTY_STOP ); + + // Text + HBufC* text = NULL; + if( iWaitNoteType == EMPXScanningNote ) + { + text = StringLoader::LoadLC( R_MPX_SCANNING_DB_TXT ); + } + else if( iWaitNoteType == EMPXRefreshingNote ) + { + text = StringLoader::LoadLC( R_MPX_REFRESHING_DB_TXT, 0 ); + } + else // iWaitNoteType == EMPXCorruptScanningNote + { + text = StringLoader::LoadLC( R_MPX_REPAIRING_CORRUPT_DB ); + } + + SetTextL( *text ); + CleanupStack::PopAndDestroy( text ); + + // Icon + TNoteIconInfo icon( (TInt)EMbmAvkonQgn_note_progress, + (TInt)EMbmAvkonQgn_note_progress_mask, + TFileName(KAvkonBitmapFile) ); + SetIconL( icon ); + + // If we are repairing a corrupt db, we first clean up the old ones + // + if( iWaitNoteType == EMPXCorruptScanningNote ) + { + HandleDatabaseCorruptionL(); + } + + // Start the scanning in harvester + // Just to be faster, lets just create a small async callback and then + // call ScanL + if( !iAsyncCallBack->IsActive() ) + { + iAsyncEvent = ECmdScan; + iCancelScan = EFalse; + iAsyncCallBack->CallBack(); + } + } + +// --------------------------------------------------------------------------- +// CMPXScanningWaitDialog::PostNoteHandleL() +// --------------------------------------------------------------------------- +// +void CMPXScanningWaitDialog::PostNoteHandleL( TInt aButtonId ) + { + MPX_DEBUG1("CMPXScanningWaitDialog::PostNoteHandleL --->"); + + MPX_DEBUG1(" BUGHUNT: cover display"); + TInt textRsc( KErrNotFound ); + + HBufC* text = NULL; + if( aButtonId == EAknSoftkeyCancel ) + { + // cancel scan in harvester + // Just to be faster, lets just create a small async callback and then + // call CancelScanL + if( !iAsyncCallBack->IsActive() ) + { + iAsyncEvent = ECmdCancleScan; + iAsyncCallBack->CallBack(); + } + else + { + iCancelScan = ETrue; + } + + if (!iRefreshEnd) + { + // When stop refreshing library, prompt a process waiting dialog. + // Inform user to wait for the updating library. + HBufC* waitText = StringLoader::LoadLC( R_MPX_UPDATING_LIBRARY_TXT ); + DisplayProcessWaitDialogL( R_MPX_GENERIC_WAIT_NOTE, *waitText ); + CleanupStack::PopAndDestroy( waitText ); + } + } + else if( iScanningError >= KErrNone ) + { + // Show completed scan note + // + if( iWaitNoteType == EMPXScanningNote || + iWaitNoteType == EMPXCorruptScanningNote ) + { + if ( isCollectionDBChanged ) + { + text = StringLoader::LoadLC( R_MPX_SCANNING_COMPLETE_TXT, + iNumItemsAdded ); + textRsc = R_MPX_SCANNING_COMPLETE_TXT; + } + else + { + text = StringLoader::LoadLC( R_MPX_UPTODATE_TXT ); + textRsc = R_MPX_UPTODATE_TXT; + } + } + else // iWaitNoteType == EMPXRefreshNote + { + if ( isCollectionDBChanged ) + { + text = StringLoader::LoadLC( R_MPX_REFRESHING_DB_COMPLETE_TXT, + iNumItemsAdded ); + textRsc = R_MPX_REFRESHING_DB_COMPLETE_TXT; + } + else + { + text = StringLoader::LoadLC( R_MPX_UPTODATE_TXT ); + textRsc = R_MPX_UPTODATE_TXT; + } + } + } + else if( iScanningError == KErrDiskFull ) + { + // If the error was disk full + // + text = StringLoader::LoadLC( R_MPX_MEM_LO_NOT_ENOUGH_MEMORY, + iNumItemsAdded ); + } + else + { + // Show stopped notes + // + if( iWaitNoteType == EMPXScanningNote || + iWaitNoteType == EMPXCorruptScanningNote ) + { + textRsc = R_MPX_SCANNING_STOPPED_TXT; + text = StringLoader::LoadLC( R_MPX_SCANNING_STOPPED_TXT, + iNumItemsAdded ); + } + else // iWaitNoteType == EMPXRefreshNote + { + textRsc = R_MPX_REFRESHING_DB_STOPPED_TXT; + text = StringLoader::LoadLC( R_MPX_REFRESHING_DB_STOPPED_TXT, + iNumItemsAdded ); + } + } + + // Show the note + if( text ) + { + if ( FeatureManager::FeatureSupported( KFeatureIdCoverDisplay ) ) + { + DisplayNoteDialogL( R_MPX_EMPTY_CLOSE_NOTE, textRsc, iNumItemsAdded, + *text, CAknNoteDialog::EConfirmationTone ); + } + else + { + // When finish updating library, cancle the process waiting + // dialog and then prompt the refreshing completion dialog. + CancelProcessWaitDialogL(); + DisplayNoteDialogL( R_MPX_EMPTY_CLOSE_NOTE, *text, + CAknNoteDialog::EConfirmationTone ); + } + CleanupStack::PopAndDestroy( text ); + } + + MPX_DEBUG1("<--CMPXScanningWaitDialog::PostNoteHandleL"); + } + +// --------------------------------------------------------------------------- +// Handle the collection message +// --------------------------------------------------------------------------- +// +void CMPXScanningWaitDialog::HandleCollectionMessage( + CMPXMessage* aMessage, TInt aError ) + { + if ( aError == KErrNone && aMessage ) + { + TRAP_IGNORE( DoHandleCollectionMessageL( *aMessage ) ); + } + } + +// --------------------------------------------------------------------------- +// Cleanup both collection and harvester databases +// --------------------------------------------------------------------------- +// +void CMPXScanningWaitDialog::HandleDatabaseCorruptionL() + { + // Cleanup Harvester + if( iHarvesterUtil != NULL ) + { + iHarvesterUtil->RecreateDatabasesL(); + } + } + +// --------------------------------------------------------------------------- +// MMPXCollectionObserver +// --------------------------------------------------------------------------- +// +void CMPXScanningWaitDialog::DoHandleCollectionMessageL( + const CMPXMessage& aMessage ) + { + MPX_FUNC( "CMPXScanningWaitDialog::DoHandleCollectionMessageL" ); + + TMPXMessageId id( aMessage.ValueTObjectL( KMPXMessageGeneralId ) ); + if ( KMPXMessageGeneral == id ) + { + TInt event( aMessage.ValueTObjectL( KMPXMessageGeneralEvent ) ); + TInt op( aMessage.ValueTObjectL( KMPXMessageGeneralType ) ); + TInt data( aMessage.ValueTObjectL( KMPXMessageGeneralData ) ); + + if(event == TMPXCollectionMessage::EBroadcastEvent && + ((op == EMcMsgRefreshStart) || (op == EMcMsgRefreshEnd))) + { + TInt songTotal = 0; + + if ( iWaitNoteType == EMPXScanningNote ) + { + RArray ary; + CleanupClosePushL( ary ); + ary.AppendL(TUid::Uid( EMPXCollectionPluginPodCast ) ); + TUid podcastCollectionId = iCollection->CollectionIDL( ary.Array() ); + ary.Reset(); + ary.AppendL(TUid::Uid(EMPXCollectionPluginMusic)); + TUid musicCollectionId = iCollection->CollectionIDL( ary.Array() ); + CleanupStack::PopAndDestroy(&ary); + + TInt removableDrive( EDriveF ); + #ifdef RD_MULTIPLE_DRIVE + User::LeaveIfError( DriveInfo::GetDefaultDrive( + DriveInfo::EDefaultRemovableMassStorage, + removableDrive ) ); + #endif // RD_MULTIPLE_DRIVE + + TInt massStorageDrive( EDriveE ); + User::LeaveIfError( DriveInfo::GetDefaultDrive( + DriveInfo::EDefaultMassStorage, + massStorageDrive ) ); + + songTotal = GetTrackCountL( removableDrive, + podcastCollectionId.iUid, EMPXCollectionCountTrack ); + songTotal += GetTrackCountL( massStorageDrive, + podcastCollectionId.iUid, EMPXCollectionCountTrack ); + + songTotal += GetTrackCountL( removableDrive, + musicCollectionId.iUid, EMPXCollectionCountTotal ); + songTotal += GetTrackCountL( massStorageDrive, + musicCollectionId.iUid, EMPXCollectionCountTotal ); + + } + if( op == EMcMsgRefreshStart ) + { + iRefreshEnd = EFalse; + isCollectionDBChanged = EFalse; + MPX_DEBUG1("refreshStart store the initial count"); + iInitialCount = songTotal; + } + + if( op == EMcMsgRefreshEnd ) + { + MPX_DEBUG1("CMPXScanningWaitDialog::HandleCollectionMessageL refresh end"); + // Do not reset iNumItemsAdded while KErrLocked or KErrDiskFull. + if( data != KErrLocked && data != KErrDiskFull ) + { + iNumItemsAdded = songTotal ; + } + switch ( iWaitNoteType ) + { + case EMPXScanningNote: + case EMPXOpeningNote: + case EMPXRefreshingNote: + case EMPXCorruptScanningNote: + case EMPXUsbEventNote: + case EMPXMTPEventNote: + case EMPXFormatScanningNote: + case EMPXMediaNotAvailableNote: + case EMPXNoteNotDefined: + // fall through + default: + { + // Synchronize the number of items added if we had no errors + // + if( data > KErrNone || iTotalNewTracks ) + { + isCollectionDBChanged = ETrue; + iNumItemsAdded = iTotalNewTracks; + } + else + { + isCollectionDBChanged = EFalse; + } + break; + } + }; + + iRefreshEnd = ETrue; + // If cancel was pressed, iWaitDialog is NULL + // + if( iWaitDialog ) + { + MPX_DEBUG1("CMPXScanningWaitDialog::HandleCollectionMessageL killing dialog"); + iScanningError = data; + iWaitDialog->ProcessFinishedL(); + } + + // Delay showing the number added dialog + if( iScanningError == KErrCancel ) + { + PostNoteHandleL( EAknSoftkeyOk ); + } + + // Save the error code + iScanningError = data; + } + } + else if( event == TMPXCollectionMessage::EBroadcastEvent && + op == EMcMsgDiskInserted ) + { + // Dismiss this scanning note because scanning will be restarted + // + MPX_DEBUG1("CMPXScanningWaitDialog::HandleCollectionMessageL \ + dismissing scan because of refresh msg "); + if( iWaitDialog ) + { + MPX_DEBUG1("CMPXScanningWaitDialog::HandleCollectionMessageL killing dialog"); + iWaitDialog->ProcessFinishedL(); + } + + iScanningError = KErrNone; + } + } + else if(id == KMPXMessageIdItemChanged) + { + // Loop through messages for arrays. + // + if (aMessage.IsSupported(KMPXMessageArrayContents)) + { + const CMPXMessageArray* messageArray = + aMessage.Value(KMPXMessageArrayContents); + User::LeaveIfNull(const_cast(messageArray)); + + for( TInt i=0; iCount(); ++i ) + { + HandleCollectionMessage( messageArray->AtL( i ), KErrNone ); + } + } + // Single item + else + { + MPX_DEBUG1("CMPXScanningWaitDialog::HandleCollectionMessageL KMPXMessageIdItemChanged"); + TMPXChangeEventType changeType( aMessage.ValueTObjectL( KMPXMessageChangeEventType ) ); + TMPXGeneralCategory cat(aMessage.ValueTObjectL(KMPXMessageMediaGeneralCategory)); + if( changeType == EMPXItemInserted && + (cat == EMPXSong || cat == EMPXPlaylist || cat == EMPXPodcast) ) + { + iNumItemsAdded++; + iTotalNewTracks++; + // Update wait note text if refreshing or scaning + if( iWaitNoteType == EMPXRefreshingNote || iWaitNoteType == EMPXScanningNote || iWaitNoteType == EMPXCorruptScanningNote && + iScanningError == KErrNone ) + { + HBufC* text = StringLoader::LoadLC( R_MPX_REFRESHING_DB_TXT, + iNumItemsAdded ); + SetTextL( *text ); + CleanupStack::PopAndDestroy( text ); + } + } + } + } + } +// --------------------------------------------------------------------------- +// Get track count for given table in the db +// --------------------------------------------------------------------------- +// +TInt CMPXScanningWaitDialog::GetTrackCountL(TInt aDrive,TInt aColDbId, TInt aColTable) + { + MPX_DEBUG2("--->CMPXScanningWaitDialog::GetTrackCountL() aDrive = %d", aDrive ); + TInt count(0); + + //get count from db + CMPXCommand* cmdCountM = CMPXMedia::NewL(); + CleanupStack::PushL(cmdCountM); + cmdCountM->SetTObjectValueL( + KMPXCommandGeneralId, + KMPXCommandCollectionGetCount ); + cmdCountM->SetTObjectValueL( + KMPXCommandGeneralDoSync, + ETrue ); + cmdCountM->SetTObjectValueL( + KMPXCommandGeneralCollectionId, + aColDbId ); + cmdCountM->SetTObjectValueL( + KMPXCommandCollectionCountDrive, + aDrive ); + cmdCountM->SetTObjectValueL( + KMPXCommandCollectionCountTable, + aColTable ); + + TRAPD( err, iCollection->Collection().CommandL( *cmdCountM ) ); + + // returned command should contain count + if ( err == KErrNone && cmdCountM->IsSupported(KMPXCommandCollectionCountValue ) ) + { + count = cmdCountM->ValueTObjectL(KMPXCommandCollectionCountValue); + } + + CleanupStack::PopAndDestroy(cmdCountM); + MPX_DEBUG2("--->CMPXScanningWaitDialog::GetTrackCountL() count = %d", count ); + + return count; + } +// --------------------------------------------------------------------------- +// async callback +// --------------------------------------------------------------------------- +// +TInt CMPXScanningWaitDialog::AsyncCallHarvesterEventL( TAny* aSelf ) + { + MPX_DEBUG1("CMPXScanningWaitDialog::CallHarvesterScanL <---"); + CMPXScanningWaitDialog* self = static_cast( aSelf ); + if( self->iHarvesterUtil == NULL ) + { + self->iHarvesterUtil = CMPXHarvesterFactory::NewL(); + } + if( self->iAsyncEvent == ECmdScan ) + { + if( !self->iCancelScan ) + { + self->iHarvesterUtil->ScanL(); + self->iScanningError = KErrNone; + } + else + { + self->iCancelScan = EFalse; + } + } + + if( self->iAsyncEvent == ECmdCancleScan || self->iCancelScan ) + { + self->iScanningError = KErrCancel; + // If harvester crashed,..... restart it. + MPX_TRAPD( err, self->iHarvesterUtil->CancelScanL() ); + if( err != KErrNone ) + { + self->iHarvesterUtil->Close(); + self->iHarvesterUtil = NULL; + self->iHarvesterUtil = CMPXHarvesterFactory::NewL(); + } + } + self->iAsyncEvent = ECmdIdle; + MPX_DEBUG1("CMPXScanningWaitDialog::CallHarvesterScanL --->"); + return KErrNone; + } +// END OF FILE +