photosgallery/viewframework/medialists/tsrc/src/glxlistreconstruction.cpp
changeset 0 4e91876724a2
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     1 /*
       
     2 * Copyright (c) 2007 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:    Class that reconstructs a list from notifications
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 //  CLASS HEADER
       
    22 #include "glxlistreconstruction.h"
       
    23 
       
    24 //  EXTERNAL INCLUDES
       
    25 #include <digia/eunit/eunitmacros.h>
       
    26 #include <digia/eunit/eunitdecorators.h>
       
    27 #include <mpxcollectionpath.h>
       
    28     
       
    29 //  INTERNAL INCLUDES
       
    30 
       
    31 // -----------------------------------------------------------------------------
       
    32 // Constructor
       
    33 // -----------------------------------------------------------------------------
       
    34 //
       
    35 void CGlxListReconstructionBase::ConstructL( TInt aReservationCount )
       
    36     {
       
    37     iNotifications.ReserveL( aReservationCount );
       
    38     iReconstructedList.ReserveL( aReservationCount );
       
    39     iFocusIndex = -1;
       
    40     }
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // Destructor
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 CGlxListReconstructionBase::~CGlxListReconstructionBase()
       
    47     {
       
    48     iNotifications.Close();
       
    49     iReconstructedList.Close();
       
    50     iSelectedItemIndices.Close();
       
    51     }
       
    52     
       
    53 // -----------------------------------------------------------------------------
       
    54 // Clear notifications array
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 void CGlxListReconstructionBase::ClearNotifications()
       
    58     {
       
    59     iNotifications.Reset();
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // Handle items being added
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 void CGlxListReconstructionBase::HandleItemsAdded( TInt aAddedAtIndex, TInt aCount ) 
       
    67     {
       
    68     TNotification::TData notification[] = { TNotification::EAdd, aAddedAtIndex, aCount };
       
    69     // If fails, not big enough reservation
       
    70     EUNIT_ASSERT( KErrNone == iNotifications.Append( *notification )  ); 
       
    71     
       
    72     // reconstruct the list
       
    73     for ( TInt i = 0; i < aCount; i++ )
       
    74         {
       
    75         // If fails, not big enough reservation
       
    76         EUNIT_ASSERT( KErrNone == iReconstructedList.Insert( 
       
    77             OriginalItem( aAddedAtIndex ), aAddedAtIndex ) );
       
    78         }
       
    79     
       
    80     // Move focus
       
    81     if ( KErrNotFound == iFocusIndex )
       
    82         {
       
    83         iFocusIndex = 0;
       
    84         }
       
    85     else if ( iFocusIndex >= aAddedAtIndex )
       
    86         {
       
    87         iFocusIndex += aCount;
       
    88         }
       
    89     
       
    90     // Move selection        
       
    91     for ( TInt i = 0; i < iSelectedItemIndices.Count(); i++ )
       
    92         {
       
    93         if ( iSelectedItemIndices[ i ] >= aAddedAtIndex )
       
    94             {
       
    95             iSelectedItemIndices[ i ] += aCount;
       
    96             }
       
    97         }
       
    98     
       
    99     // Make sure the original and reconstruction match
       
   100     EUNIT_ASSERT( ReconstructionEquals() );
       
   101     }
       
   102     
       
   103 // -----------------------------------------------------------------------------
       
   104 // Handle items being removed
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 void CGlxListReconstructionBase::HandleItemsRemoved( TInt aRemovedFromIndex, TInt aCount ) 
       
   108     {
       
   109     TNotification::TData notification[] = { TNotification::ERemove, aRemovedFromIndex, aCount };
       
   110     // If fails, not big enough reservation
       
   111     EUNIT_ASSERT( KErrNone == iNotifications.Append( *notification ) ); 
       
   112     // reconstruct the list
       
   113     for ( TInt i = 0; i < aCount; i++ )
       
   114         {
       
   115         iReconstructedList.Remove( aRemovedFromIndex );
       
   116         }
       
   117 
       
   118     // Move focus
       
   119     if ( iFocusIndex >= aRemovedFromIndex + aCount )
       
   120         {
       
   121         iFocusIndex -= aCount;
       
   122         }
       
   123     else if ( iFocusIndex >= aRemovedFromIndex )
       
   124         {
       
   125         // Focused item was removed
       
   126         iFocusIndex = aRemovedFromIndex - 1;
       
   127         if ( iFocusIndex < 0 )
       
   128             {
       
   129             iFocusIndex = 0;
       
   130             }
       
   131         }
       
   132     if ( !iReconstructedList.Count() )
       
   133         {
       
   134         iFocusIndex = KErrNotFound;
       
   135         }
       
   136     
       
   137     // Move/remove selection        
       
   138     TInt i = 0;
       
   139     while ( i < iSelectedItemIndices.Count() )
       
   140         {
       
   141         if ( iSelectedItemIndices[ i ] >= aRemovedFromIndex + aCount )
       
   142             {
       
   143             iSelectedItemIndices[ i ] -= aCount;
       
   144             }
       
   145         else if ( iSelectedItemIndices[ i ] >= aRemovedFromIndex )
       
   146             {
       
   147             iSelectedItemIndices.Remove( i );
       
   148             continue;
       
   149             }
       
   150         i++;
       
   151         }
       
   152 
       
   153     // Make sure the original and reconstruction match
       
   154     EUNIT_ASSERT( ReconstructionEquals() );
       
   155     }
       
   156     
       
   157 // -----------------------------------------------------------------------------
       
   158 // Handle focus changed
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 void CGlxListReconstructionBase::HandleFocusChanged( NGlxListDefs::TFocusChangeType aType, 
       
   162             TInt aNewIndex, TInt aOldIndex )
       
   163     {
       
   164     TNotification::TData notification[] = { TNotification::EFocus, aOldIndex, static_cast< TInt >( aType ) };
       
   165     // If fails, not big enough reservation
       
   166     EUNIT_ASSERT( iNotifications.Append( *notification ) == KErrNone ); 
       
   167 
       
   168     iFocusIndex = aNewIndex;
       
   169 
       
   170     // Make sure the original and reconstruction match
       
   171     EUNIT_ASSERT( ReconstructionEquals() );
       
   172     }
       
   173         
       
   174 // -----------------------------------------------------------------------------
       
   175 // Handle items selected
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 void CGlxListReconstructionBase::HandleItemSelected( TInt aIndex, TBool aSelected )
       
   179     {
       
   180     TNotification::TData notification[] = { TNotification::ESelection, aIndex, aSelected };
       
   181     // If fails, not big enough reservation
       
   182     EUNIT_ASSERT( iNotifications.Append( *notification ) == KErrNone ); 
       
   183 
       
   184     // Should not get a notification that causes no change
       
   185     if ( aSelected )
       
   186         {
       
   187         EUNIT_ASSERT( KErrNotFound == iSelectedItemIndices.Find( aIndex ) );
       
   188         iSelectedItemIndices.Append( aIndex );
       
   189         }
       
   190     else
       
   191         {
       
   192         TInt index = iSelectedItemIndices.Find( aIndex );
       
   193         EUNIT_ASSERT( KErrNotFound != index );
       
   194         iSelectedItemIndices.Remove( index );
       
   195         }
       
   196 
       
   197     EUNIT_ASSERT( ReconstructionEquals() );
       
   198     }
       
   199     
       
   200 // -----------------------------------------------------------------------------
       
   201 // Test if notifications match
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 TBool CGlxListReconstructionBase::NotificationListEquals( const TNotification::TData* aNotificationList )
       
   205     {
       
   206     ASSERT( aNotificationList );
       
   207     
       
   208     TBool fail = EFalse;
       
   209     // Iterator through notifications list
       
   210     TBool markerFound = EFalse;
       
   211     TInt i = 0;
       
   212     while ( ETrue )
       
   213         {
       
   214         if ( i == iNotifications.Count() )
       
   215             {
       
   216             if ( KEndMarker == aNotificationList[ i ] )
       
   217                 {
       
   218                 markerFound = ETrue;
       
   219                 }
       
   220             break;
       
   221             }
       
   222         // Notifications must match
       
   223         const TNotification& notification = iNotifications[ i ]; 
       
   224         fail |= ( notification != aNotificationList[ i ] );
       
   225         i++;
       
   226         }
       
   227     // Must have reached the end of iNotifications
       
   228     fail |= ( i != iNotifications.Count() ); 
       
   229     // Must have found a marker
       
   230     fail |= !markerFound;
       
   231     
       
   232     return !fail;
       
   233     }
       
   234