menufw/menufwui/mmextensions/mmfolderuiextension/src/mmfoldercommand.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:40:49 +0200
changeset 0 f72a12da539e
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2007-2008 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:   Interface of the folder command
 *
*/

#include <liwcommon.h>
#include <e32base.h>
#include <eikenv.h>
#include <StringLoader.h>
#include <AknQueryDialog.h>
#include <aknnotewrappers.h>
#include <s32mem.h>

#include "mmfoldercommand.h"
#include "mmfoldercommandadd.h"
#include "mmfoldercommandrename.h"
#include "mmfoldercommanddelete.h"
#include "mmmovetofoldercommand.h"
#include "mmdialogmanager.h"
#include "hnliwutils.h"
#include "menudebug.h"
#include "hnutils.h"

#include "hnmdbasekey.h"
#include "hnmdkeyfactory.h"
#include "menudebug.h"
#include "hnconvutils.h"
#include "hnservicehandler.h"
#include "mmfolderuiextpluginconstants.h"
#include "mmpluginsharedresources.h"

#include <avkon.rsg>
#include <matrixmenu.rsg>
#include <mmfolderuiextplugin.rsg>


const TInt KCountNotAllowedChars = 9;
// Unicode character of sign obtained by press '0' key three times. Enter key.
const TUint16 KIllegalCharEnter = 0x21b2;
// Unicode line separator character obtained by pressing Shift + Enter keys
const TUint16 KIllegalCharLineSeparator = 0x2028;
// Space unicode character.
// Characters which ascii value is smaller than 32 are not allowed.
const TUint16 KSpace = ' '; //32;

// ============================ MEMBER FUNCTIONS =============================
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
CMmFolderCommand::~CMmFolderCommand()
    {
    iSerializedInputList.Close();
    iSerializedOutputList.Close();
    delete iGetListOutParam;
    delete iGetListInParam;
    iMcs.Close();
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::BaseConstructL()
	{
	// Init MCS session
	TBuf16<KMaxFileName> buf;
	buf.Copy(KMatrixMenuData);
	iMcs.OpenL(buf);
	iGetListInParam = CLiwGenericParamList::NewL();
	iGetListOutParam = CLiwGenericParamList::NewL();
	}

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::MCSQueryExecutionL(
        const TDesC8& aQueryName,
        const CHnMdBaseKey* aInputData,
        const CHnMdBaseKey* aFilter,
        MLiwNotifyCallback* aCallback )
    {
    RPointerArray< CHnMdBaseKey > data;
    CleanupClosePushL( data );
    data.AppendL( aInputData );
    if ( aFilter )
        {
        data.AppendL( aFilter );
        }

    CHnMdBaseKey* serviceData = HnMdKeyFactory::CreateL(
        KServiceContentName, KKeyTypeString, KMatrixMenuData );
    CleanupStack::PushL( serviceData );

    RPointerArray< CHnMdBaseKey> constructor;
    CleanupClosePushL( constructor );
    constructor.AppendL( serviceData );
    CLiwGenericParamList* constructorLiw = CLiwGenericParamList::NewLC();
    CLiwGenericParamList* commandLiw = CLiwGenericParamList::NewLC();
    HnLiwUtils::SetGenericParamListL( constructor, *constructorLiw );
    HnLiwUtils::SetGenericParamListL( data, *commandLiw );

    TBuf8< KMaxLength > interface( KMCSDataSourceInterface8 );
    if ( !aQueryName.Compare( KCmdOrganize8 ) ||
            !aQueryName.Compare( KCmdExecuteAction8 ) )
        {
        interface.Copy( KMCSMenuContentInterface8 );
        }

    delete iServiceHandler;
    iServiceHandler = NULL;
    iServiceHandler = CHnServiceHandler::NewL(
            KMCSService8, interface, aQueryName,
            EServiceModeAsynchronous, constructorLiw, commandLiw );

    CleanupStack::Pop( commandLiw );
    CleanupStack::Pop( constructorLiw );

    iServiceHandler->ExecuteL( aCallback , 0 );

    CleanupStack::PopAndDestroy( &constructor );
    CleanupStack::PopAndDestroy( serviceData );
    CleanupStack::PopAndDestroy( &data );
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
CMmFolderCommand* CMmFolderCommand::FactoryL( const TDesC& aCommand )
    {
    CMmFolderCommand* ret = NULL;
    if( !aCommand.Compare( KAddFolderCmd ) )
		{
		ret = CMmFolderCommandAdd::NewL();
		}
    else if ( !aCommand.Compare( KRenameFolderCmd ) )
		{
		ret = CMmFolderCommandRename::NewL();
		}
    else if ( !aCommand.Compare( KDeleteFolderCmd ) )
		{
		ret = CMmFolderCommandDelete::NewL();
		}
    else if ( !aCommand.Compare( KDeleteAppCmd ) )
		{
		ret = CMmFolderDeleteApp::NewL();
		}
    else if ( !aCommand.Compare( KDeleteSuiteCmd ) )
		{
		ret = CMmFolderDeleteSuite::NewL();
		}
    else if ( !aCommand.Compare( KMoveToFolderCmd ) )
        {
        ret = CMmMoveToFolderCommand::NewL();
        }
    return ret;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
TBool CMmFolderCommand::DoChangeNameL( RBuf& aFolderName, 
		TInt aDefaultNameLength, RBuf& aNumberInBracket, 
		CLiwGenericParamList& aFoldersNames, TLiwVariant& aVar,
		TInt aNumberToAppend )
    {
    TBool nameChanged( EFalse );
    TInt position( KErrNone );
    TInt count = aFoldersNames.FindFirst( position, KReturnValue8() )
        ->Value().AsList()->Count();
    aNumberInBracket.Delete( KOpenBracket().Length(), 
        aNumberInBracket.Length() - KOpenBracket().Length() );
    
    if ( aNumberToAppend < KMaxDigitNumber )
        {
        aNumberInBracket.AppendNum( 0 );
        }
    
    for ( TInt i = 0; i < count; i++ )
        {
        HnLiwUtils::GetVariantL( aFoldersNames, KLongNamePath8, i, aVar );
        TPtrC longName;
        aVar.Get( longName );
        if ( !aFolderName.Compare( longName ) )
            {
            aNumberInBracket.AppendNum( aNumberToAppend );
            aNumberInBracket.Append( KCloseBracket );
            aFolderName.Delete( aDefaultNameLength, 
                aFolderName.Length() - aDefaultNameLength );
            aFolderName.Append( aNumberInBracket );
            nameChanged = ETrue;
            break;
            }
        }
    return nameChanged;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::ChangeNameIfAlreadyExistsL( RBuf& aFolderName,
        CLiwGenericParamList* aFoldersNames, TInt aNumberToAppend )
    {
    if ( !aFoldersNames )
        {
        return;
        }
    TLiwVariant var;
    var.PushL();
    RBuf numberInBracket;
    CleanupClosePushL(numberInBracket);
    numberInBracket.CreateL( KMaxLength );
    numberInBracket.Append( KOpenBracket );
    numberInBracket.AppendNum( aNumberToAppend );
    numberInBracket.Append( KCloseBracket );
    TInt defaultNameLength = aFolderName.Length();
    
    while( DoChangeNameL( aFolderName, defaultNameLength, numberInBracket,
            *aFoldersNames, var, ++aNumberToAppend ) )
        ;
        
    CleanupStack::PopAndDestroy(&numberInBracket);
    CleanupStack::PopAndDestroy( &var );
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
TBool CMmFolderCommand::GetFolderNameL( RBuf& aFolderName, 
        CLiwGenericParamList* aFoldersNames )
	{
	TBool res( EFalse );
	if( aFolderName.Length() == 0 )
		{
	    aFolderName.Append( iSharedResources->GetDefaultFolderName() );
	    ChangeNameIfAlreadyExistsL( aFolderName, aFoldersNames );
		}

	CAknTextQueryDialog* dialog =
	    CAknTextQueryDialog::NewL( aFolderName, CAknQueryDialog::ENoTone );
	
	dialog->PrepareLC( R_MENU_FILENAME_QUERY );
	dialog->SetPromptL( iSharedResources->GetEditFolderName() );

	SetDialogL( dialog );
    res = dialog->RunLD();
    SetDialogL( NULL );

	return res;
	}

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::GetFolderListL( TInt aItemId )
    {
    // Prepare data for GetList
    iGetListInParam->Reset();
    PrepareGetListInputL( aItemId );
    PrepareGetListFolderFilterL();
    ExternalizeInputListL();
    
    // Get folders list from MCS
    iMcs.GetListL( iSerializedInputList, iSerializedOutputList );
    InternalizeOutputListL();
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::GetListL( TInt aItemId )
    {
    // Prepare data for GetList
    iGetListInParam->Reset();
    PrepareGetListInputL( aItemId );
    PrepareGetListFilterL();
    ExternalizeInputListL();
    
    // Get folders list from MCS
    iMcs.GetListL( iSerializedInputList, iSerializedOutputList );
    InternalizeOutputListL();
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::DisplayErrorInfoL( const TDesC& aFolderName )
    {
    CAknNoteDialog* dialog = new (ELeave) CAknNoteDialog(
            CAknNoteDialog::EConfirmationTone,
            CAknNoteDialog::ELongTimeout );
    HBufC* msg = StringLoader::LoadLC(
            R_FLDR_CANNOT_DELETE_ITEM, aFolderName );
    dialog->SetTextL( msg->Des() );
    dialog->ExecuteDlgLD( R_MENU_EDIT_INTERRUPTION_INFO );

    CleanupStack::PopAndDestroy( msg );
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::SetRequestInterface( MMmActionRequest* aActionRequest )
    {
    iActionRequest = aActionRequest;
    }

void CMmFolderCommand::SetSharedResources( CMmPluginSharedResources* aResources )
	{
	iSharedResources = aResources;
	}

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::SetDialogL( CAknQueryDialog* aDialog )
    {
    iDialog = aDialog;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::RemoveDialogL()
    {
    iLockDialog = ETrue;
    if( iDialog )
        {
        iDialog->HandleQueryEditorStateEventL( NULL,
            MAknQueryControlObserver::EEmergencyCallAttempted,
            MAknQueryControlObserver::EEditorEmpty );
        iDialog = NULL;
        }
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::AddSubKeyL( CHnMdBaseKey* aInDataKey,
                                   const TDesC8& aKeyName,
                                   const TDesC8& aKeyType,
                                   const TDesC8& aKeyValue )
    {
    CHnMdBaseKey* key = HnMdKeyFactory::CreateL(
    		aKeyName, aKeyType, aKeyValue );
    CleanupStack::PushL( key );
    aInDataKey->AddSubKeyL( key );
    CleanupStack::Pop( key );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
// 
void CMmFolderCommand::AddSubKeyL( CHnMdBaseKey* aInDataKey, 
                                   const TDesC8& aKeyName, 
                                   const TDesC8& aKeyType, 
                                   const TDesC& aKeyValue )
    {
    CHnMdBaseKey* key = HnMdKeyFactory::CreateL(
    		aKeyName, aKeyType, aKeyValue );
    CleanupStack::PushL( key );
    aInDataKey->AddSubKeyL( key );
    CleanupStack::Pop( key );
    }
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
// 
TInt CMmFolderCommand::FolderNameValidationL(RBuf& aFolderName,
        CLiwGenericParamList* aFoldersNames)
    {
    TValidation allowed(EValidationOk);

    allowed = (TValidation) IllegalCharacterRemoveL(aFolderName, aFoldersNames);
    if (allowed != EValidationOk)
        {
        return allowed;
        }
    allowed = (TValidation) CheckValidFileNameL(aFolderName);
    if (allowed != EValidationOk)
        {
        // §qtn_fldr_bad_file_name§
        // data entry (for example data query New name: §qtn_fldr_item_name_prmpt§ ) is opened
        DisplayNameErrorInfoL(iSharedResources->GetMsgBadFileName());
        return allowed;
        }
    allowed = (TValidation) CheckAllowedCharsL(aFolderName);
    if (allowed != EValidationOk)
        {
        // information note "Name cannot contain
        // the characters < > \\ /"" |:*?" §qtn_fldr_illegal_characters§ is displayed.                 
        DisplayNameErrorInfoL(iSharedResources->GetMsgIllegalCharacters());
        }
    return allowed;
    }
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmFolderCommand::IllegalCharacterRemoveL(RBuf& aFolderName,
        CLiwGenericParamList* aFoldersNames)
    {
    TValidation allowed( EValidationOk );
    // illegal characters are removed
    TInt pos( 0 );
    while ( pos < aFolderName.Length() )
        {
        if ( aFolderName[pos] == KIllegalCharEnter ||
             aFolderName[pos] == KIllegalCharLineSeparator )
            {
            aFolderName.Delete( pos, 1 );
            }
        else
            {
            ++pos;
            }
        }
    if (aFolderName.Length() == 0)
        {
        aFolderName.Append(iSharedResources->GetDefaultFolderName());
        ChangeNameIfAlreadyExistsL(aFolderName, aFoldersNames);
        return allowed;
        }
    // only space character is not allowed
    RBuf trimBuf;
    CleanupClosePushL(trimBuf);
    trimBuf.CreateL(aFolderName.Length());
    trimBuf.Copy(aFolderName);
    trimBuf.Trim();
    if (!trimBuf.Length())
        {
        allowed = EValidationInvalid;
        }
    CleanupStack::PopAndDestroy(&trimBuf);

    return allowed;
    }
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmFolderCommand::CheckValidFileNameL( const TDes& aFolderName )
    {
    TValidation allowed(EValidationOk);
    _LIT( KSingleDot, ".");
    _LIT( KDoubleDot, "..");
    
    if (!aFolderName.Compare( KSingleDot) ||
            !aFolderName.Compare( KDoubleDot ) ||
            aFolderName.Length() > KMaxFileName)
        {
        allowed = EValidationInvalid;
        }
    else
        {
        // characters with ascii value less than 32
        for (TInt index(0); index < aFolderName.Length(); index++)
            {
            if (aFolderName[index] < KSpace)
                {
                allowed = EValidationInvalid;                
                }
            }
        }    
    return allowed;
    }
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmFolderCommand::CheckAllowedCharsL( const TDes& aFolderName )
    {
    TValidation allowed(EValidationOk);

    for (TInt index(0); index < aFolderName.Length(); index++)
        {
        for (TInt c(0); c < KCountNotAllowedChars; c++)
            {
            if (TChar( KNotAllowedChars[c] ) == aFolderName[index])
                {
                allowed = EValidationNotAllowed;
                }
            }
        }

    return allowed;
    }
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::DisplayNameErrorInfoL( const TDesC& aMsg )
    {
    CAknNoteDialog* dialog = new (ELeave) CAknNoteDialog(
            CAknNoteDialog::EConfirmationTone,
            CAknNoteDialog::ELongTimeout );
    dialog->SetTextL( aMsg );
    dialog->ExecuteDlgLD( R_MENU_EDIT_MOVING_ABORT_NOTIFICATION );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::PrepareGetListInputL(TInt aItemId)
	{
    CLiwDefaultMap* inputMap = CLiwDefaultMap::NewLC();
    
    // Specify GetList input data
    inputMap->InsertL( KIdAttrName8, TLiwVariant( TInt32( aItemId ) ) );         	// Item id
    inputMap->InsertL( KRecursiveSearch8, TLiwVariant( TBool ( EFalse ) ) );	// Recursive Search
    inputMap->InsertL( KFlatResult8, TLiwVariant ( TBool ( ETrue ) ) );	   	// Flat GetList
    inputMap->InsertL( KParentOnly8, TLiwVariant ( TBool ( EFalse ) ) );	   	// Get children
    
    // Fill GetList input param list
    InsertToLiwListL(iGetListInParam, KInData8, inputMap);

    CleanupStack::PopAndDestroy(inputMap);
	}

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::PrepareGetListFolderFilterL()
	{
    // Specify GetList filter
	CLiwDefaultMap* folderFilter = CLiwDefaultMap::NewLC();
	folderFilter->InsertL( KTypeAttrName8, TLiwVariant( KMenuFolder ) ); // Folders
	
	folderFilter->InsertL( KHidden8, TLiwVariant( TBool(EFalse) ) ); // Not Hidden
	folderFilter->InsertL( KDeleteLocked8, TLiwVariant( TBool(EFalse) ) ); // Not locked
	
	// Fill GetList input param list
	InsertToLiwListL(iGetListInParam, KFilter8, folderFilter);
	
	CleanupStack::PopAndDestroy(folderFilter);
	}

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::PrepareGetListFilterL()
    {
    // Specify GetList filter
    CLiwDefaultMap* folderFilter = CLiwDefaultMap::NewLC();
    
    folderFilter->InsertL( KHidden8, TLiwVariant( TBool(EFalse) ) ); // Not Hidden
    folderFilter->InsertL( KMissing8, TLiwVariant( TBool(EFalse) ) ); // Not Missing
    
    // Fill GetList input param list
    InsertToLiwListL(iGetListInParam, KFilter8, folderFilter);
    
    CleanupStack::PopAndDestroy(folderFilter);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::InsertToLiwListL(CLiwGenericParamList* aList, 
		const TDesC8& aKey, const CLiwDefaultMap* aMap)
	{
    TLiwVariant liwVar;    
    liwVar.Set( aMap );
    liwVar.PushL();
    TLiwGenericParam livGenParam( aKey, liwVar );
    livGenParam.PushL();
    aList->AppendL ( livGenParam );
    CleanupStack::PopAndDestroy( &livGenParam );
    CleanupStack::PopAndDestroy( &liwVar ); 
	}

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::ExternalizeInputListL()
	{
	iSerializedInputList.Close();
	iSerializedOutputList.Close();
	iSerializedInputList.CreateL( iGetListInParam->Size() );
	RDesWriteStream datastrm( iSerializedInputList );
	CleanupClosePushL(datastrm);
	iGetListInParam->ExternalizeL(datastrm);
	datastrm.CommitL();
	CleanupStack::PopAndDestroy(&datastrm);
	}

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolderCommand::InternalizeOutputListL()
	{
	iGetListOutParam->Reset();
	if (iSerializedOutputList.Size())
		{
		RDesReadStream stream( iSerializedOutputList );
		CleanupClosePushL( stream );
		iGetListOutParam->InternalizeL( stream ) ;
		CleanupStack::PopAndDestroy(&stream);
		}
	}


// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmFolderCommand::GetIntL(
        const CLiwGenericParamList& aParam, const TDesC8& aPath )
    {
    TInt pos( 0 );
    const TLiwGenericParam* param = aParam.FindFirst( pos, aPath );
    if( pos != KErrNotFound && param )
        {
        return param->Value().AsTInt32();
        }
    return KErrNotFound;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TPtrC CMmFolderCommand::GetStringL(
        const CLiwGenericParamList& aParam, const TDesC8& aPath )
    {
    TInt pos( 0 );
    const TLiwGenericParam* param = aParam.FindFirst( pos, aPath );
    if( pos != KErrNotFound && param )
        {
        return param->Value().AsDes();
        }
    TPtrC ret( KNullDesC16 );
    return ret; 
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TBool CMmFolderCommand::GetBoolL(
        const CLiwGenericParamList& aParam, const TDesC8& aPath )
    {
    TInt pos( 0 );
    const TLiwGenericParam* param = aParam.FindFirst( pos, aPath );
    if( pos != KErrNotFound && param )
        {
        return param->Value().AsTBool();
        }
    return EFalse; 
    }

// end of file