diff -r 000000000000 -r ff3acec5bc43 mpxmusicplayer/commonui/src/mpxcommonuihelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxmusicplayer/commonui/src/mpxcommonuihelper.cpp Thu Dec 17 08:45:05 2009 +0200 @@ -0,0 +1,1944 @@ +/* +* Copyright (c) 2006 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: Helper utility for Common UI +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef RD_MULTIPLE_DRIVE +#include +#endif // RD_MULTIPLE_DRIVE +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // TMPXItemId +#include +#include +#include +#include + +// Cover UI start +//#ifdef __COVER_DISPLAY +#include +#include +#include +#include +//#endif +// Cover UI end + +#include +#include "mpxfilenamequerydlg.h" +#include "mpxcommonui.hrh" +#include "mpxtlshelper.h" +#include "mpxcommonuihelper.h" +#include "mpxdrmuihelper.h" +#include "mpxinternalcrkeys.h" +#include "mpxlog.h" + + +// CONSTANTS +const TInt KMPXOneSecInMicroSecs( 1000000 ); +const TInt KMPXOneMinInSeconds( 60 ); +const TInt KMPXOneHourInSeconds( 3600 ); +const TInt KMPXOneDayInSeconds( 86400 ); +const TInt KMPXOneHundredHoursInSecs( 360000 ); + +const TInt KMPXDurationDisplayResvLen( 10 ); + +const TInt KMPXDecimalPlaces ( 1 ); +const TInt KMPXWidthOfChar ( 10 ); + +const TInt KMPXMaxBufferLen ( 160 ); + +const TInt KMPXMaxPlaylistPathLen ( 200 ); +const TInt KMPXPlaylistinfoLen ( 300 ); + +const TInt KMPXStandAloneProcessIDTop32( 1 ); +const TInt KMPXStandAloneProcessIDBottom32( 2 ); + +const TReal KMPXOneKB ( 1024 ); +const TReal KMPXOneMB ( 1048576 ); +const TReal KMPXOneGB ( 1073741824 ); + +const TText KRightToLeftMark = 0x200F; + +const TInt KMPXChunkSize = 100; // number of songs added in each chunk, IncAddL +const TInt KSQLErrGeneral = -311; // SQL General error. Don't want to include sql header here + +_LIT( KMPXCommonUiRscPath, "mpxcommonui.rsc" ); +_LIT( KMPXAddToPlaylistMemoryCardIcon, "\t0"); +_LIT( KMPXCommonUiIconFile, "mpxcommonui.mbm" ); +_LIT( KMPXAppUiRscPath, "mpx.rsc" ); + +// autonaming format +_LIT( KAutoNamingFormat, "%S(%S)"); +#ifndef RD_MULTIPLE_DRIVE +_LIT( KDriveFormatString, ":\\" ); +#endif // RD_MULTIPLE_DRIVE +_LIT( KAutoNumberFormat, "%u"); +_LIT( KAutoNumberPaddedFormat, "%+02u"); +_LIT( KWildCardCharacter, "*"); + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------------------------- +// +CMPXCommonUiHelper::CMPXCommonUiHelper(MMPXCollectionUtility* aCollectionUtility) + : iCollectionUtility(aCollectionUtility) + { + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CMPXCommonUiHelper::ConstructL() + { + CCoeEnv* coeEnv = CEikonEnv::Static(); + TParse parse; + parse.Set( KMPXCommonUiRscPath, &KDC_APP_RESOURCE_DIR, NULL ); + TFileName resourceFile( parse.FullName() ); + User::LeaveIfError( MPXUser::CompleteWithDllPath( resourceFile ) ); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), resourceFile ); + iResourceOffset = coeEnv->AddResourceFileL( resourceFile ); + + TParse appUiparse; + appUiparse.Set( KMPXAppUiRscPath, &KDC_APP_RESOURCE_DIR, NULL ); + TFileName appUiResourceFile( appUiparse.FullName() ); + User::LeaveIfError( MPXUser::CompleteWithDllPath( appUiResourceFile ) ); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), appUiResourceFile ); + iAppUiResourceOffset = coeEnv->AddResourceFileL( appUiResourceFile ); + + iMpxDrmHelper = CMPXDrmUiHelper::NewL( this ); + +//#ifdef __COVER_DISPLAY + if ( FeatureManager::FeatureSupported( KFeatureIdCoverDisplay ) ) + { + iCoverDisplay = ETrue; + } + else + { + iCoverDisplay = EFalse; + } +//#endif // __COVER_DISPLAY + } + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +EXPORT_C CMPXCommonUiHelper* CMPXCommonUiHelper::NewL(MMPXCollectionUtility* aCollectionUtility) + { + CMPXCommonUiHelper* self = new ( ELeave ) CMPXCommonUiHelper(aCollectionUtility); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMPXCommonUiHelper::~CMPXCommonUiHelper() + { + if ( iCollectionUiHelper ) + { + iCollectionUiHelper->Close(); + } + + if ( iWaitDialog ) + { + iWaitDialog->SetCallback( NULL ); + TRAP_IGNORE( iWaitDialog->ProcessFinishedL() ); + } + + if ( iResourceOffset ) + { + CEikonEnv::Static()->DeleteResourceFile( iResourceOffset ); + } + if ( iAppUiResourceOffset ) + { + CEikonEnv::Static()->DeleteResourceFile( iAppUiResourceOffset ); + } + delete iMpxDrmHelper; + } + +// --------------------------------------------------------------------------- +// Check if the host application is messaging or browser +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::IsHostMessagingBrowserL() + { + return ( IsHostMessagingL() || IsHostBrowserL() ); + } + +// --------------------------------------------------------------------------- +// Check if the host application is messaging +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::IsHostMessagingL() + { + TBool ret( EFalse ); + TInt hostUid = MPXTlsHelper::HostUid().iUid; + if ( hostUid == KMPXMmsViewerUid || hostUid == KMPXMmsEditorUid || + hostUid == KMPXMailViewerUid || hostUid == KMPXMailEditorUid || + hostUid == KMPXMessagingUid || hostUid == KMPXUniEditorUid ) + { + ret = ETrue; + } + return ret; + } + +// --------------------------------------------------------------------------- +// Check if the host application is browser +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::IsHostBrowserL() + { + TBool ret( EFalse ); + TInt hostUid = MPXTlsHelper::HostUid().iUid; + if ( hostUid == KMPXBrowserUid || hostUid == KMPXBrowserUid2 ) // browser + { + ret = ETrue; + } + return ret; + } + +// --------------------------------------------------------------------------- +// Check if the host application is Podcasting Application +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::IsHostPodcastingAppL() + { + return MPXTlsHelper::HostUid().iUid == KPodcastingAppUid; + } + +// --------------------------------------------------------------------------- +// Convert to displayable duration. +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC* CMPXCommonUiHelper::DisplayableDurationL( + TInt64 aDuration, + TMPXDuratDisplayMode aMode ) + { + TInt resId; + HBufC* format = NULL; + if ( aDuration >= KMPXOneHundredHoursInSecs ) + { + resId = R_MPX_TIME_DURAT_HHHMMSS_WITH_ZERO; + format = StringLoader::LoadLC( + resId, aDuration / KMPXOneHourInSeconds ); + } + else + { + resId = R_QTN_TIME_DURAT_MIN_SEC_WITH_ZERO; + if ( ( aMode == EMPXDuratHMS ) || + ( aDuration >= KMPXOneHourInSeconds ) ) + { + resId = R_QTN_TIME_DURAT_LONG_WITH_ZERO; + } + format = StringLoader::LoadLC( resId ); + } + + // Convert total playing time to texts. + TTime durTime( aDuration * KMPXOneSecInMicroSecs ); + + HBufC* buf = + HBufC::NewLC( format->Length() + KMPXDurationDisplayResvLen ); + TPtr bufTPtr( buf->Des() ); + + durTime.FormatL( bufTPtr, *format ); + AknTextUtils::LanguageSpecificNumberConversion( bufTPtr ); + CleanupStack::Pop( buf ); + CleanupStack::PopAndDestroy( format ); + + return buf; + } + +// --------------------------------------------------------------------------- +// Convert to displayable duration in text format. +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC* CMPXCommonUiHelper::DisplayableDurationInTextL( + TInt64 aDuration ) + { + HBufC* buf = NULL; + TInt days = I64INT( aDuration / KMPXOneDayInSeconds ); + TInt hours = + I64INT( ( aDuration % KMPXOneDayInSeconds ) / + KMPXOneHourInSeconds ); + TInt mins = + I64INT( ( aDuration % KMPXOneHourInSeconds ) / + KMPXOneMinInSeconds ); + TInt secs = I64INT( aDuration % KMPXOneMinInSeconds ); + + CArrayFix< TInt >* intArray = + new ( ELeave ) CArrayFixFlat( 2 ); // magic number + CleanupStack::PushL( intArray ); + + if ( days > 1 && ( hours == 0 || hours > 1 ) ) + { + intArray->AppendL( days ); + intArray->AppendL( hours ); + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_DAYS_HRS_TEXT, *intArray ); + } + else if ( days > 1 && hours == 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_DAYS_HR_TEXT, days ); + } + else if ( days == 1 && ( hours == 0 || hours > 1 ) ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_DAY_HRS_TEXT, hours ); + } + else if ( days == 1 && hours == 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_DAY_HR_TEXT ); + } + else if ( hours > 1 && ( mins == 0 || mins > 1 ) ) + { + intArray->AppendL( hours ); + intArray->AppendL( mins ); + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_HRS_MINS_TEXT, *intArray ); + } + else if ( hours > 1 && mins == 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_HRS_MIN_TEXT, hours ); + } + else if ( hours == 1 && ( mins == 0 || mins > 1 ) ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_HR_MINS_TEXT, mins ); + } + else if ( hours == 1 && mins == 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_HR_MIN_TEXT ); + } + else if ( mins > 1 && ( secs == 0 || secs > 1 ) ) + { + intArray->AppendL( mins ); + intArray->AppendL( secs ); + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_MINS_SECS_TEXT, *intArray ); + } + else if ( mins > 1 && secs == 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_MINS_SEC_TEXT, mins ); + } + else if ( mins == 1 && ( secs == 0 || secs > 1 ) ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_MIN_SECS_TEXT, secs ); + } + else if ( mins == 1 && secs == 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_MIN_SEC_TEXT ); + } + else if ( secs > 1 ) + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_SECS_TEXT, secs ); + } + else + { + buf = StringLoader::LoadLC( R_MPX_CUI_TIME_SEC_TEXT ); + } + + TPtr bufPtr = buf->Des(); + AknTextUtils::LanguageSpecificNumberConversion( bufPtr ); + CleanupStack::Pop( buf ); + CleanupStack::PopAndDestroy( intArray ); + + return buf; + } + +// --------------------------------------------------------------------------- +// Set current file as ringing tone. +// --------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::DoSetAsRingingToneL( + const CMPXMedia& aMedia, + TBool aSetToAllProfiles, + TBool aShowQuery ) + { + TInt rightsStatus( KErrNotFound ); + TBool canSetAutomated( EFalse ); + TBool okToSet( ETrue ); + TBool isProtected( EFalse ); + + if ( aMedia.IsSupported ( KMPXMediaDrmProtected ) ) + { + isProtected = aMedia.ValueTObjectL( KMPXMediaDrmProtected ); + } + if ( isProtected ) + { + if ( aMedia.IsSupported ( KMPXMediaDrmRightsStatus ) ) + { + rightsStatus = aMedia.ValueTObjectL( KMPXMediaDrmRightsStatus ); + } + if ( aMedia.IsSupported ( KMPXMediaDrmCanSetAutomated ) ) + { + canSetAutomated = aMedia.ValueTObjectL( KMPXMediaDrmCanSetAutomated ); + } + } + + if ( ( !isProtected ) || ( rightsStatus == EMPXDrmRightsFull ) + || ( canSetAutomated ) ) + { + if ( aShowQuery && aSetToAllProfiles ) + { + // Show query only if set ringtone to all profiles and needed + CAknQueryDialog* query = + CAknQueryDialog::NewL( CAknQueryDialog::EConfirmationTone ); + okToSet = query->ExecuteLD( + R_MPX_CHANGE_RT_FOR_ALL_CONFIRMATION_QUERY ); + } + + if ( okToSet ) + { + TInt error( KErrNone ); + TInt leaveError( KErrNone ); + CProfileToneHandler* toneHandler = CProfileToneHandler::NewLC(); + + if ( aSetToAllProfiles ) + { + MPX_TRAP( leaveError, error = toneHandler->SetToneForAllProfilesL( + EProfileRingingToneSetting, + aMedia.ValueText( KMPXMediaGeneralUri ) ) ); + } + else + { + MPX_TRAP( leaveError, error = toneHandler->SetActiveProfileRingingToneL( + aMedia.ValueText( KMPXMediaGeneralUri ) ) ); + } + if ( leaveError != KErrNone ) + { + error = leaveError; + } + + CleanupStack::PopAndDestroy( toneHandler ); + + if ( KErrNone == error && !aSetToAllProfiles ) + { + HBufC* text = StringLoader::LoadLC( + R_MPX_RINGTONE_SET_TEXT, aMedia.ValueText( + KMPXMediaGeneralTitle ) ); + DisplayConfirmNoteL( *text ); + CleanupStack::PopAndDestroy( text ); + } + else if ( KErrPermissionDenied == error ) + { + DisplayInfoNoteL( R_MPX_RINGTONE_UNPROTECTED_FILE_TEXT ); + } + else if ( KErrArgument == error || + KErrAccessDenied == error ) + { + DisplayInfoNoteL( R_MPX_RINGTONE_NOT_ALLOWED_TEXT ); + } + else if ( KErrNotFound == error ) + { + DisplayInfoNoteL( R_MPX_FILE_NOT_FOUND_TEXT ); + } + else + { + // do nothing + } + } + } + else + { + DisplayInfoNoteL( R_MPX_DRM_PREV_RIGHTS_SET ); + } + } + +// ----------------------------------------------------------------------------- +// Check if current profile mode is offline mode. +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::IsProfileOfflineModeL() + { + TBool isOfflineMode( EFalse ); + MProfileEngine* profileEngine; + profileEngine = CreateProfileEngineL(); + + if ( profileEngine->ActiveProfileId() == EProfileOffLineId ) + { + isOfflineMode = ETrue; + } + profileEngine->Release(); + + return isOfflineMode; + } + +// ----------------------------------------------------------------------------- +// Returns a path of the default drive used for saving playlists, ringtones, +// downloads and attachments. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC* CMPXCommonUiHelper::DefaultDriveLC() + { +#ifdef RD_MULTIPLE_DRIVE + // Use an internal mass storage drive as the default drive. If no internal + // drive (other than the phone memory) exists, use an external drive. + // Otherwise use the phone memory. + RFs& fs = CEikonEnv::Static()->FsSession(); + TDriveList driveList; + TInt driveCount(0); + TInt defaultInternalDrive(0); + TInt defaultExternalDrive(0); + TBool foundInternalDrive(EFalse); + TBool foundExternalDrive(EFalse); + User::LeaveIfError( DriveInfo::GetUserVisibleDrives( + fs, driveList, driveCount ) ); + + for( TInt driveNum = EDriveA; + ( driveNum <= EDriveZ ) && !foundInternalDrive; + driveNum++ ) + { + if ( driveList[driveNum] && ( driveNum != EDriveC ) ) // ignore C: drive + { + // Get the drive status + TUint driveStatus(0); + DriveInfo::GetDriveStatus( fs, driveNum, driveStatus ); + + if ( driveStatus & DriveInfo::EDriveInternal ) + { + defaultInternalDrive = driveNum; + foundInternalDrive = ETrue; + } // internal mass store drive + else if ( !foundExternalDrive && + (driveStatus & + (DriveInfo::EDriveRemovable | DriveInfo::EDriveRemote)) ) + { + TVolumeInfo volumeInfo; + TInt errCode = fs.Volume( volumeInfo, driveNum ); + if( errCode == KErrNone ) + { + //driveNum is really ready for use + defaultExternalDrive = driveNum; + foundExternalDrive = ETrue; + } + } // external drive + } // if (available drive) + } // for (all available drives) + + // Use the internal drive, external drive or phone memory as the default + // path + HBufC* defaultRootPath = HBufC::NewLC( 10 ); + TPtr pathPtr( defaultRootPath->Des() ); + if ( foundInternalDrive ) + { + User::LeaveIfError( + PathInfo::GetRootPath( pathPtr, defaultInternalDrive ) ); + } + else if ( foundExternalDrive ) + { + User::LeaveIfError( + PathInfo::GetRootPath( pathPtr, defaultExternalDrive ) ); + } + else // use phone memory path + { + pathPtr.Copy( PathInfo::PhoneMemoryRootPath() ); + } + + MPX_DEBUG2("CMPXCommonUiHelper::DefaultDriveLC - path = %S", &pathPtr); +#else + HBufC* defaultRootPath = NULL; + // Default drive used for saving playlists, etc + // is as following: + // 1. if E: drive exists ( MMC card inserted ) + // playlist will be saved on the E: drive unless + // ( mmc is locked, readonly, or below critical disk space) + // 2. E drive is not present ( MMC card ejected ), save the + // playlist on the phone memory instead. + + TChar drive; + if ( !IsMemoryCardWritable( drive ) ) + { + // load phone memory root path + defaultRootPath = StringLoader::LoadLC( + R_MPX_CUI_PHONE_MEMORY_ROOT_PATH ); + } + else + { + defaultRootPath = HBufC::NewLC( 10 ); + TPtr ptr( defaultRootPath->Des() ); + ptr.Append( drive ); + ptr.Append( KDriveFormatString ); + } +#endif // RD_MULTIPLE_DRIVE + return defaultRootPath; + } + +// ----------------------------------------------------------------------------- +// Returns a path of the next available drive used for saving playlists, ringtones, +// downloads and attachments. The order of priority is internal mass store, +// MMC, then phone memory. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC* CMPXCommonUiHelper::AvailableDriveLC( TInt aSize ) + { +#ifdef RD_MULTIPLE_DRIVE + // Use an available mass storage drive (other than the phone memory). If + // none exists, use an external drive. Otherwise use the phone memory. + RFs& fs = CEikonEnv::Static()->FsSession(); + TDriveList driveList; + TInt driveCount(0); + TInt availableInternalDrive(0); + TInt availableExternalDrive(0); + TBool foundInternalDrive(EFalse); + TBool foundExternalDrive(EFalse); + User::LeaveIfError( DriveInfo::GetUserVisibleDrives( + fs, driveList, driveCount ) ); + + for( TInt driveNum = EDriveA; + ( driveNum <= EDriveZ ) && !foundInternalDrive; + driveNum++ ) + { + if ( driveList[driveNum] && ( driveNum != EDriveC ) ) // ignore C: drive + { + // Get the drive status + TUint driveStatus(0); + DriveInfo::GetDriveStatus( fs, driveNum, driveStatus ); + + if ( driveStatus & DriveInfo::EDriveInternal ) + { + // Ensure there is enough disk space for the file + TBool internalDriveBelowCritical = EFalse; + MPX_TRAPD( err, internalDriveBelowCritical = + SysUtil::DiskSpaceBelowCriticalLevelL( + &fs, aSize, driveNum ) ); + if ( internalDriveBelowCritical ) + { + MPX_DEBUG2("CMPXCommonUiHelper::AvailableDriveLC - Internal drive below critical driveNum=%d", driveNum); + } + else if ( err == KErrNone ) + { + availableInternalDrive = driveNum; + foundInternalDrive = ETrue; + } + } // internal mass store drive + else if ( !foundExternalDrive && + (driveStatus & + (DriveInfo::EDriveRemovable | DriveInfo::EDriveRemote)) ) + { + TBool externalDriveBelowCritical = EFalse; + MPX_TRAPD( err, externalDriveBelowCritical = + SysUtil::DiskSpaceBelowCriticalLevelL( + &fs, aSize, driveNum ) ); + if ( externalDriveBelowCritical ) + { + MPX_DEBUG2("CMPXCommonUiHelper::AvailableDriveLC - External drive below critical driveNum=%d", driveNum); + } + else if ( err == KErrNone ) + { + availableExternalDrive = driveNum; + foundExternalDrive = ETrue; + } + } // external drive + } // if (available drive) + } // for (all available drives) + + // Use the internal drive, external drive or phone memory as the default + // path + HBufC* defaultRootPath = HBufC::NewLC( 10 ); + TPtr pathPtr( defaultRootPath->Des() ); + if ( foundInternalDrive ) + { + User::LeaveIfError( + PathInfo::GetRootPath( pathPtr, availableInternalDrive ) ); + } + else if ( foundExternalDrive ) + { + User::LeaveIfError( + PathInfo::GetRootPath( pathPtr, availableExternalDrive ) ); + } + else // use phone memory path + { + pathPtr.Copy( PathInfo::PhoneMemoryRootPath() ); + } + + MPX_DEBUG2("CMPXCommonUiHelper::AvailableDriveLC - path = %S", &pathPtr); + return defaultRootPath; +#else + (void) aSize; + return NULL; +#endif // RD_MULTIPLE_DRIVE + } + +// ----------------------------------------------------------------------------- +// Display information note +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::DisplayInfoNoteL( TInt aResourceId ) + { + HBufC* text = StringLoader::LoadLC( aResourceId ); + DisplayInfoNoteL( *text ); + CleanupStack::PopAndDestroy( text ); + } + +// ----------------------------------------------------------------------------- +// Display information note +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::DisplayInfoNoteL( const TDesC& aText ) + { + CAknInformationNote* dlg = new ( ELeave ) CAknInformationNote( ETrue ); + dlg->ExecuteLD( aText ); + } + +// ----------------------------------------------------------------------------- +// Display confirmation note +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::DisplayConfirmNoteL( TInt aResourceId ) + { + HBufC* text = StringLoader::LoadLC( aResourceId ); + +// Cover UI start +//#ifdef __COVER_DISPLAY + DisplayConfirmNoteL( *text, aResourceId ); +//#else +// DisplayConfirmNoteL( *text ); +//#endif // __COVER_DISPLAY +// CoverUI end + + CleanupStack::PopAndDestroy( text ); + } + +// ----------------------------------------------------------------------------- +// Display confirmation note +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::DisplayConfirmNoteL( const TDesC& aText ) + { + CAknConfirmationNote* dlg = new ( ELeave ) CAknConfirmationNote( ETrue ); + dlg->ExecuteLD( aText ); + } + +// Cover UI start +//#ifdef __COVER_DISPLAY +// ----------------------------------------------------------------------------- +// Display confirmation note +// ----------------------------------------------------------------------------- +// +void CMPXCommonUiHelper::DisplayConfirmNoteL( + const TDesC& aText, + TInt aResourceId ) + { + CAknConfirmationNote* dlg = new ( ELeave ) CAknConfirmationNote( ETrue ); + + CleanupStack::PushL( dlg ); + if ( aResourceId == R_MPX_SAVED_TO_COLLECTION_NOTE ) + { + dlg->PublishDialogL( + EMPlayerNoteSavedtoCollection, + KMPlayerNoteCategory); + } + else if ( aResourceId == R_MPX_SAVED_NOTE ) + { + dlg->PublishDialogL( + EMPlayerNoteSavedtoGallery, + KMPlayerNoteCategory); + } + CleanupStack::Pop( dlg ); + + dlg->ExecuteLD( aText ); + } +//#endif // __COVER_DISPLAY +// Cover UI end + +// ----------------------------------------------------------------------------- +// Convert a value from bytes to kB/MB/GB. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC* CMPXCommonUiHelper::UnitConversionL( TInt64 aByte, TBool aFree ) + { + HBufC* res = NULL; + + if ( aByte >= 0 && aByte < KMPXOneKB ) // unit is B + { + if ( aFree ) + { + res = StringLoader::LoadLC( R_MPX_CUI_MEMORY_B_FREE, aByte ); + } + else + { + res = StringLoader::LoadLC( R_MPX_CUI_MEMORY_B, aByte ); + } + } + else // unit is larger than a byte and must be displayed with decimal + { + TReal memoryUnitSize; + TInt memoryUnitResId; + + if ( aByte >= KMPXOneKB && aByte < KMPXOneMB ) // unis is kB + { + memoryUnitSize = KMPXOneKB; + if ( aFree) + { + memoryUnitResId = R_MPX_CUI_MEMORY_KB1_FREE; + } + else + { + memoryUnitResId = R_MPX_CUI_MEMORY_KB; + } + } + else if ( aByte >= KMPXOneMB && aByte < KMPXOneGB ) // unit is MB + { + memoryUnitSize = KMPXOneMB; + if ( aFree ) + { + memoryUnitResId = R_MPX_CUI_MEMORY_MB1_FREE; + } + else + { + memoryUnitResId = R_MPX_CUI_MEMORY_MB; + } + } + else // unit is GB + { + memoryUnitSize = KMPXOneGB; + if ( aFree ) + { + memoryUnitResId = R_MPX_CUI_MEMORY_GB1_FREE; + } + else + { + memoryUnitResId = R_MPX_CUI_MEMORY_GB; + } + } + + TBuf sizeBuf; + TRealFormat format = TRealFormat( KMPXWidthOfChar, KMPXDecimalPlaces ); + TReal tmpValue = ( I64REAL(aByte) / memoryUnitSize ); + sizeBuf.AppendNum( tmpValue, format ); + if ( User::Language() == ELangArabic ) + { + sizeBuf.Append( KRightToLeftMark ); + } + res = StringLoader::LoadLC( memoryUnitResId, sizeBuf ); + } + CleanupStack::Pop( res ); + return res; + } + +// ----------------------------------------------------------------------------- +// Finds all user playlists in the given collection +// ----------------------------------------------------------------------------- +// +EXPORT_C CMPXMedia* CMPXCommonUiHelper::FindPlaylistsL() + { + MPX_FUNC( "CMPXCommonUiHelper::FindPlaylistsL" ); + + RArray attrs; + CleanupClosePushL( attrs ); + attrs.Append( KMPXMediaGeneralTitle ); + attrs.Append( KMPXMediaGeneralId ); + attrs.Append( KMPXMediaGeneralFlags ); + + CMPXMedia* ret = FindAllL( EMPXPlaylist, attrs.Array() ); + CleanupStack::PopAndDestroy( &attrs ); + + return ret; + } + +// ----------------------------------------------------------------------------- +// Add to saved playlist +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::AddToSavedPlaylistL( + const CMPXMedia& aPlaylists, const CMPXMedia& aTracks, + MMPXCHelperObserver* aObserver, MProgressDialogCallback* aCallback ) + { + MPX_FUNC( "CMPXCommonUiHelper::AddToSavedPlaylistL" ); + + TBool ret( EFalse ); + + const CMPXMediaArray* mediaArray = + aPlaylists.Value( KMPXMediaArrayContents ); + User::LeaveIfNull( const_cast( mediaArray )); + + TInt count( 0 ); + if ( mediaArray ) + { + count = mediaArray->Count(); + } + else + { + User::Leave( KErrArgument ); + } + + if ( count < 1) + { + User::Leave( KErrArgument ); + } + else + { + TInt index = 0; + CAknListQueryDialog* queryDlg = + new ( ELeave ) CAknListQueryDialog( &index ); + queryDlg->PrepareLC( R_MPX_CUI_PLAYLIST_QUERY_LIST ); + +//#ifdef __COVER_DISPLAY + queryDlg->PublishDialogL( + EMPlayerQuerySelectPlaylist, KMPlayerNoteCategory ); +//#endif //__COVER_DISPLAY + + // Get the text array from the listbox model + CTextListBoxModel* lbxModel = + static_cast( queryDlg->ListBox()->Model() ); + CDesCArray* descArray = + static_cast( lbxModel->ItemTextArray() ); + descArray->Reset(); + + // Set up icon array + CAknIconArray* icons = new ( ELeave ) CAknIconArray( 1 ); // magic: icon count + CleanupStack::PushL( icons ); + TParse mbmFileName; + mbmFileName.Set( KMPXCommonUiIconFile, + &KDC_APP_RESOURCE_DIR, NULL ); + TFileName iconFile( mbmFileName.FullName() ); + User::LeaveIfError( MPXUser::CompleteWithDllPath( iconFile ) ); + + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconLC( + AknsUtils::SkinInstance(), // aInstance + KAknsIIDQgnIndiMmcAdd, // aID + KAknsIIDQsnIconColors, // aColorID + EAknsCIQsnIconColorsCG26, // aColorIndex + bitmap, + mask, + iconFile, + EMbmMpxcommonuiQgn_indi_mmc_add, + EMbmMpxcommonuiQgn_indi_mmc_add_mask, + KRgbBlack ); // aDefaultColor + CGulIcon* icon = CGulIcon::NewL( bitmap, mask ); + icon->SetBitmapsOwnedExternally( EFalse ); + + // icon now owns the bitmaps, no need to keep on cleanup stack. + CleanupStack::Pop(2); // mask, bitmap + bitmap = NULL; + mask = NULL; + CleanupStack::PushL( icon ); + icons->AppendL( icon ); + queryDlg->SetIconArrayL(icons); + CleanupStack::Pop( icon ); + CleanupStack::Pop( icons ); + + TInt mmc = MMCDriveNumber(); + // Prepare for query dialog + for ( TInt i = 0; i < count; i++ ) + { + CMPXMedia* media( mediaArray->AtL( i )); + TUint flags( 0 ); + TRAP_IGNORE(flags = media->ValueTObjectL( KMPXMediaGeneralFlags )) + TInt driveNum = ( ( flags ) & ( KMPXMediaGeneralFlagsDriveInfo ) ); + HBufC* line = NULL; + HBufC* title = media->ValueText( KMPXMediaGeneralTitle ).AllocLC(); + + if( driveNum == mmc ) + { + line = HBufC::NewLC( + KMPXAddToPlaylistMemoryCardIcon().Length() + + title->Length() ); + TPtr linePtr = line->Des(); + linePtr += *title; + linePtr.Append( KMPXAddToPlaylistMemoryCardIcon ); + } + else + { + line = title->AllocLC(); + } + descArray->AppendL( *line ); + CleanupStack::PopAndDestroy( line ); + CleanupStack::PopAndDestroy( title ); + } + + if ( queryDlg->RunLD() ) + { + if ( index >= 0 ) + { + CMPXMedia* media( mediaArray->AtL( index )); + TMPXItemId playlistId = + media->ValueTObjectL( KMPXMediaGeneralId ); + const CMPXMediaArray* tracksArray = + aTracks.Value( KMPXMediaArrayContents ); + User::LeaveIfNull( const_cast( tracksArray )); + if ( tracksArray->Count() < 1 ) + { + User::Leave( KErrArgument ); + } + else + { + if ( tracksArray->Count() == 1 ) + { + HBufC* text = StringLoader::LoadLC( + R_MPX_QTN_NMP_NOTE_ADDING_ONE_SONG ); + ShowWaitNoteL( *text, + R_AVKON_SOFTKEYS_EMPTY, ETrue, aCallback ); + CleanupStack::PopAndDestroy( text ); + } + else + { + HBufC* text = StringLoader::LoadLC( + R_MPX_QTN_MUS_NOTE_ADDING_TRACKS ); + ShowWaitNoteL( *text, + R_MPX_WAITNOTE_SOFTKEYS_EMPTY_STOP, ETrue, aCallback ); + CleanupStack::PopAndDestroy( text ); + } + CMPXMedia* media = CMPXMedia::NewL(); + CleanupStack::PushL( media ); + media->SetTObjectValueL( + KMPXMediaGeneralId, playlistId ); + media->SetTObjectValueL( + KMPXMediaGeneralType, EMPXItem ); + media->SetTObjectValueL( + KMPXMediaGeneralCategory, EMPXPlaylist ); + media->SetCObjectValueL( + KMPXMediaArrayContents, + const_cast(tracksArray )); + media->SetTObjectValueL( + KMPXMediaArrayCount, tracksArray->Count() ); + + RArray ary; + CleanupClosePushL( ary ); + ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) ); + TUid musicCollection = iCollectionUtility->CollectionIDL( ary.Array() ); + CleanupStack::PopAndDestroy( &ary ); + + media->SetTObjectValueL( KMPXMediaGeneralCollectionId, musicCollection ); + + if ( !iCollectionUiHelper ) + { + iCollectionUiHelper = CMPXCollectionHelperFactory::NewCollectionUiHelperL(); + } + iCollectionUiHelper->IncAddL( *media, aObserver, KMPXChunkSize ); + ret = ETrue; + CleanupStack::PopAndDestroy( media ); + } + } + } + } + return ret; + } + +// ----------------------------------------------------------------------------- +// Create playlist +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::CreatePlaylistL( + const CMPXMedia& aTracks, MMPXCHelperObserver* aObserver, + MProgressDialogCallback* aCallback ) + { + MPX_FUNC( "CMPXCommonUiHelper::CreatePlaylistL" ); + + RFs& fs = CEikonEnv::Static()->FsSession(); + HBufC* playlistName = HBufC::NewLC( KMaxFileName ); + TPtr playlistNamePtr = playlistName->Des(); + const TInt playListSize = 8; + +#ifdef RD_MULTIPLE_DRIVE + // Create playlist on the next available drive (internal mass store, + // MMC or phone memory) + HBufC* defaultRootPath = AvailableDriveLC( playListSize ); + playlistNamePtr = *defaultRootPath; + CleanupStack::PopAndDestroy( defaultRootPath ); +#else + HBufC* defaultRootPath = DefaultDriveLC(); + playlistNamePtr = *defaultRootPath; + CleanupStack::PopAndDestroy( defaultRootPath ); + + if ( playlistNamePtr.CompareF( PathInfo::MemoryCardRootPath() ) == 0 ) + { + // only if memory card is supported, check if there is enough space + // on the card. + TBool isBelowCritical = EFalse; + MPX_TRAPD( err, isBelowCritical = SysUtil::MMCSpaceBelowCriticalLevelL( + &fs, playListSize ) ); + if ( err || isBelowCritical ) + { + MPX_DEBUG1( "CMPXCommonUiHelper::CreatePlaylistL Error in MMC, default path changed to phone memory" ); + playlistNamePtr = PathInfo::PhoneMemoryRootPath(); + } + } +#endif // RD_MULTIPLE_DRIVE + + HBufC* defaultPath = + StringLoader::LoadLC( R_MPX_CUI_TARGETFOLDER_PLAYLIST ); + playlistNamePtr += *defaultPath; + CleanupStack::PopAndDestroy( defaultPath ); + + TBool ret( PlaylistCreationQueriesL( playlistNamePtr ) ); + if ( ret ) + { + MPX_DEBUG2( "CMPXCommonUiHelper::CreatePlaylistL Saving playlist %S", &playlistNamePtr ); + const CMPXMediaArray* tracksArray = + aTracks.Value( KMPXMediaArrayContents ); + User::LeaveIfNull( const_cast( tracksArray )); + if ( tracksArray->Count() == 1 ) + { + HBufC* text = StringLoader::LoadLC( + R_MPX_QTN_NMP_NOTE_ADDING_ONE_SONG ); + ShowWaitNoteL( *text, + R_AVKON_SOFTKEYS_EMPTY, ETrue, aCallback ); + CleanupStack::PopAndDestroy( text ); + } + else if ( tracksArray->Count() > 0 ) + { + // only show wait note if we're adding more than 1 song + HBufC* text = StringLoader::LoadLC( + R_MPX_QTN_MUS_NOTE_ADDING_TRACKS ); + ShowWaitNoteL( *text, + R_MPX_WAITNOTE_SOFTKEYS_EMPTY_STOP, ETrue, aCallback ); + CleanupStack::PopAndDestroy( text ); + } + + CMPXMedia* media = CMPXMedia::NewL(); + CleanupStack::PushL( media ); + media->SetTObjectValueL( + KMPXMediaGeneralType, EMPXItem ); + media->SetTObjectValueL( + KMPXMediaGeneralCategory, EMPXPlaylist ); + TParsePtrC fn( playlistNamePtr ); + // no extension in virtual playlist, all "extension" are inputed + // by users as a valid name + media->SetTextValueL( + KMPXMediaGeneralTitle, fn.NameAndExt() ); + + media->SetCObjectValueL( + KMPXMediaArrayContents, + const_cast(tracksArray ) ); + media->SetTObjectValueL( + KMPXMediaArrayCount, tracksArray->Count() ); + media->SetTextValueL( + KMPXMediaGeneralUri, fn.DriveAndPath() ); // exculde the file name + // new playlist + if ( !iCollectionUiHelper ) + { + iCollectionUiHelper = CMPXCollectionHelperFactory::NewCollectionUiHelperL(); + } + iCollectionUiHelper->IncAddL( *media, aObserver, KMPXChunkSize ); + CleanupStack::PopAndDestroy( media ); + } + CleanupStack::PopAndDestroy( playlistName ); + return ret; + } + +// ----------------------------------------------------------------------------- +// Launch rename dialog +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMPXCommonUiHelper::LaunchRenameDialogL( + const TDesC& aOldName, + TDes& aNewName, + const TDesC& aPath ) + { + MPX_FUNC( "CMPXCommonUiHelper::LaunchRenameDialogL" ); + CMPXFileNameQueryDlg* renameDlg = CMPXFileNameQueryDlg::NewL( + aOldName, aNewName, aPath, EMPXPlaylist, this ); + TInt ret = renameDlg->ExecuteLD( R_MPX_FILE_NAME_QUERY ); + + if ( ret ) + { + if ( aNewName.CompareF( aOldName ) == 0 ) + { + ret = EFalse; + } + else + { + if ( !iCollectionUiHelper ) + { + iCollectionUiHelper = CMPXCollectionHelperFactory::NewCollectionUiHelperL(); + } + if ( iCollectionUiHelper->TitleExistsL( EMPXPlaylist, aNewName, EMPXOtherType ) ) + { + HBufC* info = StringLoader::LoadLC( R_MPX_PLAYLIST_NAME_EXIST, aNewName ); + + if( CEikonEnv::Static()->QueryWinL( KNullDesC, *info ) ) + { + if ( !LaunchRenameDialogL( aOldName, aNewName, aPath ) ) + { + ret = EFalse; + } + } + else + { + ret = EFalse; + } + CleanupStack::PopAndDestroy( info );//query ,info + } + } + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// Shows wait note +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::ShowWaitNoteL( TDesC& aText, TInt aCBAId, + TBool aVisibilityDelayOff, MProgressDialogCallback* aCallback, TInt aResId ) + { + MPX_FUNC( "CMPXCommonUiHelper::ShowWaitNoteL" ); + if( iWaitDialog ) + { + // if wait note is already running + // cancel it and recreate will have timing issues + if ( aCallback ) + { + iWaitDialog->SetCallback( aCallback ); + } + iWaitDialog->SetTextL( aText ); + MEikButtonGroup* buttonGroup = + iWaitDialog->ButtonGroupContainer().ButtonGroup(); + if ( aCBAId ) + { + buttonGroup->SetCommandSetL( aCBAId ); + } + buttonGroup->AsControl()->DrawDeferred(); + iWaitDialog->DrawDeferred(); + } + else + { + iWaitDialog = new ( ELeave ) CAknWaitDialog( + ( CEikDialog** )&iWaitDialog, aVisibilityDelayOff ); + if ( aCallback ) + { + iWaitDialog->SetCallback( aCallback ); + } + iWaitDialog->PrepareLC( aResId ); + iWaitDialog->SetTextL( aText ); + MEikButtonGroup* buttonGroup = + iWaitDialog->ButtonGroupContainer().ButtonGroup(); + if ( aCBAId ) + { + buttonGroup->SetCommandSetL( aCBAId ); + } + buttonGroup->AsControl()->DrawDeferred(); + iWaitDialog->RunLD(); + } + } + +// ----------------------------------------------------------------------------- +// Dismiss wait note +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::DismissWaitNoteL() + { + MPX_FUNC( "CMPXCommonUiHelper::DismissWaitNoteL" ); + if( iWaitDialog ) + { + iWaitDialog->ProcessFinishedL(); + } + } + +// ----------------------------------------------------------------------------- +// Handles displaying the error message for given error code +// according to the media object provided +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMPXCommonUiHelper::HandleErrorL( + TInt aError, + const CMPXMedia* aMedia, /*=NULL*/ + RFile* aFile /*=NULL*/ ) + { + MPX_DEBUG2("CMPXCommonUiHelper::HandleErrorL(%d) entering", aError); + + TBool usingGlobalNote = EFalse; // To use CAknGlobalNote if necessary + TInt ret( KErrNone ); + CTextResolver* textResolver( NULL ); + HBufC* errorText( NULL ); + switch ( aError ) + { + case KMPXRightsAboutToExpire: + case KErrCANotSupported: + case KErrCANoPermission: + case KErrCANoRights: + case KErrCANoAgent: + case KErrCAOutOfRange: + case KErrCAPendingRights: + case KErrCASizeNotDetermined: + case KErrCANewFileHandleRequired: + { + TRAPD(err, ret = iMpxDrmHelper->HandleDrmErrorL( aError, aMedia, aFile )); + if (err) + { + ret = err; + if ( ret == KErrArgument ) + // If error is KErrArgument, map it to R_MPX_INVALID_CLIP + errorText = StringLoader::LoadLC( R_MPX_INVALID_CLIP ); + else + { + // TextResolver instance for error resolving. + textResolver = CTextResolver::NewLC(); + // Resolve the error text + const TDesC& text = + textResolver->ResolveErrorString( ret ); + errorText = text.AllocLC(); + } + } + break; + } + case KMPXAllTracksInvalid: + { + errorText = + StringLoader::LoadLC( R_MPX_INVALID_GROUP_TEXT ); + break; + } + case KErrNotSupported: + case KErrCorrupt: + { + errorText = StringLoader::LoadLC( R_MPX_INVALID_CLIP ); + break; + } + case KErrAccessDenied: + { + if ( aMedia ) + { + if ( aMedia->IsSupported( KMPXMediaDrmType ) ) + { + TMPXMediaDrmType type = + aMedia->ValueTObjectL( KMPXMediaDrmType ); + if ( EMPXDrmTypeOMA == type ) + { + errorText = StringLoader::LoadLC( R_MPX_NO_DRM_OVER_BT ); + break; + } + } + } + // fall through on purpose to use default handling + // if error was not handled above + } + case KMPXErrorVideoCall: + { + errorText = StringLoader::LoadLC( R_MPX_VIDEO_CALL_ONGOING ); + usingGlobalNote = ETrue; + break; + } + case KErrLocked: + errorText = StringLoader::LoadLC( R_MPX_CANNOT_PROCEED_WITH_OPERATION ); + break; + case KErrDisMounted: + break; + case KErrDiskFull: + case KSQLErrGeneral: + errorText = StringLoader::LoadLC( R_MPX_CUI_MEMLO_NOT_ENOUGH_MEMORY ); + break; + default: + { + // TextResolver instance for error resolving. + textResolver = CTextResolver::NewLC(); + // Resolve the error text + const TDesC& text = + textResolver->ResolveErrorString( aError ); + errorText = text.AllocLC(); + break; + } + } + + if ( errorText ) + { + if ( !usingGlobalNote ) + { + CAknErrorNote* dlg = new ( ELeave ) CAknErrorNote( ETrue ); + dlg->ExecuteLD( *errorText ); + } + else + { + // CAknErrorNote will not display when mpx is not currently foreground, + // so if necessary, use CAknGlobalNote to replace it. + CAknGlobalNote* globalInfoNote = CAknGlobalNote::NewLC(); + globalInfoNote->ShowNoteL( + EAknGlobalInformationNote, + errorText->Des() ); + CleanupStack::PopAndDestroy( globalInfoNote ); + } + CleanupStack::PopAndDestroy( errorText ); + } + if ( textResolver ) + { + CleanupStack::PopAndDestroy( textResolver ); + } + + MPX_DEBUG2("CMPXCommonUiHelper::HandleErrorL() exiting, returning %d", ret); + return ret; + } + +// --------------------------------------------------------------------------- +// Sets middle softkey label. +// --------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::SetMiddleSoftKeyLabelL( + CEikButtonGroupContainer& aCba, + TInt aResourceId, + TInt aCommandId ) + { +#ifdef __ENABLE_MSK + MPX_FUNC( "CMPXCommonUiHelper::SetMiddleSoftKeyLabelL" ); + aCba.RemoveCommandFromStack( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + aCba.ButtonGroup()->CommandId( + CEikButtonGroupContainer::EMiddleSoftkeyPosition ) ); + HBufC* middleSKText = StringLoader::LoadLC( aResourceId ); + TPtr mskPtr = middleSKText->Des(); + aCba.AddCommandToStackL( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + aCommandId, + mskPtr ); + CleanupStack::PopAndDestroy( middleSKText ); +#else + (void)aCba; + (void)aResourceId; + (void)aCommandId; + User::Leave( KErrNotSupported ); +#endif // __ENABLE_MSK + } + +// --------------------------------------------------------------------------- +// Removes middle softkey label. +// --------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::RemoveMiddleSoftKeyLabel( + CEikButtonGroupContainer& aCba ) + { +#ifdef __ENABLE_MSK + MPX_FUNC( "CMPXCommonUiHelper::RemoveMiddleSoftKeyLabel" ); + aCba.RemoveCommandFromStack( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + aCba.ButtonGroup()->CommandId( + CEikButtonGroupContainer::EMiddleSoftkeyPosition ) ); + TRAP_IGNORE( aCba.AddCommandToStackL( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + EAknSoftkeyEmpty, // no action + KNullDesC() ) ); // empty label + +#else + (void)aCba; + ASSERT(0); +#endif // __ENABLE_MSK + } + +// --------------------------------------------------------------------------- +// Sets middle softkey icon. +// --------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::SetMiddleSoftKeyIconL( + CEikButtonGroupContainer& aCba, + CFbsBitmap* aBitmap, + CFbsBitmap* aMask ) + { +#ifdef __ENABLE_MSK + MPX_FUNC( "CMPXCommonUiHelper::SetMiddleSoftKeyIconL" ); + aCba.RemoveCommandFromStack( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + aCba.ButtonGroup()->CommandId( + CEikButtonGroupContainer::EMiddleSoftkeyPosition ) ); + aCba.AddCommandToStackL( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + EAknSoftkeyContextOptions, + *aBitmap, + *aMask ); + +#else + (void)aCba; + (void)aBitmap; + (void)aMask; + User::Leave( KErrNotSupported ); +#endif // __ENABLE_MSK + } + +// --------------------------------------------------------------------------- +// Generate the next available title from the given title +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC* CMPXCommonUiHelper::GenerateTitleL( TMPXGeneralCategory aCategory, + const TDesC& aBaseTitle ) + { + MPX_FUNC( "CMPXCommonUiHelper::GenerateTitleL" ); + + // + // Find titles of all playlists in the collection + // + RArray attrs; + CleanupClosePushL( attrs ); + attrs.Append( KMPXMediaGeneralTitle ); + + CMPXMedia* results = FindAllL(aCategory, attrs.Array()); + CleanupStack::PopAndDestroy(&attrs); + CleanupStack::PushL(results); + + if (!results->IsSupported(KMPXMediaArrayContents)) + { + User::Leave(KErrArgument); + } + const CMPXMediaArray* resultArray = results->Value(KMPXMediaArrayContents); + User::LeaveIfNull( const_cast( resultArray )); + + // + // shorten this list by removing those that do not contain this pattern: + // aBaseTitle(*) + // + HBufC* matchingPattern = HBufC::NewLC(aBaseTitle.Length()+KWildCardCharacter().Length()+2); + matchingPattern->Des().Format(KAutoNamingFormat, &aBaseTitle, &KWildCardCharacter); + + CMPXMediaArray* medias = CMPXMediaArray::NewL(); + CleanupStack::PushL(medias); + + TInt count(resultArray->Count()); + + for (TInt i=0; iAtL( i )); + + if (!media->IsSupported(KMPXMediaGeneralTitle)) + { + User::Leave(KErrArgument); + } + + if (media->ValueText(KMPXMediaGeneralTitle).Match(*matchingPattern) != KErrNotFound) + { + medias->AppendL(*media); + } + } + + CleanupStack::Pop(medias); + CleanupStack::PopAndDestroy(2, results); // matchingPattern & results + CleanupStack::PushL(medias); + + // + // determine if the suggested title is already used, if so, suggest another one; + // otherwise, return the suggested title + // + TBool found(EFalse); + TUint autoNumber(0); + + HBufC* autoNumberTextBuf = HBufC::NewLC(KMaxFileName); + TPtr autoNumberText = autoNumberTextBuf->Des(); + + HBufC* suggestedTitle(NULL); + + count = medias->Count(); + + while (!found) + { + autoNumberText.Format( + ++autoNumber < 10 ? KAutoNumberPaddedFormat() : KAutoNumberFormat(), autoNumber); + + AknTextUtils::LanguageSpecificNumberConversion(autoNumberText); + + HBufC* testTitle = HBufC::NewLC(aBaseTitle.Length()+autoNumberText.Length()+2); + testTitle->Des().Format(KAutoNamingFormat, &aBaseTitle, autoNumberTextBuf); + MPX_DEBUG2("testTitle = %S", testTitle); + + TBool exists(EFalse); + for (TInt i=0; iCompare((*medias)[i]->ValueText(KMPXMediaGeneralTitle)) == 0) + { + exists = ETrue; + } + } + + if (!exists) + { + found = ETrue; + suggestedTitle = testTitle; + CleanupStack::Pop(testTitle); + } + else + { + CleanupStack::PopAndDestroy(testTitle); + } + } + + CleanupStack::PopAndDestroy(2, medias); // autoNumberTextBuf & medias + + MPX_DEBUG2("SuggestedTitle = %S", suggestedTitle); + + return suggestedTitle; + } + +// --------------------------------------------------------------------------- +// Checks if Exit option should be hidden +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::ExitOptionHiddenL() + { + MPX_FUNC( "CMPXCommonUiHelper::ExitOptionHiddenL" ); + TInt flags( 0 ); + CRepository* repository = CRepository::NewL( KCRUidMPXMPFeatures ); + repository->Get( KMPXMPLocalVariation, flags ); + delete repository; + return !static_cast( flags & KMPXEnableExitOption ); + } + +// --------------------------------------------------------------------------- +// Sets standalone mode process ID +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::SetStandAloneModePId( TInt64 aPId ) + { + MPX_FUNC( "CMPXCommonUiHelper::SetStandAloneModePId" ); + TInt err( RProperty::Define( + KAppUidMusicPlayerX, KMPXStandAloneProcessIDTop32, RProperty::EInt ) ); + MPX_DEBUG2( "CMPXCommonUiHelper::SetStandAloneModePId() RProperty top err = %d", err ); + if ( err == KErrNone || err == KErrAlreadyExists ) + { + err = RProperty::Define( + KAppUidMusicPlayerX, KMPXStandAloneProcessIDBottom32, RProperty::EInt ); + MPX_DEBUG2( "CMPXCommonUiHelper::SetStandAloneModePId() RProperty bottom err = %d", err ); + } + if ( err == KErrNone || err == KErrAlreadyExists ) + { + MPX_DEBUG2( "CMPXCommonUiHelper::SetStandAloneModePId() proc id = 0x%lx", aPId ); + TInt top32( aPId >> 32 ); + TInt bottom32( aPId & 0xFFFFFFFF ); + err = RProperty::Set( KAppUidMusicPlayerX, + KMPXStandAloneProcessIDTop32, + top32 ); + MPX_DEBUG2( "CMPXCommonUiHelper::SetStandAloneModePId() set top err = %d", err ); + err = RProperty::Set( KAppUidMusicPlayerX, + KMPXStandAloneProcessIDBottom32, + bottom32 ); + MPX_DEBUG2( "CMPXCommonUiHelper::SetStandAloneModePId() set bottom err = %d", err ); + } + return ( err == KErrNone ? ETrue : EFalse ); + } + +// --------------------------------------------------------------------------- +// Gets stand alone mode's process id +// --------------------------------------------------------------------------- +// +EXPORT_C TInt64 CMPXCommonUiHelper::StandAloneModePId() + { + MPX_FUNC( "CMPXCommonUiHelper::StandAloneModePId" ); + TInt ret( 0 ); + TInt64 procId( 0 ); + TInt err( RProperty::Get( + KAppUidMusicPlayerX, KMPXStandAloneProcessIDTop32, ret ) ); + if ( err == KErrNone ) + { + procId = TInt64( ret ) << 32; + err = RProperty::Get( + KAppUidMusicPlayerX, KMPXStandAloneProcessIDBottom32, ret ); + if ( err == KErrNone ) + { + procId += ret; + } + else + { + procId = 0; + } + } + MPX_DEBUG2( "CMPXCommonUiHelper::StandAloneModePId() combined proc id = 0x%lx", procId ); + return procId; + } + +// --------------------------------------------------------------------------- +// Checks if the application with the provided window group id is in foreground +// This method is required because AppUi()->IsForeground() does not work properly +// when the screen saver is active +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CMPXCommonUiHelper::IsForegroundApplication(TInt aWindowGroupId) + { + TBool applicationInForeground(EFalse); + TApaTaskList taskList(CCoeEnv::Static()->WsSession()); + TApaTask taskInForeground = taskList.FindByPos( 0 ); + if ( taskInForeground.Exists() && + (taskInForeground.WgId() == aWindowGroupId)) + { + applicationInForeground = ETrue; + } + return applicationInForeground; + } + +EXPORT_C TInt CMPXCommonUiHelper::MMCDriveNumber() + { +#ifdef RD_MULTIPLE_DRIVE + TInt mmc( 0 ); + TInt r = DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRemovableMassStorage, mmc ); + if (r != KErrNone) + mmc = r; +#else + TParsePtrC memorycardparse( PathInfo::MemoryCardRootPath() ); + TDriveUnit mmc( memorycardparse.Drive() ); +#endif // RD_MULTIPLE_DRIVE + return mmc; + } + +// ---------------------------------------------------------------------------- +// Cancel subsequent operations scheduled by CollectionUiHelper +// ---------------------------------------------------------------------------- +// +EXPORT_C void CMPXCommonUiHelper::CancelCollectionOperation() + { + iCollectionUiHelper->Cancel(); + } + +// ---------------------------------------------------------------------------- +// MPlayerCommonUi::IsMemoryCardWritable +// ---------------------------------------------------------------------------- +// +TBool CMPXCommonUiHelper::IsMemoryCardWritable( TChar& aDrive ) + { + TBool ret = EFalse; + TDriveList driveList; + TInt driveNum( EDriveE ); + CEikonEnv* eikEnv( CEikonEnv::Static() ); + RFs& fs( eikEnv->FsSession() ); + TInt err( fs.DriveList( driveList ) ); + + if ( err == KErrNone ) + { + // search from drive E to drive N (10 drives) + for (; driveNum <= EDriveN; ++driveNum ) + { + // Check that volume is valid (ie. not corrupted) + TVolumeInfo volumeInfo; + err = eikEnv->FsSession().Volume( volumeInfo, driveNum ); + + if ( ( err == KErrNone ) && + ( RFs::DriveToChar( driveNum, aDrive ) == KErrNone ) ) + { + ret = ETrue; + break; + } + } + } + return ret; + } + +// ----------------------------------------------------------------------------- +// CMPXCommonUiHelper::PlaylistCreationQueriesL +// ----------------------------------------------------------------------------- +// +TBool CMPXCommonUiHelper::PlaylistCreationQueriesL( TDes& aPath ) + { + MPX_FUNC( "CMPXCommonUiHelper::PlaylistCreationQueriesL" ); + + TBool ret = EFalse; + + // Get playlist filename + HBufC* playlistFileName = HBufC::NewLC( KMPXMaxPlaylistPathLen ); + TPtr playlistFileNamePtr = playlistFileName->Des(); + playlistFileNamePtr.Copy( aPath ); + User::LeaveIfError( GetNextPlaylistNameL( playlistFileNamePtr ) ); + TParsePtrC parse( playlistFileNamePtr ); + + HBufC* playlistName = + HBufC::NewLC( KMPXMaxPlaylistPathLen ); + TPtr playlistNamePtr = playlistName->Des(); + playlistNamePtr.Copy( parse.NameAndExt() ); + + if ( aPath.Length() > 0 ) + { + ret = PlaylistCreateNameExistL( playlistNamePtr , parse ); + if ( ret ) + { + aPath = parse.DriveAndPath(); + aPath.Append( playlistName->Des() ); + } + } + else + { + HBufC* saveTitle = + StringLoader::LoadLC( R_MPX_PLAYLIST_NAME_QUERY_TITLE ); + aPath.Copy( playlistNamePtr ); + + ret = AknCommonDialogs::RunSaveDlgNoDirectorySelectionLD( aPath, + R_MPX_PLAYLIST_MEMORY_SELECTION_LOCATIONS, *saveTitle ); + + CleanupStack::PopAndDestroy( saveTitle ); + } + + CleanupStack::PopAndDestroy( playlistName ); + CleanupStack::PopAndDestroy( playlistFileName ); + + return ret; + } + +// ----------------------------------------------------------------------------- +// Get next available playlist full pathname based on the information passed. +// ----------------------------------------------------------------------------- +// +TInt CMPXCommonUiHelper::GetNextPlaylistNameL( TDes& aBuf ) + { + MPX_FUNC( "CMPXCommonUiHelper::GetNextPlaylistNameL" ); + // Keep track of playlist file path + HBufC* filePath = aBuf.AllocLC(); + TParsePtrC pathParse( *filePath ); + HBufC* origPlaylistName( NULL ); + if ( !pathParse.NamePresent() ) + { + // Load default name if filename is missing + origPlaylistName = + StringLoader::LoadLC( R_MPX_CUI_DEFAULT_PLAYLIST_NAME ); + } + else + { + origPlaylistName = pathParse.Name().AllocLC(); + } + + if ( !iCollectionUiHelper ) + { + iCollectionUiHelper = CMPXCollectionHelperFactory::NewCollectionUiHelperL(); + } + if ( iCollectionUiHelper->TitleExistsL( EMPXPlaylist, *origPlaylistName ) ) + { + HBufC* newTitle = GenerateTitleL( EMPXPlaylist, *origPlaylistName ); + aBuf.Copy( pathParse.DriveAndPath() ); + aBuf.Append( *newTitle ); + delete newTitle; + } + else + { + aBuf.Copy( pathParse.DriveAndPath() ); + aBuf.Append( *origPlaylistName ); + } + CleanupStack::PopAndDestroy( 2, filePath ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// Finds all items in the specified category +// ----------------------------------------------------------------------------- +// +CMPXMedia* CMPXCommonUiHelper::FindAllL(TMPXGeneralCategory aCategory, const TArray& aAttrs) + { + MPX_FUNC( "CMPXCommonUiHelper::FindAllL" ); + + if (!iCollectionUtility) + { + User::Leave(KErrArgument); + } + + CMPXMedia* ret( NULL ); + CMPXMedia* criteria = CMPXMedia::NewL(); + CleanupStack::PushL( criteria ); + criteria->SetTObjectValueL( + KMPXMediaGeneralType, EMPXGroup ); + criteria->SetTObjectValueL( + KMPXMediaGeneralCategory, aCategory ); + + // Look up collection UID and set to criteria + // + RArray ary; + CleanupClosePushL( ary ); + ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) ); + TUid musicCollection = iCollectionUtility->CollectionIDL( ary.Array() ); + CleanupStack::PopAndDestroy( &ary ); + + criteria->SetTObjectValueL( KMPXMediaGeneralCollectionId, musicCollection ); + + ret = iCollectionUtility->Collection().FindAllL( *criteria, aAttrs ); + CleanupStack::PopAndDestroy( criteria ); + return ret; + } + +// ----------------------------------------------------------------------------- +// Handles the completion of setting a media event. +// ----------------------------------------------------------------------------- +// +void CMPXCommonUiHelper::HandleOperationCompleteL( TCHelperOperation aOperation, + TInt aErr, + void* aArgument ) + { + if ( iAddObserver ) + { + iAddObserver->HandleOperationCompleteL( aOperation, aErr, aArgument ); + } + iAddObserver = NULL; + } + +// ---------------------------------------------------------------------------- +// CMPXCommonUiHelper::PlaylistCreateNameExistL +// ---------------------------------------------------------------------------- +// +TBool CMPXCommonUiHelper::PlaylistCreateNameExistL( TDes& aName, const TParseBase& aParse ) + { + TBool ret( EFalse ); + CMPXFileNameQueryDlg* nameDlg = CMPXFileNameQueryDlg::NewL( + aName, aName, aParse.DriveAndPath(), + EMPXPlaylist, this ); +// Cover UI start +//#ifdef __COVER_DISPLAY + nameDlg->PublishDialogL( + EMPlayerQueryCreatePlaylist, + KMPlayerNoteCategory); +//#endif +// Cover UI end + ret = nameDlg->ExecuteLD( R_MPX_CREATE_PLAYLIST_NAME_QUERY ); + + if ( ret ) + { + if ( iCollectionUiHelper->TitleExistsL( EMPXPlaylist, aName, EMPXOtherType ) ) + { + HBufC* info = StringLoader::LoadLC( R_MPX_PLAYLIST_NAME_EXIST, aName ); + + if( CEikonEnv::Static()->QueryWinL( KNullDesC, *info ) ) + { + if ( !PlaylistCreateNameExistL( aName, aParse ) ) + { + ret = EFalse; + } + } + else + { + ret = EFalse; + } + CleanupStack::PopAndDestroy( info );//query ,info + } + } + + return ret; + } +// End of File