photosgallery/controllers/collectionmanager/src/glxcollectionmanagerimpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:45:44 +0200
changeset 0 4e91876724a2
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2008-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:    Implementation of collection manager API for external use
*
*/




#include "glxcollectionmanagerimpl.h"

#include <glxcommandfactory.h>
#include <glxpanic.h>
#include <mpxcollectionmessage.h>
#include <mpxcollectionpath.h>
#include <mpxcollectionutility.h>
#include <mpxmediacontainerdefs.h>
#include <mpxmediageneraldefs.h>
#include <mpxmessagegeneraldefs.h>

#include "glxcollectioninfo.h"

#include <glxcollectionplugincamera.hrh>
#include <glxcollectionpluginalbums.hrh>

// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
//
CGlxCollectionManagerImpl::CGlxCollectionManagerImpl()
    {
    }
// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
//
CGlxCollectionManagerImpl::~CGlxCollectionManagerImpl()
    {
    CloseCollection();
    delete iUri;
    }
// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::AddToContainerL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::AddToContainerL(const TDesC& aUri, 
		CGlxCollectionManager::TCollection aContainer, TRequestStatus& aRequestStatus)
    {
    __ASSERT_DEBUG(CGlxCollectionManager::ECollectionCameraAlbum == aContainer, Panic(EGlxPanicUnsupportedCollection));
    
    iCollectionId.iUid = KGlxCollectionPluginCameraImplementationUid;
    iContainerId = 0; // A zero container id indicates to the data source that we wish to the 
    // 'special album' related to the collection id. e.g. the camera album.
    
    AddToContainerL(aUri,aRequestStatus);
    }
    
// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::AddToContainerL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::AddToContainerL(const TDesC& aUri, 
                        TUint32 aCollectionId, TRequestStatus& aRequestStatus)
    {
    iCollectionId.iUid = KGlxCollectionPluginAlbumsImplementationUid;
    iContainerId = aCollectionId;
    
    AddToContainerL(aUri,aRequestStatus);
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::CollectionInfoL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::CollectionInfoL(CGlxCollectionInfo& aInfo,
                        TRequestStatus& aRequestStatus)
    {
    __ASSERT_DEBUG(iState == EClosed || iState == EOpen, Panic(EGlxPanicIllegalState));
    
    iCollectionInfo = &aInfo;
    InitializeRequest(aRequestStatus);
    
    if (iState == EOpen)
    	{
    	CloseCollection(); // Close and re-open the collection to ensure we have the
    	                   // latest changes.
    	}

    iState = EOpeningForCollectionInfo;
    OpenCollectionL();
    
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::Cancel
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::Cancel()
    {	
    ///@todo test canceling
    
    switch (iState)
    	{
    	case EClosed:
    	case EOpen:
    	case EOpening:
    		{
    		// no request outstanding
    		break;
    		}
    	case EOpeningForAdd:
    	case EOpeningForCollectionInfo:
    		{
    		iState = EOpening; // Complete open if we can.
    		break;		
    		}
    	case EAdding:
    	case ERequestingMedia:
    		{
    		iState = EOpen;
    		iCollectionUtility->Collection().CancelRequest();
    		}
    	}
    CompleteRequest(KErrCancel);
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::HandleCollectionMessageL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::HandleCollectionMessageL(const TMPXCollectionMessage& /*aMessage*/)
    {
    // Don't do anything.
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::HandleCollectionMessageL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::HandleCollectionMessageL(const CMPXMessage& aMsg)
    {
    if (aMsg.IsSupported(KMPXMessageGeneralEvent))
    	{
	    switch (aMsg.ValueTObjectL<TInt>(KMPXMessageGeneralEvent))
	    	{
	    	case TMPXCollectionMessage::EPathChanged:
	    		{
	            __ASSERT_DEBUG(iState == EOpeningForAdd || iState == EOpeningForCollectionInfo || iState == EOpening || iState == EOpen, Panic(EGlxPanicIllegalState));
	    		
	            TState oldState = iState;
	            iState = EOpen;
	            
	            switch(oldState)
	            {
	            case EOpeningForAdd:
	            	{
	            	iState = EOpen;
	            	DoAddToContainerL();
	            	break;
	            	}
	            case EOpeningForCollectionInfo:
	            	{
	        		iState = EOpen;
	            	__ASSERT_DEBUG(iCollectionInfo, Panic(EGlxPanicNullPointer));
		 
	        		DoCollectionInfoL();
	        		break;
	            	}
	            case EOpening:
	            	{
	            	// don't do anything
	            	break;
	            	}
		    		}
	    		}
	    	break;
	    	default:
	    	break;
	    	}
    	}
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::HandleOpenL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::HandleOpenL(const CMPXMedia& /*aEntries*/,
                         TInt /*aIndex*/,TBool /*aComplete*/,TInt aError)
    { 
    // Handle open only gets called when an error occurs
    ///@todo check that this method works
    
    __ASSERT_DEBUG(iState == EOpening || iState == EOpeningForAdd || iState == EOpeningForCollectionInfo, Panic(EGlxPanicIllegalState));
    	
    if (aError != KErrNone)
    	{
    	CompleteRequest(aError);
    	iState = EClosed;
    	}  	
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::HandleOpenL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::HandleOpenL(const CMPXCollectionPlaylist& /*aPlaylist*/ ,TInt /*aError*/)
    {
    // Don't do anything.
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::HandleCollectionMediaL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::HandleCollectionMediaL(const CMPXMedia& aMedia, TInt aError)
    {
    iState = EOpen;    	
    
    if (aError == KErrNone && iCollectionInfo)
    	{
        iCollectionInfo->SetExists(ETrue);
        iCollectionInfo->SetTitleL(aMedia.ValueText(KMPXMediaGeneralTitle));
    	}
  
    CompleteRequest(aError);
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::HandleCommandComplete
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::HandleCommandComplete(CMPXCommand* /*aCommandResult*/, TInt aError)
    {
    CompleteRequest(aError);
    iState = EOpen;
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::CompleteRequest
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::CompleteRequest(TInt aError)
    {
    if (iRequestStatus)
        {
        User::RequestComplete(iRequestStatus, aError);
        iRequestStatus = NULL;
        }
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::InitializeRequest
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::InitializeRequest(TRequestStatus& aRequestStatus)
    {
    __ASSERT_DEBUG(!iRequestStatus, Panic(EGlxPanicCollectionManagerOutstandingRequest));
    iRequestStatus = &aRequestStatus;
    *iRequestStatus = KRequestPending;
    }

/// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::OpenCollectionL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::OpenCollectionL()
    {
    if (iCollectionUtility)
    	{
    	iCollectionUtility->Close(); // deletes the collection utility's this pointer. 
    	}
    iCollectionUtility = NULL;
    iCollectionUtility = MMPXCollectionUtility::NewL(this);
	CMPXCollectionPath* path = CMPXCollectionPath::NewL();
    CleanupStack::PushL(path);
	path->AppendL(KGlxCollectionPluginAlbumsImplementationUid); //Open the albums collection plugin
	// We can use this plugin to add things to the camera album.
	iCollectionUtility->Collection().OpenL(*path);
	CleanupStack::PopAndDestroy(path);
    }

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::CloseCollection
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::CloseCollection()
	{
	if (iCollectionUtility)
		{
		iCollectionUtility->Close();
		iCollectionUtility = NULL;
		}
	iState = EClosed;
	}

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::DoAddToContainerL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::DoAddToContainerL()
	{
	__ASSERT_DEBUG(iState == EOpen, Panic(EGlxPanicIllegalState));
	CMPXCollectionPath* targetContainerPath = CMPXCollectionPath::NewL();
    CleanupStack::PushL(targetContainerPath);
    targetContainerPath->AppendL(iCollectionId.iUid);

    targetContainerPath->AppendL(iContainerId);
    CMPXCommand* command = TGlxCommandFactory::AddToContainerCommandLC(*iUri, *targetContainerPath);
    CleanupStack::Pop(command);
    CleanupStack::PopAndDestroy(targetContainerPath);
    CleanupStack::PushL(command);
    iCollectionUtility->Collection().CommandL(*command);
    CleanupStack::PopAndDestroy(command);
    iState = EAdding;
	}

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::AddToContainerL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::AddToContainerL(const TDesC& aUri, TRequestStatus& aRequestStatus)
	{
    __ASSERT_DEBUG(iState == EClosed || iState == EOpen,  Panic(EGlxPanicIllegalState));
    
    InitializeRequest(aRequestStatus);
    
	delete iUri;
    iUri = NULL;
    iUri = aUri.AllocL();
    
    if (iState == EClosed)
    	{
    	iState = EOpeningForAdd;
    	OpenCollectionL();
    	}
    else
    	{
    	DoAddToContainerL();
    	}
	}

// -----------------------------------------------------------------------------
// CGlxCollectionManagerImpl::DoCollectionInfoL
// -----------------------------------------------------------------------------
//
void CGlxCollectionManagerImpl::DoCollectionInfoL()
	{
    __ASSERT_DEBUG(iState == EOpen,  Panic(EGlxPanicIllegalState));
	CMPXCollectionPath* path = iCollectionUtility->Collection().PathL();
	CleanupStack::PushL(path);
	
	TInt index = path->IndexOfId(iCollectionInfo->Id());
	if (index == KErrNotFound)
		{
		iCollectionInfo->SetExists(EFalse);
		CompleteRequest(KErrNone);
		}
	else if(index < 0) // Index is an error other than KErrNotFound
		{
		CompleteRequest(index);
		}
	else
		{
		// the index is good get the title
		path->Set(index);
		
		RArray<TMPXAttribute> attributeArray;
		CleanupClosePushL(attributeArray);
		attributeArray.AppendL(KMPXMediaGeneralTitle);
		iCollectionUtility->Collection().MediaL(*path, attributeArray.Array());
		CleanupStack::PopAndDestroy(&attributeArray);
		iState = ERequestingMedia;
		}
	CleanupStack::PopAndDestroy(path);
	}