ui/commandhandlers/commoncommandhandlers/src/glxcommandhandlerrename.cpp
author hgs
Thu, 14 Oct 2010 17:54:23 +0530
changeset 72 0a8e959402e5
parent 62 36d93b4dc635
permissions -rw-r--r--
201041

/*
 * Copyright (c) 2009 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: 
 *
 */

//Includes Qt/Symbian
#include <QFile>
#include <caf/manager.h>

//Includes Orbit
#include <hblabel.h>
#include <hbmessagebox.h>

//User Includes
#include <mglxmedialist.h>
#include <glxcommondialogs.h>
#include <mpxcollectionpath.h>
#include <glxcommandfactory.h>
#include <glxattributecontext.h>
#include <glxcommandhandlers.hrh>
#include <glxattributeretriever.h>
#include "glxlocalisationstrings.h"
#include <glxfetchcontextremover.h>
#include <glxcommandhandlerrename.h>   

GlxCommandHandlerRename::GlxCommandHandlerRename()
    {
    }

GlxCommandHandlerRename::~GlxCommandHandlerRename()
    {
    }

CMPXCommand* GlxCommandHandlerRename::CreateCommandL(TInt aCommandId,
        MGlxMediaList& aMediaList, TBool& aConsume) const
    {
    Q_UNUSED(aCommandId);
    Q_UNUSED(aConsume);
    
    bool ok = false;
    CMPXCommand* command = NULL;
    CMPXCollectionPath* path = NULL;
    QString mainPane = GetName(aMediaList);
    GlxTextInputDialog* dlg = new GlxTextInputDialog();

    if (aCommandId == EGlxCmdRenameFile)
        {
        mMediaTitle = dlg->getText(GLX_DIALOG_NAME_PROMPT, mainPane, &ok);
        }
    else
        {
        mMediaTitle = dlg->getText(GLX_DIALOG_ALBUM_PROMPT, mainPane, &ok);
        }
    delete dlg;

    if(ok == true)
        {
        TPtrC16 newMediaItemTitleDes =
                (reinterpret_cast<const TUint16*> (mMediaTitle.utf16()));
        HBufC* newMediaItemTitle = newMediaItemTitleDes.Alloc();
        CleanupStack::PushL(newMediaItemTitle);

        if (aCommandId == EGlxCmdRenameFile)
            {
            TDesC& aTitleText = *newMediaItemTitle;
            TInt index = aMediaList.FocusIndex();
            const TGlxMedia& media = aMediaList.Item(index);
            TParsePtrC parsePtr(media.Uri());

            //Constructs the File Name with complete Path
            TFileName destinationFileName;
            destinationFileName.Append(parsePtr.DriveAndPath());
            destinationFileName.Append(aTitleText);
            destinationFileName.Append(parsePtr.Ext());

            HBufC* modifiedName = destinationFileName.AllocLC();
            QString fileName = QString::fromUtf16(modifiedName->Ptr(),
                    modifiedName->Length());

            ContentAccess::CManager *manager =
                    ContentAccess::CManager::NewL();
            CleanupStack::PushL(manager);

            QFile filePath(fileName);
            bool isFileExist = filePath.exists();

            if (!isFileExist)
                {
                //rename the media
                TInt error = manager->RenameFile(media.Uri(), *modifiedName);
				//reset the flag to 'false'!
                iIsCmdActive = false;
                
				/*
				1. Photos renames the file with file system services
                2. Photos tries to update the title of the renamed images
                -> Image object is opened for modifications
                3. MDS gets notification from the file server that the image has been renamed
                -> Handling this fails with -22 KErrLocked as the same object is opened
                by Photos for changing the title
                -> MDS cannot update the the URI or Title for locked object
                4. Photos completes updating the title
                -> title for xxx.jpg is set as A, but the uri is still xxx.jpg in
                MDS DB as MDS could not modify the object--
				So Removing the manually changing of the title completely.
				As MDS will update the title field automatically if it was originally
				populated from the uri, changing the title manually after rename is complitely
				unnecessary anyway. So let MDS do the updating by itself as it should,
				and you will still get modified event from MDS when the update, including
				the title, is complete
                */
				/*
				if (error == KErrNone)
                    {
                    path = aMediaList.PathLC(
                            NGlxListDefs::EPathFocusOrSelection);
                    command = TGlxCommandFactory::RenameCommandLC(
                            *newMediaItemTitle, *path);
                    CleanupStack::Pop(command);
                    CleanupStack::PopAndDestroy(path);
                    }*/
                }
            else
                {
                //The Name of the file name already exists, display an message .
                HandleErrorL(KErrAlreadyExists);
                }
            CleanupStack::PopAndDestroy(manager);
            CleanupStack::PopAndDestroy(modifiedName);
            CleanupStack::PopAndDestroy(newMediaItemTitle);
            }
        else
            {
            //Rename of Album
            CMPXCollectionPath* path = aMediaList.PathLC(
                    NGlxListDefs::EPathFocusOrSelection);
            command = TGlxCommandFactory::RenameCommandLC(*newMediaItemTitle,
                    *path);
            CleanupStack::Pop(command);
            CleanupStack::PopAndDestroy(path);
            CleanupStack::PopAndDestroy(newMediaItemTitle);
            }
        }
    else
        {
		// If cancel is pressed, reset the flag!!
        iIsCmdActive = false;
        }
    return command;
    }

QString GlxCommandHandlerRename::CompletionTextL() const
    {
	//return command completion text
	return QString();
    }

QString GlxCommandHandlerRename::GetName(MGlxMediaList& aMediaList) const
    {
        // Create an iterator to retrieve the relevant attribute
    TGlxSelectionIterator iterator;
    // only want the title of one item
	iterator.SetRange( 1 );
    CGlxAttributeContext* context = new( ELeave )
        CGlxAttributeContext( &iterator );
	CleanupStack::PushL( context );
        
	// Want to read the title attribute    
    // Configure the context
	context->AddAttributeL( KMPXMediaGeneralTitle );
	
	// Add the context to the media list
	aMediaList.AddContextL( context, KGlxFetchContextPriorityBlocking );

    // TGlxContextRemover will remove the context when it goes out of scope
    // Used here to avoid a trap and still have safe cleanup    
    TGlxFetchContextRemover contextRemover( context, aMediaList );
    // put to cleanupstack as cleanupstack is emptied before stack objects
    // are deleted
    CleanupClosePushL( contextRemover );
	// Yuck - a leave and a return code!
	// EFalse => don't show a progress dialog
    TInt err = GlxAttributeRetriever::RetrieveL( *context, aMediaList, EFalse );
    // Using a distinct error value as "LeaveIfError( FuncL() );" looks bad
    User::LeaveIfError( err );
    // context off the list
    CleanupStack::PopAndDestroy( &contextRemover );

    // Now get the title of the relevant item: if *an* item is selected use its
    // title, otherwise use the item with focus
	// Get the index of the item to rename
    TInt index = KErrNotFound;
    QString title = NULL;
	// first see if there's a selected item...
    if ( aMediaList.SelectionCount() == 1 )
    	{
        // Find the index of the selected item
    	index = aMediaList.Count();
    	do
            {
            --index;
            }
        while ( !aMediaList.IsSelected( index ) && index > 0 );
    	}
    else
    	{
    	// Use the index of the item with focus
       	index = aMediaList.FocusIndex();
    	}

	if ( index != KErrNotFound )
		{
        // use iterator to get the right item
        iterator.SetToFirst( &aMediaList );
        const CGlxMedia* media = aMediaList.Item( iterator++ ).Properties();
		if( media )
			{
			// found the item's media properties, extract the title
            const TDesC& titleDesc = media->ValueText(KMPXMediaGeneralTitle);
            title = QString::fromUtf16(titleDesc.Ptr(),
                    titleDesc.Length());
			}
		}
    CleanupStack::PopAndDestroy( context );

    return title;
    }

void GlxCommandHandlerRename::HandleErrorL(TInt aErrorCode) const
	{
    if(aErrorCode == KErrAlreadyExists)
        {
        QString stringToDisplay = hbTrId(GLX_NAME_ALREADY_EXIST).arg(
                mMediaTitle);
        HbMessageBox::warning(stringToDisplay);
        }
	else{
		GlxMpxCommandHandler::HandleErrorL(aErrorCode);
		}	
	}