diff -r 000000000000 -r ba25891c3a9e ncdengine/provider/client/src/ncdnodefolderproxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ncdengine/provider/client/src/ncdnodefolderproxy.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,407 @@ +/* +* 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: Contains CNcdNodeFolderProxy class implementation +* +*/ + + +#include "ncdnodefolderproxy.h" +#include "ncdnodemetadataproxy.h" +#include "catalogsclientserver.h" +#include "ncdnodemanagerproxy.h" +#include "ncdoperationmanagerproxy.h" +#include "ncdnodeidentifier.h" +#include "catalogsdebug.h" +#include "ncdnodefunctionids.h" +#include "ncdnodeclassids.h" +#include "catalogsinterfaceidentifier.h" +#include "ncdloadnodeoperationproxy.h" +#include "ncdnodesearchimpl.h" +#include "catalogsutils.h" +#include "ncdchildentity.h" +#include "ncdproviderdefines.h" +#include "ncdnodeuricontentproxy.h" +#include "ncdcapabilities.h" +#include "ncdnodeseenfolderproxy.h" +#include "ncderrors.h" + +CNcdNodeFolderProxy::CNcdNodeFolderProxy( MCatalogsClientServer& aSession, + TInt aHandle, + CNcdNodeManagerProxy& aNodeManager, + CNcdOperationManagerProxy& aOperationManager, + CNcdFavoriteManagerProxy& aFavoriteManager ) +: CNcdNodeProxy( aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager ) + { + } + + +void CNcdNodeFolderProxy::ConstructL() + { + CNcdNodeProxy::ConstructL(); + + // Add the interface information to the list + MNcdNodeContainer* container( this ); + AddInterfaceL( + CCatalogsInterfaceIdentifier::NewL( container, this, MNcdNodeContainer::KInterfaceUid ) ); + } + + +CNcdNodeFolderProxy* CNcdNodeFolderProxy::NewL( MCatalogsClientServer& aSession, + TInt aHandle, + CNcdNodeManagerProxy& aNodeManager, + CNcdOperationManagerProxy& aOperationManager, + CNcdFavoriteManagerProxy& aFavoriteManager ) + { + CNcdNodeFolderProxy* self = + CNcdNodeFolderProxy::NewLC( + aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager ); + CleanupStack::Pop( self ); + return self; + } + +CNcdNodeFolderProxy* CNcdNodeFolderProxy::NewLC( MCatalogsClientServer& aSession, + TInt aHandle, + CNcdNodeManagerProxy& aNodeManager, + CNcdOperationManagerProxy& aOperationManager, + CNcdFavoriteManagerProxy& aFavoriteManager ) + { + CNcdNodeFolderProxy* self = + new( ELeave ) CNcdNodeFolderProxy( + aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager ); + // Using PushL because the object does not have any references yet + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +CNcdNodeFolderProxy::~CNcdNodeFolderProxy() + { + // Remove interfaces implemented by this class from the interface list. + // So, the interface list is up to date when this class object is deleted. + RemoveInterface( MNcdNodeContainer::KInterfaceUid ); + RemoveInterface( MNcdNodeSearch::KInterfaceUid ); + + // Delete the objects that are owned by this class and provide functionality + // through the api. + // Notice that the api-objects are Released (not deleted) from the UI side. + // The node owns the data and the reference counter of the node keeps + // track of the api objects it owns. When the reference counter of the node + // reaches zero, it means that nobody is using the node or the classes owned + // by the node. If somebody is using the object owned by the node, the reference + // counter can not be zero until everything is released. + // Thus, the node may delete the data here. + + delete iSearch; + iSearch = NULL; + + delete iNodeSeenFolder; + iNodeSeenFolder = NULL; + + iChildren.ResetAndDestroy(); + } + + + + +TInt CNcdNodeFolderProxy::ExpectedChildCount() const + { + return iExpectedChildCount; + } + + +MNcdLoadNodeOperation* CNcdNodeFolderProxy::LoadL( + MNcdLoadNodeOperationObserver& aObserver ) + { + DLTRACEIN((_L("This ns: %S, id: %S"), &Namespace(), &Id() )); + return CNcdNodeProxy::LoadL( aObserver ); + } + + +TInt CNcdNodeFolderProxy::ChildCount() const + { + return iExpectedChildCount; + } + + +MNcdNode* CNcdNodeFolderProxy::ChildL( TInt aIndex ) + { + DLTRACEIN(( _L("This parent: %S, %S"), &Namespace(), &Id(), aIndex )); + DLINFO(("aIndex = %d, expected childcount= %d, real child count = %d", + aIndex, iExpectedChildCount, iChildren.Count() )); + + if ( aIndex < 0 || aIndex >= iExpectedChildCount ) + { + // Nothing to be done + DLERROR(( "Index error. expected child count: %d Given index: %d", + iExpectedChildCount, aIndex )); + DASSERT( EFalse ); + User::Leave( KErrArgument ); + } + + // search for a child with given index + const CNcdNodeIdentifier* child = NULL; + for( TInt i = 0 ; i < iChildren.Count() ; i++ ) + { + if ( iChildren[i]->Index() == aIndex ) + { + child = &iChildren[i]->Identifier(); + } + else if ( iChildren[i]->Index() > aIndex ) + { + // no sense in searching further + break; + } + } + + if( child == NULL ) + { + return NULL; + } + + MNcdNode* node( NULL ); + + TRAPD( err, node = &NodeManager().NodeL( *child ) ); + + if ( err == KErrNotFound ) + { + return NULL; + } + + User::LeaveIfError( err ); + + // Increase the reference counter by one + node->AddRef(); + + DLTRACEOUT(("")); + + return node; + } + + +MNcdLoadNodeOperation* CNcdNodeFolderProxy::LoadChildrenL( TInt aIndex, + TInt aSize, + TNcdChildLoadMode aMode, + MNcdLoadNodeOperationObserver& aObserver ) + { + DLTRACEIN(("aIndex: %d, aSize: %d, expected child count: %d, load mode: %d", + aIndex, aSize, iExpectedChildCount, aMode )); + + if ( aSize < 1 + || aIndex < 0 + || ( aMode == ELoadMetadata + && aSize != KMaxTInt + && aIndex + aSize > ChildCount() ) ) + { + // Nothing to be done + DLERROR(( "Argument error. ChildCount: %d Given index: %d, size: %d", + ChildCount(), aIndex, aSize )); + User::Leave( KErrArgument ); + } + + if ( aSize == KMaxTInt ) + { + // Because aSize is KMaxTInt, reduce it by the aIndex value. + // This way we will not have possible overload if aIndex is later added + // to the aSize value. It does not really matter what the aSize value is + // after this. KMaxTInt is so great value, that in all the cases the server + // request should give all the required items. + aSize -= aIndex; + DLINFO(("aSize was KMaxTInt. Reduced by index: %d", aSize)); + } + + DLTRACE(( _L("Node: %S, %S"), &Namespace(), &Id() )); + + CNcdLoadNodeOperationProxy* operation = + OperationManager().CreateLoadNodeOperationL( + *this, ETrue, aSize, aIndex, 1, aMode ); + + if ( !operation ) + { + DLTRACEOUT(("NULL")); + return NULL; + } + + operation->AddObserverL( this ); + operation->AddObserverL( &aObserver ); + + DLTRACEOUT(("")); + + return operation; + } + +TNcdContainerType CNcdNodeFolderProxy::ContainerType() const + { + if ( IsRemote() ) + { + return ECatalog; + } + else + { + return EFolder; + } + } + +void CNcdNodeFolderProxy::OperationComplete( + MNcdLoadNodeOperation& /*aOperation*/, TInt aError ) + { + DLTRACEIN(( "Error: %d", aError )); + + if ( aError == KErrNone || aError == KNcdErrorSomeCatalogsFailedToLoad ) + { + // update proxy's status from the server + TRAP_IGNORE( InternalizeL() ); + } + } + +void CNcdNodeFolderProxy::InternalizeL() + { + DLTRACEIN(("")); + + // First call the parent internalizator. So, all the parent stuff will + // be initialized before folder specific data. + CNcdNodeProxy::InternalizeL(); + + // Add the search interface because it is availabe for all the folders + // that have at least one child. + + // check that is search supported for this node + TBool isSearchSupported = IsSearchSupportedL(); + + DLINFO(( "isSearchSupported: %d, child count: %d", isSearchSupported, + ChildCount() )); + if ( isSearchSupported ) + { + DLTRACE(("add search interface")); + if ( iSearch == NULL ) + { + // Create new search because old one did not exist. + // Notice that the creation adds the interface to the node interface list + // automatically. + iSearch = CNcdNodeSearch::NewL( *this, OperationManager() ); + } + } + else + { + DLTRACE(("remove search interface")); + delete iSearch; + iSearch = NULL; + } + + InternalizeNodeSeenFolderL(); + + DLTRACEOUT(("")); + } + + +void CNcdNodeFolderProxy::InternalizeNodeDataL( RReadStream& aStream ) + { + DLTRACEIN(("")); + + // First internalize parent data + CNcdNodeProxy::InternalizeNodeDataL( aStream ); + + // Get the children data here. + + DLTRACE(("Handle children")); + + // Clear the buffer because new childs will be appended + iChildren.ResetAndDestroy(); + + TInt childrenCount( aStream.ReadInt32L() ); + DLTRACE(("Children: %d", childrenCount )); + + TInt classObjectType( NcdNodeClassIds::ENcdNullObjectClassId ); + + for ( TInt i = 0; i < childrenCount; ++i ) + { + // This is safe casting because enum is same as TInt + classObjectType = + static_cast(aStream.ReadInt32L()); + if ( NcdNodeClassIds::ENcdChildEntityClassId == classObjectType ) + { + CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( aStream ); + iChildren.AppendL( childEntity ); + CleanupStack::Pop( childEntity ); + DLINFO((_L("Added child, id: %S, array index: %d, real index: %d"), + &childEntity->Identifier().NodeId(), i, childEntity->Index() )); + } + else + { + // For debug purposes + DLERROR(("Wrong class id")); + DASSERT( EFalse ); + + // Wrong kind of class object info + User::Leave( KErrCorrupt ); + } + } + + // Show node info here, after the internalization has been done. + DLTRACEOUT(( _L("Node: %S, %S, %d"), + &Namespace(), &Id(), NodeIdentifier().ClientUid().iUid )); + } + + +void CNcdNodeFolderProxy::InternalizeNodeLinkDataL( RReadStream& aStream ) + { + DLTRACEIN(( _L("Node: %S, %S"), &Namespace(), &Id() )); + + // First internalize parent data + CNcdNodeProxy::InternalizeNodeLinkDataL( aStream ); + + // Then, set the data for this class object + + iExpectedChildCount = aStream.ReadInt32L(); + + DLTRACEOUT(("")); + } + +TBool CNcdNodeFolderProxy::IsSearchSupportedL() + { + DLTRACEIN(("")); + // check if this node has search capability set + return NodeManager().IsCapabilitySupportedL( NodeIdentifier(), + NcdCapabilities::KSearch ); + } + + +void CNcdNodeFolderProxy::InternalizeNodeSeenFolderL() + { + DLTRACEIN(("")); + + if ( iNodeSeenFolder ) + { + iNodeSeenFolder->InternalizeL(); + } + else + { + // Create the object. + // Get the handle at first. + TInt handle( 0 ); + User::LeaveIfError( + ClientServerSession().SendSync( + NcdNodeFunctionIds::ENcdNodeSeenFolderHandle, + KNullDesC(), + handle, + Handle() ) ); + + DLINFO(( "handle: %d", handle )); + + iNodeSeenFolder = CNcdNodeSeenFolderProxy::NewL( + ClientServerSession(), handle, *this ); + } + } + +