mpxmusicplayer/commonui/src/mpxcommonuihelper.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Feb 2010 22:48:30 +0200
branchRCL_3
changeset 11 13afc0e517bd
parent 0 ff3acec5bc43
child 14 943ff5625028
permissions -rw-r--r--
Revision: 201003 Kit: 201007

/*
* 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 <coeutils.h>
#include <avkon.hrh>
#include <avkon.rsg>
#include <AknWaitDialog.h>
#include <AknProgressDialog.h>
#include <AknCommonDialogs.h>
#include <CAknFileNamePromptDialog.h>
#include <centralrepository.h>
#include <AknsUtils.h>
#include <AknIconArray.h>
#include <barsread.h>
#include <StringLoader.h>
#include <AknUtils.h>
#include <bautils.h>
#include <eikapp.h>
#include <cprofiletonehandler.h>
#include <pathinfo.h>
#ifdef RD_MULTIPLE_DRIVE
#include <driveinfo.h>
#endif // RD_MULTIPLE_DRIVE
#include <MProfileEngine.h>
#include <AknQueryDialog.h>
#include <aknnotewrappers.h>
#include <data_caging_path_literals.hrh>
#include <caf/caferr.h>
#include <sysutil.h>
#include <textresolver.h>
#include <aknnotewrappers.h>

#include <mpxmedia.h>
#include <mpxmediageneraldefs.h>
#include <mpxmediadrmdefs.h>
#include <mpxmediacontainerdefs.h>
#include <mpxmediaarray.h>
#include <mpxcommonui.rsg>
#include <mpxcommonui.mbg>
#include <mpx.rsg>
#include <mpxcollectionhelperfactory.h>
#include <mpxcollectionpath.h> // TMPXItemId
#include <mpxcollectionutility.h>
#include <mpxcollectionplugin.hrh>
#include <mpxuser.h>
#include <AknGlobalNote.h>

// Cover UI start
//#ifdef __COVER_DISPLAY
#include <aknSDData.h>
#include <AknMediatorFacade.h>
#include <mplayersecondarydisplayapi.h>
#include <featmgr.h>
//#endif
// Cover UI end

#include <mpxconstants.h>
#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<TInt>( 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<TBool>( KMPXMediaDrmProtected );
        }
    if ( isProtected )
        {
        if ( aMedia.IsSupported ( KMPXMediaDrmRightsStatus ) )
            {
            rightsStatus = aMedia.ValueTObjectL<TInt>( KMPXMediaDrmRightsStatus );
            }
        if ( aMedia.IsSupported ( KMPXMediaDrmCanSetAutomated ) )
            {
            canSetAutomated = aMedia.ValueTObjectL<TBool>( 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<KMPXMaxBufferLen> 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<TMPXAttribute> 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<CMPXMediaArray>( KMPXMediaArrayContents );
    User::LeaveIfNull( const_cast<CMPXMediaArray*>( 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<CTextListBoxModel*>( queryDlg->ListBox()->Model() );
        CDesCArray* descArray =
            static_cast<CDesCArray*>( 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<TUint>( 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<TMPXItemId>( KMPXMediaGeneralId );
                const CMPXMediaArray* tracksArray =
                    aTracks.Value<CMPXMediaArray>( KMPXMediaArrayContents );
                User::LeaveIfNull( const_cast<CMPXMediaArray*>( 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<TMPXItemId>(
                        KMPXMediaGeneralId, playlistId );
                    media->SetTObjectValueL<TMPXGeneralType>(
                        KMPXMediaGeneralType, EMPXItem );
                    media->SetTObjectValueL<TMPXGeneralCategory>(
                        KMPXMediaGeneralCategory, EMPXPlaylist );
                    media->SetCObjectValueL(
                        KMPXMediaArrayContents,
                        const_cast<CMPXMediaArray*>(tracksArray ));
                    media->SetTObjectValueL(
                        KMPXMediaArrayCount, tracksArray->Count() );

                    RArray<TUid> ary;
                    CleanupClosePushL( ary );
                    ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) );
                    TUid musicCollection = iCollectionUtility->CollectionIDL( ary.Array() );
                    CleanupStack::PopAndDestroy( &ary );

                    media->SetTObjectValueL<TUid>( 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<CMPXMediaArray>( KMPXMediaArrayContents );
        User::LeaveIfNull( const_cast<CMPXMediaArray*>( 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<TMPXGeneralType>(
            KMPXMediaGeneralType, EMPXItem );
        media->SetTObjectValueL<TMPXGeneralCategory>(
            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<CMPXMediaArray*>(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 );
                CAknQueryDialog* query = new(ELeave)CAknQueryDialog( *info );
                if( query->ExecuteLD( R_RENAME_QUERY ) )
                    {
                    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<TMPXMediaDrmType>( 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<TMPXAttribute> 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<CMPXMediaArray>(KMPXMediaArrayContents);
    User::LeaveIfNull( const_cast<CMPXMediaArray*>( 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; i<count; i++)
        {
        const CMPXMedia* media( resultArray->AtL( 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; i<count && !exists; i++)
            {
            if (testTitle->Compare((*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<TBool>( 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<TMPXAttribute>& aAttrs)
    {
    MPX_FUNC( "CMPXCommonUiHelper::FindAllL" );

    if (!iCollectionUtility)
        {
        User::Leave(KErrArgument);
        }

    CMPXMedia* ret( NULL );
    CMPXMedia* criteria = CMPXMedia::NewL();
    CleanupStack::PushL( criteria );
    criteria->SetTObjectValueL<TMPXGeneralType>(
        KMPXMediaGeneralType, EMPXGroup );
    criteria->SetTObjectValueL<TMPXGeneralCategory>(
        KMPXMediaGeneralCategory, aCategory );

    // Look up collection UID and set to criteria
    //
    RArray<TUid> ary;
    CleanupClosePushL( ary );
    ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) );
    TUid musicCollection = iCollectionUtility->CollectionIDL( ary.Array() );
    CleanupStack::PopAndDestroy( &ary );

    criteria->SetTObjectValueL<TUid>( 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 );
            CAknQueryDialog* query = new(ELeave)CAknQueryDialog( *info );
            if( query->ExecuteLD( R_RENAME_QUERY ) )
                {
                if ( !PlaylistCreateNameExistL( aName, aParse ) )
                    {
                    ret = EFalse;
                    }
                }
             else
                {
                ret = EFalse;
                }
             CleanupStack::PopAndDestroy( info );//query ,info
             }
        }

    return ret;
    }    
//  End of File