menufw/menufwui/mmextensions/mmfolderuiextension/src/mmmovetofoldercommand.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:40:49 +0200
changeset 0 f72a12da539e
child 23 7be2816dbabd
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:   Add folder command
 *
*/

 
#include <liwcommon.h>

#include "mmmovetofoldercommand.h"
#include "hnglobals.h"
#include "menudebug.h"
#include "hnconvutils.h"
#include "hnliwutils.h"
#include "hnutils.h"

#include "hnmdbasekey.h"
#include "hnmdkeyfactory.h"
#include "menudebug.h"
#include "mmactionrequest.h"
#include "hnservicehandler.h"
#include "mmpluginsharedresources.h"

#include <StringLoader.h>
#include <liwcommon.h>
#include <avkon.rsg>
#include <avkon.mbg>
#include <AknIconArray.h>
#include <AknIconUtils.h>
#include <aknnotedialog.h>
#include <mmf/common/mmfcontrollerpluginresolver.h>
#include <mmfolderuiextplugin.rsg>
#include <matrixmenu.rsg>

_LIT( KFolderClosed, "0\t" );
_LIT( KFolderOpened, "1\t" );
const TInt KSoftkeyBack( 0 );

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

// ---------------------------------------------------------------------------
// Symbian factory function.
// ---------------------------------------------------------------------------
//
CMmMoveToFolderCommand* CMmMoveToFolderCommand::NewL()
    {
    CMmMoveToFolderCommand* self = new( ELeave ) CMmMoveToFolderCommand();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------------------------
// Symbian second phase constructor.
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::ConstructL()
    {
    BaseConstructL();
    iLockDialog = EFalse;
    iFlagLeave = EFalse;
    }

// ---------------------------------------------------------------------------
// Destructor.
// ---------------------------------------------------------------------------
//
CMmMoveToFolderCommand::~CMmMoveToFolderCommand()
    {
    iItemName.Close();
    iFolderName.Close();
    iWidgetType.Close();
    iOpenedHierarchy.ResetAndDestroy();
    iOpenedHierarchy.Close();
    delete iServiceHandler;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CMmMoveToFolderCommand::CMmMoveToFolderCommand()
    {
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmMoveToFolderCommand::HandleNotifyL(
        TInt /*aCmdId*/, 
        TInt aEventId,
        CLiwGenericParamList& /*aEventParamList*/,
        const CLiwGenericParamList& /*aInParamList*/ )
    {
    if (aEventId != KLiwEventCanceled)
        {
        NotificationMovingCompleteL();
        iItemName.Close();
        iFolderName.Close();
        }
    return KErrNone;
    }


// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::ExecuteActionL(
        CLiwGenericParamList* aEventParamList )
    {
    
    //
    // Prepare move to folder operation
    MMPERF(("CMmMoveToFolderCommand::ExecuteActionL - START"));
    iItemId = GetIntL( *aEventParamList, KIdAttrName8 );
    iParentId = GetIntL( *aEventParamList, KFolderAttrName8 );
    TPtrC widget = GetStringL( *aEventParamList, KWidgetAttrName8 );
    TPtrC currentTempName = GetStringL( *aEventParamList, KName8 );
    
    iItemName.Close();
    iItemName.CreateL( currentTempName );
    
    iWidgetType.Close();
    iWidgetType.CreateL( widget );
    
    CMmFolder* rootFolder = CMmFolder::NewL();
    CleanupStack::PushL( rootFolder );
   
    rootFolder->SetNameL( iSharedResources->GetRootFolder());
    rootFolder->SetId( KRootId );
    iOpenedHierarchy.AppendL( rootFolder );
    CleanupStack::Pop( rootFolder );
    iLockDialog = EFalse;

    // Excute move to folder operation
    TInt err( KErrNone );
    
	// Get folder list form MCS
	GetFolderListL( CurrentFolder()->Id() );
	
	RPointerArray< CMmFolder > folders;
	CleanupResetAndDestroyPushL( folders );

	// Get folders from GetList output
	GetFoldersL(folders);
	
    // if foler already exists, reopen options menu
    do
    	{
    	TRAP( err, ExecuteMoveToFolderL());
    	}
    while ( err == KErrAlreadyExists && folders.Count() > 0 );
    
    // if any different leave was trapped, pass it on
    if ( err != KErrNone )
    	{
    	User::Leave( err );
    	}
    
    CleanupStack::PopAndDestroy( &folders );
    //MMPERF(("CFolderUiExtPlugin::AddFolderCommandL - END"));
    }


// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CMmFolder* CMmMoveToFolderCommand::CurrentFolder()
    {
    ASSERT( iOpenedHierarchy.Count() > 0 );
    return iOpenedHierarchy[ iOpenedHierarchy.Count() - 1 ];
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::MoveToFolderL( TInt aId, TInt aFolderId,
                                            TInt aBeforeItemId )
    {
    if( aFolderId != iParentId )
        {
        CHnMdBaseKey* inDataKey = HnMdKeyFactory::CreateL(
            KInData8, KKeyTypeMap, KDefaultParentId8 );
        CleanupStack::PushL( inDataKey );
        CHnMdBaseKey* listIds = HnMdKeyFactory::CreateL(
            KIdsList, KKeyTypeList, KNullDesC8 );

        HBufC8* id = HnConvUtils::NumToStr8LC( aId );
        AddSubKeyL( listIds, KIdParam, KKeyTypeBoolean, *id );
        CleanupStack::PopAndDestroy();
        
        inDataKey->AddSubKeyL( listIds );
        HBufC8* folderId = HnConvUtils::NumToStr8LC( aFolderId );
        AddSubKeyL( inDataKey, KFolderId8, KKeyTypeBoolean, *folderId );
        CleanupStack::PopAndDestroy( folderId );

        if( aBeforeItemId != KErrNotFound )
            {
            HBufC8* itemId = HnConvUtils::NumToStr8LC( aBeforeItemId );
            AddSubKeyL( inDataKey, KBeforeItemId8, KKeyTypeBoolean, *itemId );
            CleanupStack::PopAndDestroy( itemId );
            }
        MCSQueryExecutionL( KCmdOrganize8, inDataKey, NULL, this );
        iOpenedHierarchy.ResetAndDestroy();

        CleanupStack::PopAndDestroy( inDataKey );
        CLiwGenericParamList* list = CLiwGenericParamList::NewLC();
        TLiwGenericParam command( KHnRequest, TLiwVariant( KDisableActionsForItem ) );
        TLiwGenericParam itemCustomId(
                KItemCustomId8, TLiwVariant( static_cast<TInt32>( aId ) ) );
        list->AppendL( itemCustomId );
        list->AppendL( command );
        iActionRequest->HandleRequestL( *list );
        CleanupStack::PopAndDestroy( list );  
        }
    else
        {
        NotificationItemAlreadyStoredL();
        if( iOpenedHierarchy.Count() > 0 && !iLockDialog )
            {
            if( CurrentFolder()->Id() == iParentId && iParentId != KRootId )
                {
                StepBackInHierarchy();
                }
            else if ( iParentId == KRootId )
                {
                User::Leave( KErrAlreadyExists );
                }
            }
        }
    }


// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::SelectFolderL(
        const RPointerArray< CMmFolder >& aFolderContent )
    {
    CDesCArrayFlat* folders =
        new( ELeave )CDesCArrayFlat( aFolderContent.Count() + 1 );
    CleanupStack::PushL( folders );
    RBuf currentFolder;
    CleanupClosePushL( currentFolder );
    currentFolder.CreateL(
        KFolderOpened().Length() + CurrentFolder()->Name().Length() );
    currentFolder.Append( KFolderOpened );
    currentFolder.Append( CurrentFolder()->Name() );
    folders->AppendL( currentFolder );
    
    for( int i( 0 ); i<aFolderContent.Count(); i++ )
        {
        CMmFolder* folder = aFolderContent[ i ];
        RBuf name;
        CleanupClosePushL( name );
        name.CreateL( KFolderClosed().Length() + folder->Name().Length() );
        name.Append( KFolderClosed );
        name.Append( folder->Name() );
        folders->AppendL( name );
        CleanupStack::PopAndDestroy( &name );
        }
    
    TInt selected( SelectFolderFromListL(
        folders, CurrentFolder()->Id() == KRootId ) );
    
    switch( selected )
        {
        case EAknSoftkeyBack:
            {
            if( iOpenedHierarchy.Count() > 1 && !iLockDialog )
                {
                StepBackInHierarchy();
                break;
                }
            }
        case EAknSoftkeyExit:
            {
            iItemName.Close();
            iFolderName.Close();
            iOpenedHierarchy.ResetAndDestroy();
            break;
            }
        default:
            {
            if( selected > 0 )
                {
                CMmFolder* folder = CMmFolder::NewL();
                CleanupStack::PushL( folder );
                folder->SetNameL( aFolderContent[ selected - 1 ]->Name() );
                folder->SetId( aFolderContent[ selected - 1 ]->Id() );
                iOpenedHierarchy.AppendL( folder );
                CleanupStack::Pop( folder );
                }
            else
                {
                iFolderName.Close();
                iFolderName.CreateL( CurrentFolder()->Name() );
                MoveToFolderL( iItemId, CurrentFolder()->Id() );
                }
            break;
            }
        }
    
    CleanupStack::PopAndDestroy( &currentFolder );
    CleanupStack::PopAndDestroy( folders );
    }


// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmMoveToFolderCommand::SelectFolderFromListL(
        CDesCArrayFlat* aItems, TBool aIsRoot )
    {
    TInt selected( KErrNotFound );
    
    CAknListQueryDialog* dialog =
        new ( ELeave ) CAknListQueryDialog( &selected );
    if( aIsRoot )
        {
        dialog->PrepareLC( R_MENU_EDIT_MOVE_TO_FOLDER_SELECT_CANCEL_QUERY );
        }
    else
        {
        dialog->PrepareLC( R_MENU_EDIT_MOVE_TO_FOLDER_SELECT_BACK_QUERY );
        }
    dialog->SetItemTextArray( aItems );
    dialog->SetOwnershipType( ELbmDoesNotOwnItemArray );
    CArrayPtr<CGulIcon>* icons = GetFolderIconsL();
    dialog->SetIconArrayL( icons );
    dialog->ListBox()->SetCurrentItemIndexAndDraw( 0 );
    
    if( !iLockDialog )
        {
        SetDialogL( dialog );
        TInt softkey ( KErrNotFound );
        softkey = dialog->RunLD();
        SetDialogL( NULL );
        
        if( softkey == KSoftkeyBack )
            {
            selected = EAknSoftkeyBack;
            }
        else if( selected < 0 ||
                ( softkey != EAknSoftkeyOk && softkey != EAknSoftkeySelect ) )
            {
            selected = EAknSoftkeyExit;
            }
        }
    else
        {
        CleanupStack::PopAndDestroy( dialog );
        selected = EAknSoftkeyExit;
        }

    return selected;
    }


// ---------------------------------------------------------------------------
// Action resolving function.
// ---------------------------------------------------------------------------
//  
CArrayPtr<CGulIcon>* CMmMoveToFolderCommand::GetFolderIconsL()
    {
    CArrayPtr<CGulIcon>* icons = new( ELeave )CAknIconArray( 10 );
    CleanupStack::PushL( icons );
    CFbsBitmap* folderClosed     = NULL;
    CFbsBitmap* folderClosedMask = NULL;
        
    AknIconUtils::CreateIconL( folderClosed, folderClosedMask,
            AknIconUtils::AvkonIconFileName(),
            EMbmAvkonQgn_prop_folder_small,
            EMbmAvkonQgn_prop_folder_small_mask );
    CleanupStack::PushL( folderClosed );
    CleanupStack::PushL( folderClosedMask );
    icons->AppendL( CGulIcon::NewL( folderClosed, folderClosedMask ) );
    CleanupStack::Pop( 2 );

    CFbsBitmap* folderOpened     = NULL;
    CFbsBitmap* folderOpenedMask = NULL;
    AknIconUtils::CreateIconL( folderOpened, folderOpenedMask,
            AknIconUtils::AvkonIconFileName(),
            EMbmAvkonQgn_prop_folder_current, 
            EMbmAvkonQgn_prop_folder_current_mask );
    CleanupStack::PushL( folderOpened );
    CleanupStack::PushL( folderOpenedMask );
    icons->AppendL( CGulIcon::NewL( folderOpened, folderOpenedMask ) );
    CleanupStack::Pop( 3 );
    return icons;
    }


// ---------------------------------------------------------------------------
// Action resolving function.
// ---------------------------------------------------------------------------
//  
HBufC* CMmMoveToFolderCommand::GetFromResourceLC( TInt aIdentifier )
    {
    HBufC* string = StringLoader::LoadLC( aIdentifier );
    return string;
    }


// ---------------------------------------------------------------------------
// Action resolving function.
// ---------------------------------------------------------------------------
//  
void CMmMoveToFolderCommand::NotificationMovingCompleteL()
    {
    CDesCArrayFlat* items = new(ELeave) CDesCArrayFlat( 1 );
    CleanupStack::PushL( items );
    items->AppendL( iItemName );
    items->AppendL( iFolderName );
    
    HBufC* msg = StringLoader::LoadLC( R_APPS_NOTE_MOVE_TO_FOLDER, *items );
    CAknNoteDialog* dialog = new (ELeave) CAknNoteDialog(
            CAknNoteDialog::EConfirmationTone,
            CAknNoteDialog::ELongTimeout );
    dialog->SetTextL( msg->Des() );
    dialog->ExecuteDlgLD( R_MENU_EDIT_MOVING_COMPLETE_NOTIFICATION );
    
    CleanupStack::PopAndDestroy( msg );
    CleanupStack::PopAndDestroy( items );
    }


// ---------------------------------------------------------------------------
// Action resolving function.
// ---------------------------------------------------------------------------
//  
void CMmMoveToFolderCommand::NotificationItemAlreadyStoredL()
    {
    HBufC* message = StringLoader::LoadLC( R_APPS_NOTE_ITEM_ALREADY_STORED );
    CAknNoteDialog* dialog = new (ELeave) CAknNoteDialog(
            CAknNoteDialog::EConfirmationTone,
            CAknNoteDialog::ELongTimeout );
    dialog->SetTextL( message->Des() );
    dialog->ExecuteDlgLD( R_MENU_EDIT_MOVING_ABORT_NOTIFICATION );
    
    CleanupStack::PopAndDestroy( message );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::StepBackInHierarchy()
	{
	// Remove last folder from iOpenedHierarchy
	CMmFolder* folder = CurrentFolder();
	iOpenedHierarchy.Remove( iOpenedHierarchy.Count() - 1 );
	delete folder;
	}



// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::ExecuteMoveToFolderL()
	{
    while (iOpenedHierarchy.Count() > 0)
    	{
    	// Get folder list form MCS
    	GetFolderListL( CurrentFolder()->Id() );
    	
    	RPointerArray< CMmFolder > folders;
    	CleanupResetAndDestroyPushL( folders );

    	// Get folders from GetList output
    	GetFoldersL(folders);

    	// Perform further folder selection or move operation
    	if( folders.Count() > 0 )
    		{
    		SelectFolderL( folders );
    		}
    	else
    		{
    		iFolderName.Close();
    		iFolderName.CreateL( CurrentFolder()->Name() );
    		MoveToFolderL( iItemId, CurrentFolder()->Id() );
    		}
    	CleanupStack::PopAndDestroy( &folders );
    	}
	}

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmMoveToFolderCommand::GetFoldersL(RPointerArray<CMmFolder >& aFolderArray)
	{
	TInt pos( 0 );
	TInt count = iGetListOutParam->FindFirst(
			pos, KReturnValue8() )->Value().AsList()->Count();
	TLiwVariant var; var.PushL();
	
	// Get propper widget names depending from view type
	// and append to aFolderArray
	for( TInt i = 0; i < count; i++ )
		{
		HnLiwUtils::GetVariantL( *iGetListOutParam, KIdPath8, i, var );
		TInt32 id;
		var.Get( id );

		if (id != iItemId)
			{
			CMmFolder* folder = CMmFolder::NewL();
			CleanupStack::PushL( folder );
			
			folder->SetId( id );
			
			TPtrC title;
			if( !iWidgetType.Compare( KWidgetTypeList ) )
				{
				HnLiwUtils::GetVariantL(
						*iGetListOutParam, KLongNamePath8, i, var );
				}
			else if( !iWidgetType.Compare( KWidgetTypeGrid ) )
				{
				HnLiwUtils::GetVariantL(
						*iGetListOutParam, KShortNamePath8, i, var );
				}
			else
				{
				HnLiwUtils::GetVariantL(
						*iGetListOutParam, KAppGroupNamePath8, i, var );
				}
			var.Get( title );
			folder->SetNameL( title );
			aFolderArray.AppendL( folder );
			
			CleanupStack::Pop( folder );
			}
		}
	CleanupStack::PopAndDestroy(&var);
	}

// ---------------------------------------------------------------------------
// Symbian factory function.
// ---------------------------------------------------------------------------
//
CMmFolder* CMmFolder::NewL()
    {
    CMmFolder* self = new( ELeave ) CMmFolder();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// Symbian second phase constructor.
// ---------------------------------------------------------------------------
//
void CMmFolder::ConstructL()
    {
    }

// ---------------------------------------------------------------------------
// Destructor.
// ---------------------------------------------------------------------------
//
CMmFolder::~CMmFolder()
    {
    iName.Close();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CMmFolder::CMmFolder()
    {
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolder::SetNameL( const TDesC& aName )
    {
    iName.Close();
    iName.CreateL( aName );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
const TDesC& CMmFolder::Name() const
    {
    return iName;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CMmFolder::SetId( TInt aId )
    {
    iId = aId;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TInt CMmFolder::Id()
    {
    return iId;
    }
    
// end of file