--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/server/src/ncdnodeseenfolderimpl.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,344 @@
+/*
+* 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:
+*
+*/
+
+
+#include "ncdnodeseenfolderimpl.h"
+#include "catalogsdebug.h"
+#include "ncdnodefunctionids.h"
+#include "catalogsbasemessage.h"
+#include "ncdnodemanager.h"
+#include "ncdnodefolder.h"
+#include "ncdnodeseenimpl.h"
+#include "catalogsutils.h"
+#include "ncdnodeidentifier.h"
+
+CNcdNodeSeenFolder* CNcdNodeSeenFolder::NewL( CNcdNodeFolder& aParent )
+ {
+ DLTRACEIN((""));
+ CNcdNodeSeenFolder* self = NewLC( aParent );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+CNcdNodeSeenFolder* CNcdNodeSeenFolder::NewLC( CNcdNodeFolder& aParent )
+ {
+ DLTRACEIN((""));
+ CNcdNodeSeenFolder* self = new( ELeave ) CNcdNodeSeenFolder( aParent );
+ CleanupClosePushL( *self );
+ self->ConstructL();
+ return self;
+ }
+
+
+CNcdNodeSeenFolder::CNcdNodeSeenFolder( CNcdNodeFolder& aParent ) :
+ iOwnerNode( aParent )
+ {
+ }
+
+
+void CNcdNodeSeenFolder::ConstructL()
+ {
+ }
+
+
+CNcdNodeSeenFolder::~CNcdNodeSeenFolder()
+ {
+ DLTRACEIN((""));
+ }
+
+
+void CNcdNodeSeenFolder::ReceiveMessage(
+ MCatalogsBaseMessage* aMessage,
+ TInt aFunctionNumber )
+ {
+ DLTRACEIN((""));
+
+ DASSERT( aMessage );
+
+ TInt trapError( KErrNone );
+
+ switch( aFunctionNumber )
+ {
+ case NcdNodeFunctionIds::ENcdNodeSeenFolderSetContentsSeen:
+ TRAP( trapError, SetContentsSeenRequestL( *aMessage ) );
+ break;
+
+ case NcdNodeFunctionIds::ENcdNodeSeenFolderNewCount:
+ TRAP( trapError, NewCountRequestL( *aMessage ) );
+ break;
+
+ case NcdNodeFunctionIds::ENcdNodeSeenFolderNewNodes:
+ TRAP( trapError, NewNodesRequestL( *aMessage ) );
+ break;
+
+ case NcdNodeFunctionIds::ENcdRelease:
+ ReleaseRequest( *aMessage );
+ break;
+
+ default:
+ DLERROR(("Unidentified function request"));
+ DASSERT( EFalse );
+ break;
+ }
+
+ if ( trapError != KErrNone )
+ {
+ // Because something went wrong the complete has not been
+ // yet called for the message.
+ // So, inform the client about the error.
+ aMessage->CompleteAndRelease( trapError );
+ }
+ }
+
+
+void CNcdNodeSeenFolder::CounterPartLost( const MCatalogsSession& /*aSession*/ )
+ {
+ DLTRACEIN((""));
+ }
+
+
+void CNcdNodeSeenFolder::SetContentsSeenRequestL(
+ MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+ SetContentsSeenL();
+ aMessage.CompleteAndRelease( KErrNone );
+ }
+
+
+void CNcdNodeSeenFolder::NewCountRequestL(
+ MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+
+ // Read the level number.
+ RCatalogsMessageReader reader;
+ reader.OpenLC( aMessage );
+
+ TInt level = reader().ReadInt32L();
+ DASSERT( level > 0 );
+
+ CleanupStack::PopAndDestroy( &reader );
+
+ TInt count = NewChildCountL( level - 1 );
+
+ aMessage.CompleteAndReleaseL( count, KErrNone );
+ }
+
+
+void CNcdNodeSeenFolder::NewNodesRequestL(
+ MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+
+ // Read the level number
+ RCatalogsMessageReader reader;
+ reader.OpenLC( aMessage );
+
+ TInt level = reader().ReadInt32L();
+ DASSERT( level > 0 );
+
+ CleanupStack::PopAndDestroy( &reader );
+
+ RPointerArray<CNcdNodeIdentifier> newNodes;
+ CleanupResetAndDestroyPushL( newNodes );
+
+ NewChildrenL( level - 1, newNodes );
+ TInt newCount = newNodes.Count();
+
+ DLINFO(("found %d new nodes", newCount ));
+
+ // Write the node identifier to output buffer.
+ RCatalogsBufferWriter writer;
+ writer.OpenLC();
+ writer().WriteInt32L( newCount );
+
+ for ( TInt i = 0; i < newCount; i++ )
+ {
+ newNodes[ i ]->ExternalizeL( writer() );
+ }
+
+ aMessage.CompleteAndReleaseL( writer.PtrL(), KErrNone );
+
+ CleanupStack::PopAndDestroy( &writer );
+ CleanupStack::PopAndDestroy( &newNodes );
+ }
+
+
+void CNcdNodeSeenFolder::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+
+ // Decrease the reference count for this object.
+ // When the reference count reaches zero, this object will be destroyed
+ // and removed from the session.
+ MCatalogsSession& requestSession( aMessage.Session() );
+ TInt handle( aMessage.Handle() );
+ aMessage.CompleteAndRelease( KErrNone );
+ requestSession.RemoveObject( handle );
+
+ DLTRACEOUT((""));
+ }
+
+
+TInt CNcdNodeSeenFolder::NewChildCountL(
+ TInt aRecursionLevel ) const
+ {
+ DLTRACEIN((""));
+ DASSERT( aRecursionLevel >= 0 );
+
+ CNcdNodeManager& nodeManager = iOwnerNode.NodeManager();
+
+ TInt newCount( 0 );
+
+ for ( TInt i = 0; i < iOwnerNode.ChildCount(); i++ )
+ {
+ const CNcdNodeIdentifier& childIdentifier =
+ iOwnerNode.ChildL( i );
+ CNcdNode* child = nodeManager.NodePtrL( childIdentifier );
+ if ( child )
+ {
+ // Increase the count if the node is not seen, but skip transparent nodes since
+ // they are not visible in proxy side anyway.
+ if ( !child->NodeSeen().IsSeenL() &&
+ child->ClassId() != NcdNodeClassIds::ENcdTransparentFolderNodeClassId )
+ {
+ newCount++;
+ }
+ else if ( child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId
+ && aRecursionLevel == 0 )
+ {
+ // Transparent child, add the children of the folder to child count.
+ CNcdNodeFolder* transparent = static_cast<CNcdNodeFolder*>( child );
+ newCount += transparent->NodeSeenFolder().NewChildCountL( aRecursionLevel );
+ }
+
+ if ( aRecursionLevel > 0 )
+ {
+ // If recursion level is greater than 0 and the
+ // the node is a folder, add the child count of
+ // the folder too.
+ if ( CNcdNodeFactory::NodeTypeL( *child ) == CNcdNodeFactory::ENcdNodeFolder )
+ {
+ CNcdNodeFolder* folder = static_cast<CNcdNodeFolder*>( child );
+
+ // If the folder is transparent folder, the recursion level must not
+ // be decreased.
+ TInt nextRecursionLevel( aRecursionLevel - 1 );
+ if ( folder->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId )
+ {
+ nextRecursionLevel++;
+ }
+
+ newCount += folder->NodeSeenFolder().NewChildCountL(
+ nextRecursionLevel );
+ }
+ }
+ }
+ }
+
+ return newCount;
+ }
+
+
+void CNcdNodeSeenFolder::NewChildrenL(
+ TInt aRecursionLevel, RPointerArray<CNcdNodeIdentifier>& aNodes ) const
+ {
+ DLTRACEIN(("level %d", aRecursionLevel));
+ DASSERT( aRecursionLevel >= 0 );
+
+ CNcdNodeManager& nodeManager = iOwnerNode.NodeManager();
+ TInt childCount = iOwnerNode.ChildCount();
+
+ for ( TInt i = 0; i < childCount; i++ )
+ {
+ const CNcdNodeIdentifier& childId = iOwnerNode.ChildL( i );
+ CNcdNode* child = nodeManager.NodePtrL( childId );
+ if ( !child )
+ {
+ continue;
+ }
+
+ // If the child is transparent folder, don't add it to the array.
+ if ( child->ClassId() != NcdNodeClassIds::ENcdTransparentFolderNodeClassId && !child->NodeSeen().IsSeenL() )
+ {
+ // Create copy of the identifier and add it to the array.
+ CNcdNodeIdentifier* copy = CNcdNodeIdentifier::NewLC( childId );
+ aNodes.AppendL( copy );
+ CleanupStack::Pop( copy );
+ }
+ else if ( child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId
+ && aRecursionLevel == 0 )
+ {
+ // Transparent child, and this is the last recursion level. The children of the
+ // transparent folder must be added to the array.
+ CNcdNodeFolder* transparent = static_cast<CNcdNodeFolder*>( child );
+ transparent->NodeSeenFolder().NewChildrenL( aRecursionLevel, aNodes );
+ }
+
+ if ( aRecursionLevel > 0 )
+ {
+ // If the node is a folder, go further in recursion.
+ CNcdNodeFactory::TNcdNodeType nodeType = CNcdNodeFactory::NodeTypeL( *child );
+ if ( nodeType == CNcdNodeFactory::ENcdNodeFolder ||
+ nodeType == CNcdNodeFactory::ENcdNodeRoot )
+ {
+ CNcdNodeFolder* folder = static_cast<CNcdNodeFolder*>( child );
+
+ // If the folder is transparent folder, the recursion level must not
+ // be decreased.
+ TInt nextRecursionLevel( aRecursionLevel - 1 );
+ if ( folder->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId )
+ {
+ nextRecursionLevel++;
+ }
+ folder->NodeSeenFolder().NewChildrenL( nextRecursionLevel, aNodes );
+ }
+ }
+ }
+ }
+
+
+void CNcdNodeSeenFolder::SetContentsSeenL() const
+ {
+ DLTRACEIN((""));
+
+ CNcdNodeManager& nodeManager = iOwnerNode.NodeManager();
+
+ // Set the children of the folder as seen.
+ for ( TInt i = 0; i < iOwnerNode.ChildCount(); i++ )
+ {
+ const CNcdNodeIdentifier& childIdentifier =
+ iOwnerNode.ChildL( i );
+ CNcdNode* child = nodeManager.NodePtrL( childIdentifier );
+ if ( child )
+ {
+ // If the child is transparent folder, set its contents as seen since in
+ // UI they are immediate children of this folder.
+ if ( child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId )
+ {
+ CNcdNodeFolder* transparent = static_cast<CNcdNodeFolder*>( child );
+ transparent->NodeSeenFolder().SetContentsSeenL();
+ }
+ else
+ {
+ child->NodeSeen().SetSeenL();
+ }
+ }
+ }
+ }