mpxmusicplayer/commonui/src/mpxfilenamequerydlg.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 14:28:40 +0300
branchRCL_3
changeset 66 1f1dad4af8f8
parent 53 3de6c4cf6b67
permissions -rw-r--r--
Revision: 201039 Kit: 201041

/*
* 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:  rename dialog for Common UI
*
*/


// INCLUDE FILES
#include <coeutils.h>
#include <eikapp.h>
#include <StringLoader.h>
#include <aknnotewrappers.h>
#include <mpxcollectionuihelper.h>
#include <mpxcollectionhelperfactory.h>
#include <mpxcommonui.rsg>
#include <mpxlog.h>

#include "mpxcommonuihelper.h"
#include "mpxfilenamequerydlg.h"

// CONSTANTS
const TInt KMPXMaxPlaylistPathLen ( 200 );

_LIT( KBackslash, "\\" );
_LIT( KDirectionalChars, "\x202A\x202B\x202C\x202D\x200E\x200F" );

const TUint16 KIllegalChars[] = {
    '<', '>', '"', '/', '\\', '|', ':', '*', '?',
    0xFF02, // Full width quote
    0xFF0A, // Full width asterisk
    0xFF0F, // Full width slash
    0xFF1A, // Full width colon
    0xFF1C, // Full width left arrow
    0xFF1E, // Full width right arrow
    0xFF1F, // Full width question mark
    0xFF3C, // Full width back slash
    0xFF5C, // Full width pipe
    0x201C, // Left quote
    0x201D, // Right quote
    0x201F, // Reversed quote
    0, // Array terminator
};


// ============================ MEMBER FUNCTIONS ===============================


// ---------------------------------------------------------------------------
// Two-phased constructor.
// ---------------------------------------------------------------------------
//
CMPXFileNameQueryDlg* CMPXFileNameQueryDlg::NewL(
        const TDesC& aOldName,
        TDes& aNewName,
        const TDesC& aPath,
        TMPXGeneralCategory aCategory,
        CMPXCommonUiHelper* aParent )
    {
    MPX_FUNC( "CMPXFileNameQueryDlg::NewL" );
    CMPXFileNameQueryDlg* self =
        new( ELeave ) CMPXFileNameQueryDlg( aNewName, aCategory, aParent );

    CleanupStack::PushL( self );
    self->ConstructL( aOldName, aPath );
    CleanupStack::Pop( self );

    return self;
    }

// ---------------------------------------------------------------------------
// C++ default constructor can NOT contain any code, that
// might leave.
// ---------------------------------------------------------------------------
//
CMPXFileNameQueryDlg::CMPXFileNameQueryDlg(
    TDes& aNewName,
    TMPXGeneralCategory aCategory,
    CMPXCommonUiHelper* aParent ) :
    CAknTextQueryDialog( aNewName ),
    iParent( aParent ),
    iCategory( aCategory )
    {
    }

// ---------------------------------------------------------------------------
// Symbian 2nd phase constructor can leave.
// ---------------------------------------------------------------------------
//
void CMPXFileNameQueryDlg::ConstructL(
    const TDesC& aOldName, const TDesC& aPath )
    {
    MPX_FUNC( "CMPXFileNameQueryDlg::ConstructL" );
    TParsePtrC name( aOldName );
    iOldName = aOldName.AllocL();
    iPath = aPath.AllocL();
    // Strip any directionality markers to get pure name
    TPtr ptr( iOldName->Des() );
    AknTextUtils::StripCharacters( ptr, KDirectionalChars );
    TInt extLength( 0 );
    if ( iCategory == EMPXPlaylist )
        {
        Text().Copy( name.NameAndExt() );
        }
    else
        {
        Text().Copy( name.Name() );
        if ( name.ExtPresent() )
            {
            extLength = name.Ext().Length();
            }
        }
    TInt maxLength( KMPXMaxPlaylistPathLen - aPath.Length() - extLength );
    MPX_DEBUG2( "CMPXFileNameQueryDlg::ConstructL setting max length = %d", maxLength );
    SetMaxLength( maxLength );
    iCollectionUiHelper = CMPXCollectionHelperFactory::NewCollectionUiHelperL();
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CMPXFileNameQueryDlg::~CMPXFileNameQueryDlg()
    {
    if ( iCollectionUiHelper )
        {
        iCollectionUiHelper->Close();
        }
    delete iOldName;
    delete iPath;
    }

// ---------------------------------------------------------------------------
// CFileManagerFileNameQueryDlg::OkToExitL
// ---------------------------------------------------------------------------
//
TBool CMPXFileNameQueryDlg::OkToExitL( TInt aButtonId )
    {
    MPX_FUNC( "CMPXFileNameQueryDlg::OkToExitL" );
    TBool result( CAknTextQueryDialog::OkToExitL( aButtonId ) );

    HBufC* userText = Text().AllocLC();
    TPtr ptrUserText( userText->Des() );

    // Strip any directionality markers to get pure name
    AknTextUtils::StripCharacters( ptrUserText, KDirectionalChars );

    TParsePtrC currentPath( *iPath );
    // Check file name
    TBool isValidName = IsValidName( currentPath.DriveAndPath(), *userText, EFalse );
    if( !isValidName )
        {
        if( IllegalChars( *userText ) )
            {
            iParent->DisplayInfoNoteL(
                R_MPX_QTN_FLDR_ILLEGAL_CHARACTERS );
            }
        else
            {
            iParent->DisplayInfoNoteL(
                R_MPX_QTN_FLDR_BAD_FILE_NAME );
            }
        CAknQueryControl* queryControl = QueryControl();
        if ( queryControl )
            {
            CEikEdwin* edwin = static_cast< CEikEdwin* >(
                queryControl->ControlByLayoutOrNull( EDataLayout ) );
            if (edwin)
                {
                edwin->SetSelectionL( edwin->TextLength(), 0 );
                }
            }
        CleanupStack::PopAndDestroy( userText );
        return EFalse;
        }

    // if some other entry found with same name
    // not ok except if name same as original
    if ( iCategory != EMPXPlaylist )
        {
        if ( iCollectionUiHelper->TitleExistsL( iCategory, *userText ) )
            {
            TBool overWrite( EFalse );
            HBufC* text = StringLoader::LoadLC( R_MPX_QTN_FLDR_OVERWRITE_QUERY, Text() );
            CAknQueryDialog* dlg = CAknQueryDialog::NewL();
            overWrite = dlg->ExecuteLD( R_MPX_CONFIRM_QUERY_WITH_YES_NO, *text );
            CleanupStack::PopAndDestroy( text );
            if( !overWrite )
                {
                CAknQueryControl* queryControl = QueryControl();
                if (queryControl)
                    {
                    CEikEdwin* edwin = static_cast< CEikEdwin* >(
                        queryControl->ControlByLayoutOrNull( EDataLayout ) );

                    HBufC* newTitle = iParent->GenerateTitleL( iCategory, *userText );
                    CleanupStack::PushL(newTitle);

                    if ( edwin )
                        {
                        edwin->SetTextL( newTitle );
                        edwin->SetSelectionL( edwin->TextLength(), 0 );
                        }
                    CleanupStack::PopAndDestroy(newTitle);
                    }
                result = EFalse;
                }
            }
        }
    CleanupStack::PopAndDestroy( userText );
    if ( result && iCategory != EMPXPlaylist )
        {
        // playlist has no extension, don't need to do this
        TParsePtrC oldName( *iOldName );
        iDataText.Append( oldName.Ext() );
        }
    return result;
    }

// -----------------------------------------------------------------------------
// CMPXFileNameQueryDlg::OfferKeyEventL
// 
// -----------------------------------------------------------------------------
// 
TKeyResponse CMPXFileNameQueryDlg::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType ) 
    { 
    TKeyResponse response = EKeyWasNotConsumed;
    // consume 'enter' so it won't acknowledge the dialog
    TBool vkbOpen = EFalse;
    CAknQueryControl* queryControl = QueryControl();
    if ( queryControl )
        {
        CEikEdwin* edwin = static_cast< CEikEdwin* >(
            queryControl->ControlByLayoutOrNull( EDataLayout ) );
        if ( edwin )
            {            
            if ( edwin->AknEdwinFlags() & EAknEditorFlagTouchInputModeOpened )
                {
                // virtual keyboard is active.                
                vkbOpen = ETrue;
                }
            }
        }    
    
    if ( vkbOpen && aType == EEventKey && aKeyEvent.iCode == EKeyEnter ) 
        { 
        response = EKeyWasConsumed;
        } 
    else
        {
        response = CAknTextQueryDialog::OfferKeyEventL(aKeyEvent, aType); 
        }
    return response;
    }

// -----------------------------------------------------------------------------
// CMPXFileNameQueryDlg::IsValidName
// -----------------------------------------------------------------------------
//
TBool CMPXFileNameQueryDlg::IsValidName(
        const TDesC& aDriveAndPath, const TDesC& aName, TBool aIsFolder ) const
    {
    MPX_FUNC( "CMPXFileNameQueryDlg::IsValidName" );
    // Check name for bad chars
    const TUint16 KMinAllowedChar = 0x0020;
    const TUint16 KParagraphSeparator = 0x2029;
    const TUint16 KDot = '.';
    TInt nameLen( aName.Length() );
    if ( !nameLen )
        {
        return EFalse;
        }
    for ( TInt i( 0 ); i < nameLen; i++ )
        {
        TUint16 ch( aName[ i ] );
        if ( ch < KMinAllowedChar || ch == KParagraphSeparator )
            {
            return EFalse;
            }
        }
    // File system ignores totally dot in the end of name, so
    // we set here as not valid name, so that user gets correctly informed
    if ( aName[ nameLen - 1 ] == KDot || IllegalChars( aName ) )
        {
        return EFalse;
        }
    // Get full path length
    TPtrC pathPtr( aDriveAndPath );
    TInt pathLen( pathPtr.Length() );
    if ( !pathLen )
        {
        return EFalse;
        }
    TInt fullPathLen( pathLen );
    if ( pathPtr[ pathLen - 1 ] != KBackslash()[ 0 ] )
        {
        ++fullPathLen; // Add backslash before name
        }
    fullPathLen += nameLen;
    if ( aIsFolder )
        {
        ++fullPathLen; // Add folder final backslash
        }

    TBool ret( EFalse );
    if ( fullPathLen <= KMaxFileName )
        {
        // Check full path
        HBufC* fullPath = HBufC::New( KMaxFileName );
        if ( fullPath )
            {
            TPtr ptr( fullPath->Des() );
            ptr.Copy( pathPtr );
            if ( pathPtr[ pathLen - 1 ] != KBackslash()[ 0 ] )
                {
                ptr.Append( KBackslash ); // Add backslash before name
                }
            ptr.Append( aName );
            RFs fs;
            TInt connectError = fs.Connect();
            if ( connectError == KErrNone )
            {
                ret = fs.IsValidName( ptr );
                fs.Close();
            }
            delete fullPath;
            }
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMPXFileNameQueryDlg::IllegalChars
// -----------------------------------------------------------------------------
//
TBool CMPXFileNameQueryDlg::IllegalChars( const TDesC& aName ) const
    {
    MPX_FUNC( "CMPXFileNameQueryDlg::IllegalChars" );
    for ( TInt i( 0 ); KIllegalChars[ i ]; i++ )
        {
        if ( aName.Locate( KIllegalChars[ i ] ) != KErrNotFound )
            {
            return ETrue;
            }
        }
    return EFalse;
    }

//  End of File