ncdengine/provider/server/src/ncdnodeseeninfo.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodeseeninfo.h"
       
    20 
       
    21 #include "ncdnodeidentifierutils.h"
       
    22 #include "ncdnodeidentifier.h"
       
    23 #include "ncdstorage.h"
       
    24 #include "ncdstoragemanager.h"
       
    25 #include "ncdproviderdefines.h"
       
    26 #include "ncddatabasestorage.h"
       
    27 #include "ncdstorageitem.h"
       
    28 #include "ncdrootnode.h"
       
    29 #include "ncdnodeidentifiereditor.h"
       
    30 #include "catalogsutils.h"
       
    31 #include "ncdchildentity.h"
       
    32 #include "ncdchildentitymap.h"
       
    33 #include "ncdnodefolderlink.h"
       
    34 #include "ncdgeneralmanager.h"
       
    35 
       
    36 #include "catalogsdebug.h"
       
    37 
       
    38 CNcdNodeSeenInfo* CNcdNodeSeenInfo::NewL( CNcdGeneralManager& aGeneralManager )
       
    39     {
       
    40     CNcdNodeSeenInfo* self = NewLC( aGeneralManager );
       
    41     CleanupStack::Pop( self );
       
    42     return self;
       
    43     }
       
    44     
       
    45 
       
    46 CNcdNodeSeenInfo* CNcdNodeSeenInfo::NewLC( CNcdGeneralManager& aGeneralManager )
       
    47     {
       
    48     CNcdNodeSeenInfo* self = new( ELeave ) CNcdNodeSeenInfo( aGeneralManager );
       
    49     CleanupStack::PushL( self );
       
    50     self->ConstructL();
       
    51     return self;
       
    52     }
       
    53 
       
    54 
       
    55 CNcdNodeSeenInfo::CNcdNodeSeenInfo( CNcdGeneralManager& aGeneralManager ) :
       
    56     iGeneralManager( aGeneralManager ),
       
    57     iStorageManager( aGeneralManager.StorageManager() ), 
       
    58     iNodeManager( aGeneralManager.NodeManager() )
       
    59     {	
       
    60     }    
       
    61 
       
    62 
       
    63 void CNcdNodeSeenInfo::ConstructL()
       
    64     {
       
    65     }    
       
    66 
       
    67 
       
    68 CNcdNodeSeenInfo::~CNcdNodeSeenInfo()
       
    69     {
       
    70     DLTRACEIN((""));
       
    71     iClientSeenInfos.ResetAndDestroy();
       
    72     }
       
    73     
       
    74 void CNcdNodeSeenInfo::AddNewIdL( const CNcdChildEntity& aChildEntity )
       
    75     {
       
    76     DLTRACEIN((""));
       
    77     AddNewIdL( aChildEntity.Identifier(), ENcdStatusNew, aChildEntity.NodeType() );
       
    78     }
       
    79 
       
    80 void CNcdNodeSeenInfo::AddNewIdL( const CNcdNodeIdentifier& aNodeIdentifier,
       
    81     TNcdNewStatus aNewStatus, CNcdNodeFactory::TNcdNodeType aNodeType )
       
    82     {
       
    83     DLTRACEIN((""));
       
    84         
       
    85     const TUid& clientUid = aNodeIdentifier.ClientUid();
       
    86             
       
    87     if ( !IsClientInfoLoaded( clientUid ) ) 
       
    88         {
       
    89         DbLoadClientInfoL( clientUid );
       
    90         }
       
    91     
       
    92     CClientSeenInfo* info = ClientInfo( clientUid );
       
    93     DASSERT( info );
       
    94 
       
    95 #ifdef CATALOGS_BUILD_CONFIG_DEBUG
       
    96     DLINFO(("New status array:"));
       
    97     for( TInt i = 0 ; i < info->iNodeNewStatusArray.Count() ; i++ )
       
    98         {
       
    99         DLINFO((_L("index: %d, id: %S"),i, &info->iNodeNewStatusArray[i]->Identifier().NodeId() ));
       
   100         }
       
   101 #endif
       
   102 
       
   103     // Latest "new" nodes will be added to the top of the list and older "new" nodes will
       
   104     // drop out when max size is exceeded.
       
   105     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   106     if( index == KErrNotFound )
       
   107         {
       
   108         DLTRACE(("Not found, create new."));
       
   109         // Create new status.
       
   110         CNcdNodeNewStatus* nodeNewStatus = CNcdNodeNewStatus::NewLC(
       
   111             aNodeIdentifier,
       
   112             aNewStatus,
       
   113             aNodeType );
       
   114         // Insert to the top of the list.
       
   115         info->iNodeNewStatusArray.InsertL( nodeNewStatus, 0 );
       
   116         CleanupStack::Pop( nodeNewStatus );
       
   117         
       
   118         }
       
   119     else
       
   120         {
       
   121         DLTRACE(("Found, update."));
       
   122         // Node is already in the new list -> move it to the top of the list.
       
   123         CNcdNodeNewStatus* nodeNewStatus = info->iNodeNewStatusArray[index];
       
   124         info->iNodeNewStatusArray.InsertL( nodeNewStatus, 0 );
       
   125         info->iNodeNewStatusArray.Remove( index + 1 );
       
   126         // Remove seen status if any
       
   127         RemoveFromSeenListL( aNodeIdentifier );
       
   128         // Update new status.
       
   129         nodeNewStatus->SetNewStatus( TNcdNewStatus(nodeNewStatus->NewStatus() | aNewStatus) );
       
   130         }
       
   131         
       
   132     // Set parent new as well.
       
   133     if( !NcdNodeIdentifierEditor::IdentifiesSomeRoot( aNodeIdentifier ) )
       
   134         {
       
   135         CNcdNodeIdentifier* parent = NcdNodeIdentifierEditor::ParentOfLC( aNodeIdentifier );
       
   136         AddNewIdL( *parent, ENcdStatusNewNodesInside, CNcdNodeFactory::ENcdNodeFolder );
       
   137         CleanupStack::PopAndDestroy( parent );
       
   138         }
       
   139     
       
   140     // Remove identifiers from the bottom if max size is exceeded.
       
   141     while( info->iNodeNewStatusArray.Count() > KNewListMaxSize )
       
   142         {
       
   143         delete info->iNodeNewStatusArray[info->iNodeNewStatusArray.Count() - 1];
       
   144         info->iNodeNewStatusArray.Remove(
       
   145             info->iNodeNewStatusArray.Count() - 1 );
       
   146         }
       
   147         
       
   148 #ifdef CATALOGS_BUILD_CONFIG_DEBUG
       
   149     DLINFO(("New status array:"));
       
   150     for( TInt i = 0 ; i < info->iNodeNewStatusArray.Count() ; i++ )
       
   151         {
       
   152         DLINFO((_L("index: %d, id: %S"),i, &info->iNodeNewStatusArray[i]->Identifier().NodeId() ));
       
   153         }
       
   154 #endif
       
   155     }
       
   156     
       
   157 
       
   158 TBool CNcdNodeSeenInfo::IsSeenL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   159     {
       
   160     DLTRACEIN((_L("ns: %S, id: %S"), &aNodeIdentifier.NodeNameSpace(), &aNodeIdentifier.NodeId()));
       
   161 
       
   162     const TUid& clientUid = aNodeIdentifier.ClientUid();
       
   163     
       
   164     if ( !IsClientInfoLoaded( clientUid ) )
       
   165         {
       
   166         DbLoadClientInfoL( clientUid );
       
   167         }
       
   168 
       
   169     CClientSeenInfo* clientInfo = ClientInfo( aNodeIdentifier.ClientUid() );
       
   170     DASSERT( clientInfo );
       
   171     DLINFO((("clientInfo-ptr: %x"), clientInfo ));    
       
   172     
       
   173     DLINFO(("new count: %d", clientInfo->iNodeNewStatusArray.Count() ));
       
   174     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   175     DLINFO(("index in new status array: %d", index ));
       
   176     return index == KErrNotFound;
       
   177     }
       
   178     
       
   179 
       
   180 TBool CNcdNodeSeenInfo::ChildExistsInArrayL( const CNcdChildEntity& aChildEntity,
       
   181         const RPointerArray<CNcdChildEntity>& aChildArray,
       
   182         TBool& aNodeWithSameIndexFound )
       
   183     {
       
   184     DLTRACEIN((""));
       
   185     TBool childFound = EFalse;
       
   186     aNodeWithSameIndexFound = EFalse;
       
   187     for( TInt i = 0 ; i < aChildArray.Count() ; i++ )
       
   188         {
       
   189         if( aChildArray[i]->Identifier().Equals( aChildEntity.Identifier() ) )
       
   190             {
       
   191             childFound = ETrue;
       
   192             }
       
   193         if( aChildArray[i]->Index() == aChildEntity.Index() )
       
   194             {
       
   195             aNodeWithSameIndexFound = ETrue;
       
   196             }
       
   197         }
       
   198     DLINFO(("childFound %d, aNodeWithSameIndexFound: %d", childFound,
       
   199         aNodeWithSameIndexFound));
       
   200     return childFound;
       
   201     }
       
   202 
       
   203 void CNcdNodeSeenInfo::RefreshFolderSeenStatusL( 
       
   204     const CNcdNodeIdentifier& aNodeIdentifier )
       
   205     {
       
   206     DLTRACEIN((_L("aNodeIdentifier: %S"), &aNodeIdentifier.NodeId() ));
       
   207     const TUid& clientUid = aNodeIdentifier.ClientUid();
       
   208             
       
   209     if ( !IsClientInfoLoaded( clientUid ) ) 
       
   210         {
       
   211         DbLoadClientInfoL( clientUid );
       
   212         }
       
   213     
       
   214     CClientSeenInfo* info = ClientInfo( clientUid );
       
   215     DASSERT( info );
       
   216     
       
   217     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   218     if( index == KErrNotFound )
       
   219         {
       
   220         DLTRACE(("Not in new status array"));
       
   221         return;
       
   222         }
       
   223     
       
   224     if( !FolderHasNewChildrenL( aNodeIdentifier ) )
       
   225         {
       
   226         CNcdNodeNewStatus* newStatus = info->iNodeNewStatusArray[index];
       
   227         // Don't touch folders that are really new, only folders that have just
       
   228         // new items inside.
       
   229         if( !( newStatus->NewStatus() & ENcdStatusNew ||
       
   230                newStatus->NewStatus() & ENcdStatusNewButSeen ) )
       
   231             {
       
   232             // Special case: all new children have been removed, immediately remove folder's new status
       
   233             // (better user experience when compared to just setting it seen)
       
   234             RemoveFromNewListL( aNodeIdentifier );
       
   235             RemoveFromSeenListL( aNodeIdentifier );
       
   236             // Check parent as well.
       
   237             if( !NcdNodeIdentifierEditor::IdentifiesSomeRoot( aNodeIdentifier ) )
       
   238                 {
       
   239                 CNcdNodeIdentifier* parent = NcdNodeIdentifierEditor::ParentOfLC( aNodeIdentifier );
       
   240                 RefreshFolderSeenStatusL( *parent );
       
   241                 CleanupStack::PopAndDestroy( parent );
       
   242                 }
       
   243             }
       
   244         }
       
   245     }
       
   246     
       
   247 void CNcdNodeSeenInfo::SetFolderSeenIfNeededL( 
       
   248     const CNcdNodeIdentifier& aNodeIdentifier )
       
   249     {
       
   250     DLTRACEIN((""));
       
   251     
       
   252     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   253     if( index == KErrNotFound || IsAddedAsSeen( aNodeIdentifier ) )
       
   254         {
       
   255         DLTRACE(("Not in new status array, or already set seen"));
       
   256         return;
       
   257         }
       
   258     
       
   259     if( !FolderHasNewUnseenChildrenL( aNodeIdentifier ) )
       
   260         {
       
   261         // Add to seen list.
       
   262         AddSeenIdL( aNodeIdentifier );
       
   263         // Check parent as well.
       
   264         if( !NcdNodeIdentifierEditor::IdentifiesSomeRoot( aNodeIdentifier ) )
       
   265             {
       
   266             CNcdNodeIdentifier* parent = NcdNodeIdentifierEditor::ParentOfLC( aNodeIdentifier );
       
   267             SetFolderSeenIfNeededL( *parent );
       
   268             CleanupStack::PopAndDestroy( parent );
       
   269             }
       
   270         }
       
   271     }
       
   272     
       
   273 TBool CNcdNodeSeenInfo::FolderHasNewUnseenChildrenL(
       
   274     const CNcdNodeIdentifier& aNodeIdentifier )
       
   275     {
       
   276     DLTRACEIN((""));    
       
   277     CNcdNodeFolder& folder = iNodeManager.FolderL( aNodeIdentifier );
       
   278     const RPointerArray<CNcdChildEntity>& childArray = folder.ChildArray();
       
   279     for( TInt i = 0 ; i < childArray.Count() ; i++ )
       
   280         {
       
   281         // NOTE: Children that are set seen are not considered new here.
       
   282         CNcdNodeNewStatus* nodeNewStatus = NodeNewStatus( childArray[i]->Identifier() );
       
   283         if( nodeNewStatus && !IsAddedAsSeen( childArray[i]->Identifier() ) )
       
   284             {
       
   285             DLTRACE(("New child found"));
       
   286             return ETrue;
       
   287             }
       
   288         }
       
   289     return EFalse;
       
   290     }
       
   291     
       
   292  TBool CNcdNodeSeenInfo::FolderHasNewChildrenL(
       
   293     const CNcdNodeIdentifier& aNodeIdentifier )
       
   294     {
       
   295     DLTRACEIN((""));    
       
   296     CNcdNodeFolder& folder = iNodeManager.FolderL( aNodeIdentifier );
       
   297     const RPointerArray<CNcdChildEntity>& childArray = folder.ChildArray();
       
   298     for( TInt i = 0 ; i < childArray.Count() ; i++ )
       
   299         {
       
   300         // NOTE: Children that are set seen are considered new here.
       
   301         CNcdNodeNewStatus* nodeNewStatus = NodeNewStatus( childArray[i]->Identifier() );
       
   302         if( nodeNewStatus )
       
   303             {
       
   304             DLTRACE(("New child found"));
       
   305             return ETrue;
       
   306             }
       
   307         }
       
   308     return EFalse;
       
   309     }
       
   310 
       
   311 void CNcdNodeSeenInfo::AddSeenIdL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   312     {
       
   313     DLTRACEIN((""));
       
   314     CClientSeenInfo* info = ClientInfo( aNodeIdentifier.ClientUid() );
       
   315     DASSERT( info );
       
   316     // Add to seen list.
       
   317     CNcdNodeIdentifier* copy = CNcdNodeIdentifier::NewLC( aNodeIdentifier );
       
   318     info->iSeenStructureIds.AppendL( copy );
       
   319     CleanupStack::Pop( copy );
       
   320     }
       
   321 
       
   322 void CNcdNodeSeenInfo::SetSeenL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   323     {
       
   324     DLTRACEIN((""));
       
   325         
       
   326     const TUid& clientUid = aNodeIdentifier.ClientUid();
       
   327             
       
   328     if ( !IsClientInfoLoaded( clientUid ) ) 
       
   329         {
       
   330         DbLoadClientInfoL( clientUid );
       
   331         }
       
   332     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   333     
       
   334     if( index == KErrNotFound || IsAddedAsSeen( aNodeIdentifier ) )
       
   335         {
       
   336         DLTRACE(("Not in new status array, or already set seen"));
       
   337         return;
       
   338         }
       
   339     
       
   340     CClientSeenInfo* info = ClientInfo( clientUid );
       
   341     DASSERT( info );
       
   342     
       
   343     CNcdNodeNewStatus* nodeNewStatus = info->iNodeNewStatusArray[index];
       
   344     if( nodeNewStatus->NodeType() == CNcdNodeFactory::ENcdNodeItem )
       
   345         {
       
   346         AddSeenIdL( aNodeIdentifier );
       
   347         }
       
   348     else if ( nodeNewStatus->NewStatus() & ENcdStatusNew &&
       
   349         nodeNewStatus->NewStatus() & ENcdStatusNewNodesInside )
       
   350         {
       
   351         nodeNewStatus->SetNewStatus(
       
   352             TNcdNewStatus( ENcdStatusNewButSeen | ENcdStatusNewNodesInside ) );
       
   353         }
       
   354     else if ( nodeNewStatus->NewStatus() & ENcdStatusNew )
       
   355         {
       
   356         AddSeenIdL( aNodeIdentifier );
       
   357         }
       
   358         
       
   359     if( !NcdNodeIdentifierEditor::IdentifiesSomeRoot( aNodeIdentifier ) )
       
   360         {
       
   361         CNcdNodeIdentifier* parent = NcdNodeIdentifierEditor::ParentOfLC( aNodeIdentifier );
       
   362         SetFolderSeenIfNeededL( *parent );
       
   363         CleanupStack::PopAndDestroy( parent );
       
   364         }
       
   365     }
       
   366     
       
   367 void CNcdNodeSeenInfo::CheckFolderNewStatusL( CNcdNodeFolder& aParentFolder )
       
   368     {
       
   369     DLTRACEIN((""));
       
   370     // New checking for children can only be done if the previous
       
   371     // child array has been stored. (Not stored e.g. on first time browse and
       
   372     // after restart)
       
   373     if( aParentFolder.PreviousChildCount() != KErrNotFound )
       
   374         {
       
   375         DLTRACE(("Previous children set -> do new comparison"));
       
   376         const RPointerArray<CNcdChildEntity>& previousChildArray =
       
   377             aParentFolder.PreviousChildArray();
       
   378         CheckFolderNewStatusL( aParentFolder, previousChildArray );
       
   379         }
       
   380     }
       
   381         
       
   382 void CNcdNodeSeenInfo::CheckFolderNewStatusL( CNcdNodeFolder& aParentFolder,
       
   383     const RPointerArray<CNcdChildEntity>& aPreviousChildArray )
       
   384     {
       
   385     const TUid& clientUid = aParentFolder.Identifier().ClientUid();
       
   386             
       
   387     if ( !IsClientInfoLoaded( clientUid ) ) 
       
   388         {
       
   389         DbLoadClientInfoL( clientUid );
       
   390         }
       
   391         
       
   392     CClientSeenInfo* info = ClientInfo( clientUid );
       
   393     DASSERT( info );
       
   394     
       
   395     // This flag is used to determine whether this folder contains any new items.
       
   396     TBool newChildrenFound = EFalse;
       
   397     // Check new array against the previous array
       
   398     const RPointerArray<CNcdChildEntity>& childArray =
       
   399         aParentFolder.ChildArray();
       
   400     CNcdNodeNewStatus* parentNewStatus = NodeNewStatus( aParentFolder.Identifier() );
       
   401     TBool parentIsNew = parentNewStatus &&
       
   402             ( parentNewStatus->NewStatus() & ENcdStatusNew ||
       
   403               parentNewStatus->NewStatus() & ENcdStatusNewButSeen );
       
   404     for( TInt i = 0 ; i < childArray.Count() ; i++ )
       
   405         {
       
   406         // compare with previous list
       
   407         TBool nodeWithSameIndexFound = EFalse;
       
   408         TBool childFound = ChildExistsInArrayL( *childArray[i],
       
   409             aPreviousChildArray,
       
   410             nodeWithSameIndexFound );
       
   411         
       
   412         if( parentIsNew )
       
   413             {
       
   414             DLTRACE(("Parent folder is new -> all children are new "));
       
   415             AddNewIdL( *childArray[i] );
       
   416             newChildrenFound = ETrue;
       
   417             }
       
   418         // if found -> old
       
   419         else if( childFound )
       
   420             {
       
   421             DLTRACE(("Child found -> old"));
       
   422             }
       
   423         // if not found && index < old child count && no node with this index in previous list
       
   424         //      -> old ( cannot know whether this is new or old so default to old, special case! )
       
   425         else if( !childFound
       
   426             && childArray[i]->Index() < aParentFolder.PreviousChildCount()
       
   427             && !nodeWithSameIndexFound )
       
   428             {
       
   429             DLTRACE(("Child not found and index < previous child count && node with same index not found -> default to old"));
       
   430             }
       
   431         // if not found && index < old child count && node exists with this index in previous list
       
   432         //      -> new ( the "usual" new case )
       
   433         else if( !childFound
       
   434              && childArray[i]->Index() < aParentFolder.PreviousChildCount()
       
   435              && nodeWithSameIndexFound )
       
   436             {
       
   437             DLTRACE(("New"));
       
   438             AddNewIdL( *childArray[i] );
       
   439             newChildrenFound = ETrue;
       
   440             }
       
   441         // if not found && index > old child count -> new 
       
   442         else if( !childFound
       
   443             && childArray[i]->Index() >= aParentFolder.PreviousChildCount() )
       
   444             {
       
   445             DLTRACE(("New"));
       
   446             AddNewIdL( *childArray[i] );
       
   447             newChildrenFound = ETrue;
       
   448             }
       
   449             
       
   450         // If no new children are found before, check that is this node previously new
       
   451         if( !newChildrenFound )
       
   452             {
       
   453             DLTRACE(("Check if already set new"));
       
   454             // Must be in new array and not in seen array to be new
       
   455             // (internally new, i.e. new even after commit).
       
   456             CNcdNodeNewStatus* nodeNewStatus = NodeNewStatus(
       
   457                 childArray[i]->Identifier() );
       
   458             if( nodeNewStatus )
       
   459                 {
       
   460                 newChildrenFound = ETrue;
       
   461                 }
       
   462             }
       
   463         }
       
   464         
       
   465     if( !newChildrenFound && parentIsNew )
       
   466         {
       
   467         // Special case: all new items have been removed, immediately remove parent's new status
       
   468         // (better user experience when compared to just setting it seen)
       
   469         RemoveFromNewListL( aParentFolder.Identifier() );
       
   470         }
       
   471     }   
       
   472 
       
   473 void CNcdNodeSeenInfo::CheckChildNewStatusL( CNcdNodeFolder& aParentFolder,
       
   474     TInt aChildIndex )
       
   475     {
       
   476     DLTRACEIN((""));
       
   477     const TUid& clientUid = aParentFolder.Identifier().ClientUid();
       
   478             
       
   479     if ( !IsClientInfoLoaded( clientUid ) ) 
       
   480         {
       
   481         DbLoadClientInfoL( clientUid );
       
   482         }
       
   483     
       
   484     CNcdNodeNewStatus* parentNewStatus = NodeNewStatus( aParentFolder.Identifier() );
       
   485     TBool parentIsNew = parentNewStatus &&
       
   486             ( parentNewStatus->NewStatus() & ENcdStatusNew ||
       
   487               parentNewStatus->NewStatus() & ENcdStatusNewButSeen );
       
   488     if( parentIsNew )
       
   489         {
       
   490         DLTRACE(("Parent is new, set child new as well"));
       
   491         AddNewIdL( aParentFolder.ChildEntityByServerIndexL( aChildIndex ) );
       
   492         }
       
   493     else if( aParentFolder.PreviousChildCount() != KErrNotFound )
       
   494         {
       
   495         DLTRACE(("Previous child list set, do comparison."));
       
   496         const CNcdChildEntity& child = aParentFolder.ChildEntityByServerIndexL( aChildIndex );
       
   497         // compare with previous list
       
   498         TBool nodeWithSameIndexFound = EFalse;
       
   499         TBool childFound = ChildExistsInArrayL( child,
       
   500             aParentFolder.PreviousChildArray(),
       
   501             nodeWithSameIndexFound );
       
   502 
       
   503         // if found -> old
       
   504         if( childFound )
       
   505             {
       
   506             DLTRACE(("Child found -> old"));
       
   507             }
       
   508         // if not found && index < old child count && no node with this index in previous list
       
   509         //      -> old ( cannot know whether this is new or old so default to old, special case! )
       
   510         else if( !childFound
       
   511             && child.Index() < aParentFolder.PreviousChildCount()
       
   512             && !nodeWithSameIndexFound )
       
   513             {
       
   514             DLTRACE(("Child not found and index < previous child count && node with same index not found -> default to old"));
       
   515             }
       
   516         // if not found && index < old child count && node exists with this index in previous list
       
   517         //      -> new ( the "usual" new case )
       
   518         else if( !childFound
       
   519              && child.Index() < aParentFolder.PreviousChildCount()
       
   520              && nodeWithSameIndexFound )
       
   521             {
       
   522             DLTRACE(("New"));
       
   523             AddNewIdL( child );
       
   524             }
       
   525         // if not found && index > old child count -> new 
       
   526         else if( !childFound
       
   527             && child.Index() >= aParentFolder.PreviousChildCount() )
       
   528             {
       
   529             DLTRACE(("New"));
       
   530             AddNewIdL( child );
       
   531             }
       
   532         }
       
   533     }
       
   534     
       
   535 void CNcdNodeSeenInfo::ClearInfoL( const TUid& aClientUid )
       
   536     {
       
   537     DLTRACEIN((""));
       
   538     if ( !IsClientInfoLoaded( aClientUid ) ) 
       
   539         {
       
   540         DbLoadClientInfoL( aClientUid );
       
   541         }
       
   542     CClientSeenInfo* info = ClientInfo( aClientUid );
       
   543     DASSERT( info );
       
   544     info->iNodeNewStatusArray.ResetAndDestroy();
       
   545     info->iSeenStructureIds.ResetAndDestroy();
       
   546     }
       
   547 
       
   548 void CNcdNodeSeenInfo::CommitChangesL( const TUid& aClientUid ) 
       
   549     {
       
   550     DLTRACEIN((""));
       
   551     
       
   552     CClientSeenInfo* info = ClientInfo( aClientUid );
       
   553     if ( !info )
       
   554         {
       
   555         // No changes made, return;
       
   556         return;
       
   557         }
       
   558     
       
   559     for( TInt i = info->iNodeNewStatusArray.Count() - 1 ; i >= 0 ; i-- )
       
   560         {
       
   561         CNcdNodeNewStatus* nodeNewStatus = info->iNodeNewStatusArray[i];
       
   562         if( nodeNewStatus->NewStatus() & ENcdStatusNewButSeen )
       
   563             {
       
   564             nodeNewStatus->SetNewStatus( 
       
   565                 TNcdNewStatus(nodeNewStatus->NewStatus() ^ ENcdStatusNewButSeen ) );
       
   566             }
       
   567         }
       
   568     
       
   569     TInt count = info->iSeenStructureIds.Count();
       
   570     // Remove the seen identifiers from the new list.
       
   571     while ( count-- ) 
       
   572         {
       
   573         RemoveFromNewListL( *info->iSeenStructureIds[ count ] );
       
   574         delete info->iSeenStructureIds[ count];
       
   575         // Removing here in case RemoveFromNewListL leaves
       
   576         info->iSeenStructureIds.Remove( count );
       
   577         }
       
   578         
       
   579     DASSERT( info->iSeenStructureIds.Count() == 0 );
       
   580     // Save the changes to db.
       
   581     DbSaveClientInfoL( aClientUid );
       
   582     }
       
   583 
       
   584  void CNcdNodeSeenInfo::CreatePreviousListsForChildrenL(
       
   585     CNcdNodeFolder& aParentFolder,
       
   586     RPointerArray<CNcdChildEntityMap>& aChildEntityMaps )
       
   587     {
       
   588     DLTRACEIN((""));
       
   589     for( TInt i = 0 ; i < aParentFolder.ChildArray().Count() ; i++ )
       
   590         {
       
   591         if( aParentFolder.ChildArray()[i]->NodeType() ==
       
   592             CNcdNodeFactory::ENcdNodeFolder )
       
   593             {
       
   594             CNcdNodeFolder* child = NULL;
       
   595             TRAPD(err, child = &iNodeManager.FolderL(
       
   596                 aParentFolder.ChildArray()[i]->Identifier() ) ); //TRAPD
       
   597             // Special handling for bundles
       
   598             if( err != KErrNone )
       
   599                 {
       
   600                 DLTRACE(("Child not found from cache or db."));
       
   601                 continue;
       
   602                 }
       
   603             TInt childCount = 0;
       
   604             if( CNcdNodeFactory::NodePurposeL( *child ) ==
       
   605                 CNcdNodeFactory::ENcdBundleNode && 
       
   606                 child->ChildrenPreviouslyLoaded() )
       
   607                 {
       
   608                 DLTRACE((""))
       
   609                 CreatePreviousListsForChildrenL( *child, aChildEntityMaps );
       
   610                 childCount = child->ChildCount();
       
   611                 }
       
   612             else
       
   613                 {
       
   614                 childCount = child->FolderLinkL().ExpectedChildrenCount();
       
   615                 }
       
   616             // Store only if previously loaded.
       
   617             if( child->ChildrenPreviouslyLoaded() )
       
   618                 {
       
   619                 DLTRACEIN((_L("Creating previous list for: %S"),
       
   620                     &child->Identifier().NodeId() ));
       
   621                 CNcdChildEntityMap* childEntityMap =
       
   622                     CNcdChildEntityMap::NewLC(
       
   623                         child->Identifier(),
       
   624                         child->ChildArray(),
       
   625                         childCount );
       
   626                 aChildEntityMaps.AppendL( childEntityMap );
       
   627                 CleanupStack::Pop( childEntityMap );
       
   628                 }
       
   629             }
       
   630         }
       
   631     }
       
   632 
       
   633 void CNcdNodeSeenInfo::StorePreviousListsToExistingChildrenL(
       
   634     CNcdNodeFolder& aParentFolder,
       
   635     const RPointerArray<CNcdChildEntityMap>& aChildEntityMaps )
       
   636     {
       
   637     DLTRACEIN((""));
       
   638     const RPointerArray<CNcdChildEntity>& children = aParentFolder.ChildArray();
       
   639     for( TInt i = 0 ; i < children.Count() ; i++ )
       
   640         {
       
   641         CNcdNodeFolder* folder = NULL;
       
   642         TRAPD(err, folder =
       
   643             &iNodeManager.FolderL( children[i]->Identifier() ) ); //TRAPD
       
   644         if( err != KErrNone )
       
   645             {
       
   646             DLTRACE(("Child not found from cache or db."));
       
   647             continue;
       
   648             }
       
   649         if( CNcdNodeFactory::NodePurposeL( 
       
   650             *folder ) == CNcdNodeFactory::ENcdBundleNode )
       
   651             {
       
   652             DLTRACE(("Child is bundle -> store it's children's previous lists."));
       
   653             StorePreviousListsToExistingChildrenL( *folder, aChildEntityMaps );
       
   654             }
       
   655             
       
   656         for( TInt j = 0 ; j < aChildEntityMaps.Count() ; j++ )
       
   657             {
       
   658             // Should remove child entity map when matching child is found.
       
   659             const CNcdChildEntityMap* previousChildEntityMap = aChildEntityMaps[j];
       
   660             if( previousChildEntityMap->ParentIdentifier().Equals( 
       
   661                 folder->Identifier() ) )
       
   662                 {
       
   663                 DLTRACE(("Matching child found, store it's previous list."));
       
   664                 folder->StoreChildrenToPreviousListL( 
       
   665                     previousChildEntityMap->ChildArray(),
       
   666                     previousChildEntityMap->ChildCount() );
       
   667                 break;
       
   668                 }
       
   669             }
       
   670         }
       
   671     }
       
   672 
       
   673 void CNcdNodeSeenInfo::DoNewCheckForTransparentChildrenL(
       
   674     CNcdNodeFolder& aParentFolder )
       
   675     {
       
   676     DLTRACEIN((""));
       
   677     const RPointerArray<CNcdChildEntity>& children = aParentFolder.ChildArray();
       
   678     for( TInt i = 0 ; i < children.Count() ; i++ )
       
   679         {
       
   680         if( children[i]->NodeType() == CNcdNodeFactory::ENcdNodeFolder
       
   681             && children[i]->IsTransparent() )
       
   682             {
       
   683             CNcdNodeFolder* folder = NULL;
       
   684             TRAPD(err, folder =
       
   685                 &iNodeManager.FolderL( children[i]->Identifier() ) ); //TRAPD
       
   686             if( err == KErrNone )
       
   687                 {
       
   688                 CNcdNodeNewStatus* parentNewStatus = NodeNewStatus( children[i]->Identifier() );
       
   689                 TBool parentIsNew = parentNewStatus &&
       
   690                     ( parentNewStatus->NewStatus() & ENcdStatusNew ||
       
   691                       parentNewStatus->NewStatus() & ENcdStatusNewButSeen );
       
   692                 if( parentIsNew )
       
   693                     {
       
   694                     SetChildrenNewL( *folder );
       
   695                     }
       
   696                 else
       
   697                     {
       
   698                     CheckFolderNewStatusL( *folder );
       
   699                     }
       
   700                 }
       
   701             }
       
   702         }
       
   703     }
       
   704 
       
   705 CNcdNodeSeenInfo::CClientSeenInfo* CNcdNodeSeenInfo::ClientInfo(
       
   706     const TUid& aClientUid ) const 
       
   707     {
       
   708     for ( TInt i = 0; i < iClientSeenInfos.Count(); i++ ) 
       
   709         {
       
   710         if ( iClientSeenInfos[ i ]->iClientUid == aClientUid ) 
       
   711             {
       
   712             return iClientSeenInfos[ i ];
       
   713             }
       
   714         }
       
   715     return NULL;
       
   716     }
       
   717     
       
   718 
       
   719 TInt CNcdNodeSeenInfo::IndexInSeenArray( const CNcdNodeIdentifier& aNodeIdentifier ) const
       
   720     {
       
   721     DLTRACEIN((""));
       
   722     CClientSeenInfo* info = ClientInfo( aNodeIdentifier.ClientUid() );
       
   723     DASSERT( info );
       
   724     return NcdNodeIdentifierUtils::IdentifierIndex(
       
   725         aNodeIdentifier, info->iSeenStructureIds );
       
   726     }
       
   727     
       
   728 TBool CNcdNodeSeenInfo::IsAddedAsSeen( const CNcdNodeIdentifier& aNodeIdentifier ) const
       
   729     {
       
   730     DLTRACEIN((""));
       
   731     return IndexInSeenArray( aNodeIdentifier ) != KErrNotFound;
       
   732     }
       
   733     
       
   734 TInt CNcdNodeSeenInfo::IndexInNewStatusArray( const CNcdNodeIdentifier& aNodeIdentifier ) const
       
   735     {
       
   736     DLTRACEIN((""));
       
   737     CClientSeenInfo* info = ClientInfo( aNodeIdentifier.ClientUid() );
       
   738     DASSERT( info );
       
   739     TInt index = KErrNotFound;
       
   740     for( TInt i = 0 ; i < info->iNodeNewStatusArray.Count() ; i++ )
       
   741         {
       
   742         if( info->iNodeNewStatusArray[i]->Identifier().Equals( aNodeIdentifier ) )
       
   743             {
       
   744             index = i;
       
   745             break;
       
   746             }
       
   747         }
       
   748     return index;
       
   749     }
       
   750     
       
   751 CNcdNodeSeenInfo::CNcdNodeNewStatus* CNcdNodeSeenInfo::NodeNewStatus( const CNcdNodeIdentifier& aNodeIdentifier )
       
   752     {
       
   753     DLTRACEIN((""));
       
   754     CNcdNodeNewStatus* nodeNewStatus = NULL;
       
   755     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   756     if( index != KErrNotFound )
       
   757         {
       
   758         CClientSeenInfo* info = ClientInfo( aNodeIdentifier.ClientUid() );
       
   759         DASSERT( info );
       
   760         nodeNewStatus = info->iNodeNewStatusArray[index];
       
   761         }
       
   762     return nodeNewStatus;
       
   763     }
       
   764     
       
   765 void CNcdNodeSeenInfo::RemoveFromSeenListL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   766     {
       
   767     DLTRACEIN((""));
       
   768     const TUid& clientUid = aNodeIdentifier.ClientUid();
       
   769             
       
   770     if ( !IsClientInfoLoaded( clientUid ) ) 
       
   771         {
       
   772         DbLoadClientInfoL( clientUid );
       
   773         }
       
   774         
       
   775     CClientSeenInfo* info = ClientInfo( clientUid );
       
   776     DASSERT( info );
       
   777     
       
   778     TInt index = NcdNodeIdentifierUtils::IdentifierIndex(
       
   779         aNodeIdentifier, info->iSeenStructureIds );
       
   780     if( index != KErrNotFound )
       
   781         {
       
   782         delete info->iSeenStructureIds[index];
       
   783         info->iSeenStructureIds.Remove( index );
       
   784         }
       
   785     }
       
   786 
       
   787 void CNcdNodeSeenInfo::RemoveFromNewListL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   788     {
       
   789     DLTRACEIN((""));
       
   790     const TUid& clientUid = aNodeIdentifier.ClientUid();
       
   791             
       
   792     if ( !IsClientInfoLoaded( clientUid ) ) 
       
   793         {
       
   794         DbLoadClientInfoL( clientUid );
       
   795         }
       
   796         
       
   797     CClientSeenInfo* info = ClientInfo( clientUid );
       
   798     DASSERT( info );
       
   799     
       
   800     TInt index = IndexInNewStatusArray( aNodeIdentifier );
       
   801     if( index != KErrNotFound )
       
   802         {
       
   803         DLTRACE((_L("Removing from new status array, id: %S"), &aNodeIdentifier.NodeId() ));
       
   804         delete info->iNodeNewStatusArray[index];
       
   805         info->iNodeNewStatusArray.Remove( index );
       
   806         }
       
   807     }
       
   808 
       
   809 TBool CNcdNodeSeenInfo::IsClientInfoLoaded( const TUid& aClientUid ) const
       
   810     {
       
   811     DLTRACEIN((""));
       
   812     return ClientInfo( aClientUid ) != NULL;
       
   813     }
       
   814     
       
   815 
       
   816 void CNcdNodeSeenInfo::RemoveClientInfo( const TUid& aClientUid )
       
   817     {
       
   818     DLTRACEIN((""));
       
   819     for ( TInt i = 0; i < iClientSeenInfos.Count(); i++ ) 
       
   820         {
       
   821         if ( iClientSeenInfos[ i ]->iClientUid == aClientUid ) 
       
   822             {
       
   823             delete iClientSeenInfos[ i ];
       
   824             iClientSeenInfos.Remove( i );
       
   825             break;
       
   826             }
       
   827         }
       
   828     }       
       
   829     
       
   830 
       
   831 void CNcdNodeSeenInfo::DbLoadClientInfoL( const TUid& aClientUid )
       
   832     {
       
   833     DLTRACEIN((""));
       
   834     
       
   835     RemoveClientInfo( aClientUid );
       
   836     
       
   837     MNcdStorage& providerStorage = iStorageManager.ProviderStorageL(
       
   838         iGeneralManager.FamilyName() );
       
   839     MNcdDatabaseStorage& database =
       
   840         providerStorage.DatabaseStorageL( NcdProviderDefines::KDefaultDatabaseUid );
       
   841         
       
   842     if( !database.ItemExistsInStorageL( aClientUid.Name(), 
       
   843         NcdProviderDefines::ENcdNodeSeenInfo ) ) 
       
   844         {
       
   845         // Create empty client info object.
       
   846         CClientSeenInfo* empty = new( ELeave ) CClientSeenInfo( aClientUid );
       
   847         CleanupStack::PushL( empty );
       
   848         iClientSeenInfos.AppendL( empty );
       
   849         CleanupStack::Pop( empty );
       
   850         }
       
   851     else 
       
   852         {
       
   853         // Database contains the data, load it.
       
   854         // Get the storage item from which the data is loaded
       
   855         // Note: database has the ownership of the item
       
   856         MNcdStorageItem* item = database.StorageItemL(
       
   857             aClientUid.Name(), NcdProviderDefines::ENcdNodeSeenInfo );    
       
   858         
       
   859         // Get data from database by using CClientSeenInfo as the target so that 
       
   860         // internalize will be called for it
       
   861         CClientSeenInfo* data = new( ELeave ) CClientSeenInfo( aClientUid );
       
   862         CleanupStack::PushL( data );
       
   863         item->SetDataItem( data );
       
   864     
       
   865         // Read data -> calls CClientSeenInfo::InternalizeL
       
   866         item->ReadDataL();
       
   867         
       
   868         iClientSeenInfos.AppendL( data );
       
   869         CleanupStack::Pop( data );
       
   870         }
       
   871     }
       
   872     
       
   873     
       
   874 void CNcdNodeSeenInfo::DbSaveClientInfoL( const TUid& aClientUid )
       
   875     {
       
   876     DLTRACEIN((""));
       
   877     
       
   878     CClientSeenInfo* info = ClientInfo( aClientUid );
       
   879     if ( !info ) 
       
   880         {
       
   881         return;
       
   882         }
       
   883         
       
   884     MNcdStorage& providerStorage = iStorageManager.ProviderStorageL(
       
   885         iGeneralManager.FamilyName() );
       
   886     MNcdDatabaseStorage& database =
       
   887         providerStorage.DatabaseStorageL( NcdProviderDefines::KDefaultDatabaseUid );
       
   888         
       
   889     // Get the storage item to which the client seen info is stored
       
   890     // Note: database has the ownership of the item
       
   891     MNcdStorageItem* item = database.StorageItemL(
       
   892         aClientUid.Name(), NcdProviderDefines::ENcdNodeSeenInfo );
       
   893     item->SetDataItem( info );
       
   894     item->OpenL();
       
   895         
       
   896     // Calls ExternalizeL for this
       
   897     item->WriteDataL();
       
   898     item->SaveL();
       
   899     }
       
   900     
       
   901 void CNcdNodeSeenInfo::SetChildrenNewL( CNcdNodeFolder& aParentFolder )
       
   902     {
       
   903     DLTRACEIN((""));
       
   904     const RPointerArray<CNcdChildEntity>& children = aParentFolder.ChildArray();
       
   905     for( TInt i = 0 ; i < children.Count() ; i++ )
       
   906         {
       
   907         AddNewIdL( *children[i] );
       
   908         RemoveFromSeenListL( children[i]->Identifier() );
       
   909         }
       
   910     }
       
   911         
       
   912     
       
   913 // ----------------------------------------------------------------------------------------------
       
   914 // CNcdNodeSeenInfo::CClientInfo
       
   915 // ----------------------------------------------------------------------------------------------
       
   916 //
       
   917 
       
   918 CNcdNodeSeenInfo::CClientSeenInfo::CClientSeenInfo( const TUid& aClientUid ) :
       
   919     iClientUid( aClientUid ) 
       
   920     {
       
   921     }
       
   922     
       
   923 CNcdNodeSeenInfo::CClientSeenInfo::~CClientSeenInfo()
       
   924     {
       
   925     iNodeNewStatusArray.ResetAndDestroy();
       
   926     iSeenStructureIds.ResetAndDestroy();
       
   927     }
       
   928     
       
   929 
       
   930 // From MNcdStorageDataItem
       
   931 
       
   932 void CNcdNodeSeenInfo::CClientSeenInfo::ExternalizeL( RWriteStream& aStream ) 
       
   933     {
       
   934     DLTRACEIN((""));
       
   935     
       
   936     // Write uid.
       
   937     aStream.WriteInt32L( iClientUid.iUid );
       
   938 
       
   939     // Write new structure ids.
       
   940     TInt count = iNodeNewStatusArray.Count();
       
   941     aStream.WriteInt32L( count );
       
   942     for ( TInt i = 0; i < count; i++ ) 
       
   943         {
       
   944         iNodeNewStatusArray[ i ]->ExternalizeL( aStream );
       
   945         }
       
   946     }
       
   947 
       
   948 
       
   949 void CNcdNodeSeenInfo::CClientSeenInfo::InternalizeL( RReadStream& aStream ) 
       
   950     {
       
   951     DLTRACEIN((""));
       
   952     iNodeNewStatusArray.ResetAndDestroy();
       
   953     
       
   954     // Read uid.
       
   955     iClientUid = TUid::Uid( aStream.ReadInt32L() );
       
   956     
       
   957     // Read new structure ids.
       
   958     TInt count = aStream.ReadInt32L();
       
   959     for ( TInt i = 0; i < count; i++ ) 
       
   960         {
       
   961         CNcdNodeNewStatus* identifier = CNcdNodeNewStatus::NewLC( aStream );
       
   962         iNodeNewStatusArray.AppendL( identifier );
       
   963         CleanupStack::Pop( identifier );
       
   964         }
       
   965     }
       
   966 
       
   967 CNcdNodeSeenInfo::CNcdNodeNewStatus* CNcdNodeSeenInfo::CNcdNodeNewStatus::NewL(
       
   968     const CNcdNodeIdentifier& aNodeIdentifier,
       
   969     TNcdNewStatus aNewStatus,
       
   970     CNcdNodeFactory::TNcdNodeType aNodeType )
       
   971     {
       
   972     DLTRACEIN((""));
       
   973     CNcdNodeNewStatus* self = CNcdNodeNewStatus::NewLC( aNodeIdentifier,
       
   974         aNewStatus,
       
   975         aNodeType );
       
   976     CleanupStack::Pop( self );
       
   977     return self;
       
   978     }
       
   979     
       
   980 CNcdNodeSeenInfo::CNcdNodeNewStatus* CNcdNodeSeenInfo::CNcdNodeNewStatus::NewLC(
       
   981     const CNcdNodeIdentifier& aNodeIdentifier,
       
   982     TNcdNewStatus aNewStatus,
       
   983     CNcdNodeFactory::TNcdNodeType aNodeType )
       
   984     {
       
   985     DLTRACEIN((""));
       
   986     CNcdNodeNewStatus* self = new ( ELeave ) CNcdNodeNewStatus( aNewStatus,
       
   987         aNodeType );
       
   988     CleanupStack::PushL( self );
       
   989     self->ConstructL( aNodeIdentifier );
       
   990     return self;
       
   991     }
       
   992     
       
   993 CNcdNodeSeenInfo::CNcdNodeNewStatus* CNcdNodeSeenInfo::CNcdNodeNewStatus::NewL(
       
   994     RReadStream& aReadStream )
       
   995     {
       
   996     DLTRACEIN((""));
       
   997     CNcdNodeNewStatus* self = CNcdNodeNewStatus::NewLC( aReadStream );
       
   998     CleanupStack::Pop( self );
       
   999     return self;
       
  1000     }
       
  1001     
       
  1002 CNcdNodeSeenInfo::CNcdNodeNewStatus* CNcdNodeSeenInfo::CNcdNodeNewStatus::NewLC(
       
  1003     RReadStream& aReadStream )
       
  1004     {
       
  1005     DLTRACEIN((""));
       
  1006     CNcdNodeNewStatus* self = new ( ELeave ) CNcdNodeNewStatus();
       
  1007     CleanupStack::PushL( self );
       
  1008     self->InternalizeL( aReadStream );
       
  1009     return self;
       
  1010     }
       
  1011     
       
  1012 CNcdNodeSeenInfo::CNcdNodeNewStatus::~CNcdNodeNewStatus()
       
  1013     {
       
  1014     DLTRACEIN((""));
       
  1015     delete iNodeIdentifier;
       
  1016     }
       
  1017 
       
  1018 const CNcdNodeIdentifier& CNcdNodeSeenInfo::CNcdNodeNewStatus::Identifier() const
       
  1019     {
       
  1020     return *iNodeIdentifier;
       
  1021     }
       
  1022 
       
  1023 TNcdNewStatus CNcdNodeSeenInfo::CNcdNodeNewStatus::NewStatus() const
       
  1024     {
       
  1025     return iNewStatus;
       
  1026     }
       
  1027     
       
  1028 void CNcdNodeSeenInfo::CNcdNodeNewStatus::SetNewStatus( TNcdNewStatus aNewStatus )
       
  1029     {
       
  1030     DLTRACEIN((""));
       
  1031     iNewStatus = aNewStatus;
       
  1032     }
       
  1033 
       
  1034 CNcdNodeFactory::TNcdNodeType CNcdNodeSeenInfo::CNcdNodeNewStatus::NodeType() const
       
  1035     {
       
  1036     return iNodeType;
       
  1037     }
       
  1038 
       
  1039 void CNcdNodeSeenInfo::CNcdNodeNewStatus::ExternalizeL( RWriteStream& aStream )
       
  1040     {
       
  1041     DLTRACEIN((""));
       
  1042     iNodeIdentifier->ExternalizeL( aStream );
       
  1043     aStream.WriteInt32L( iNewStatus );
       
  1044     aStream.WriteInt32L( iNodeType );
       
  1045     }
       
  1046 
       
  1047 
       
  1048 void CNcdNodeSeenInfo::CNcdNodeNewStatus::InternalizeL( RReadStream& aStream ) 
       
  1049     {
       
  1050     DLTRACEIN((""));
       
  1051     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewL( aStream );
       
  1052     delete iNodeIdentifier;
       
  1053     iNodeIdentifier = identifier;
       
  1054     iNewStatus = static_cast<TNcdNewStatus>( aStream.ReadInt32L() );
       
  1055     iNodeType = static_cast<CNcdNodeFactory::TNcdNodeType>( aStream.ReadInt32L() );
       
  1056     }
       
  1057 
       
  1058 CNcdNodeSeenInfo::CNcdNodeNewStatus::CNcdNodeNewStatus( TNcdNewStatus aNewStatus,
       
  1059     CNcdNodeFactory::TNcdNodeType aNodeType )
       
  1060     : iNewStatus( aNewStatus ), iNodeType( aNodeType )
       
  1061     {
       
  1062     }
       
  1063     
       
  1064 CNcdNodeSeenInfo::CNcdNodeNewStatus::CNcdNodeNewStatus()
       
  1065     {
       
  1066     }
       
  1067  
       
  1068 void CNcdNodeSeenInfo::CNcdNodeNewStatus::ConstructL(
       
  1069     const CNcdNodeIdentifier& aNodeIdentifier )
       
  1070     {
       
  1071     DLTRACEIN((""));
       
  1072     iNodeIdentifier = CNcdNodeIdentifier::NewL( aNodeIdentifier );
       
  1073     }