photosgallery/viewframework/medialists/src/glxmedialistiterator.cpp
changeset 0 4e91876724a2
child 18 bcb43dc84c44
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     1 /*
       
     2 * Copyright (c) 2008-2009 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:    Item ordered for traversing lists
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "mglxmedialist.h"
       
    22 #include "glxlistutils.h"
       
    23 #include "glxmedialistiterator.h"
       
    24 
       
    25 #include <glxtracer.h>
       
    26 #include <glxlog.h>
       
    27 #include <hal.h>
       
    28 
       
    29 const TInt KSequentialIteratorInitialValue = -1;
       
    30 // Default granularity of items to request for
       
    31 const TUint KGlxBlockyIteratorDefaultGranularity = 15;
       
    32 
       
    33 const TInt KGlxLowerMemoryLimitForCacheSize = 15000000;
       
    34 const TInt KGlxUpperMemoryLimitForCacheSize = 25000000;
       
    35 
       
    36 const TInt KMaxLowMemOffsetValue = 3;
       
    37 const TInt KMinLowMemOffsetValue = 1;
       
    38 
       
    39 EXPORT_C TGlxSequentialIterator::TGlxSequentialIterator()
       
    40     {
       
    41     TRACER("TGlxSequentialIterator::TGlxSequentialIterator");
       
    42     
       
    43     iList = NULL;
       
    44     iCurrentItem = KSequentialIteratorInitialValue;
       
    45     iRange = KMaxTInt;      // To support full list length iteration,if range is not set                         
       
    46     }
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // Set to first item
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 void TGlxSequentialIterator::SetToFirst(const MGlxMediaList* aList)
       
    53     {
       
    54     TRACER("TGlxSequentialIterator::SetToFirst");
       
    55     
       
    56     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
    57     iList = aList;
       
    58     iCurrentItem = KSequentialIteratorInitialValue;
       
    59     }
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // Return the next item index or KErrNotFound
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 TInt TGlxSequentialIterator::operator++(TInt) 
       
    66     {
       
    67     TRACER("TGlxSequentialIterator::operator++");
       
    68     
       
    69     iCurrentItem++;
       
    70     if (iCurrentItem < iList->Count() && iCurrentItem < iRange )
       
    71         {
       
    72         return iCurrentItem;
       
    73         }
       
    74     else
       
    75         {
       
    76         return KErrNotFound;
       
    77         }
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // Return ETrue if index is within range, EFalse otherwise
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 TBool TGlxSequentialIterator::InRange(TInt aIndex) const
       
    85     {
       
    86     TRACER("TGlxSequentialIterator::InRange");
       
    87     
       
    88     return (aIndex < iRange && aIndex < iList->Count() && aIndex >= 0);
       
    89     }
       
    90 // -----------------------------------------------------------------------------
       
    91 // SetRange
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 EXPORT_C void TGlxSequentialIterator::SetRange( TInt aRange )
       
    95     {
       
    96     TRACER("TGlxSequentialIterator::SetRange");
       
    97     
       
    98     iRange = aRange; 
       
    99     }
       
   100     
       
   101 // -----------------------------------------------------------------------------
       
   102 // Constructor
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C TGlxSpecificIdIterator::TGlxSpecificIdIterator(const TGlxIdSpaceId& aIdSpaceId, TGlxMediaId aMediaId)
       
   106     : iMediaId(aMediaId), iIdSpaceId(aIdSpaceId), iFinished(EFalse)
       
   107     {
       
   108     TRACER("TGlxSpecificIdIterator::TGlxSpecificIdIterator");
       
   109     
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // Set to first item
       
   114 // -----------------------------------------------------------------------------
       
   115 //
       
   116 void TGlxSpecificIdIterator::SetToFirst(const MGlxMediaList* aList)
       
   117     {
       
   118     TRACER("TGlxSpecificIdIterator::SetToFirst");
       
   119     
       
   120     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
   121     iList = aList;
       
   122     iFinished = EFalse;
       
   123     }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // Return the next item index or KErrNotFound
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 TInt TGlxSpecificIdIterator::operator++(TInt) 
       
   130     {
       
   131     TRACER("TGlxSpecificIdIterator::operator++");
       
   132     
       
   133     if (iFinished)
       
   134         {
       
   135         return KErrNotFound;
       
   136         }
       
   137     else
       
   138         {
       
   139         iFinished = ETrue;        
       
   140         return iList->Index(iIdSpaceId, iMediaId);
       
   141         }
       
   142     }
       
   143 // -----------------------------------------------------------------------------
       
   144 // Return ETrue if index is within range, EFalse otherwise
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 TBool TGlxSpecificIdIterator::InRange(TInt aIndex) const
       
   148     {
       
   149     TRACER("TGlxSpecificIdIterator::InRange");
       
   150     
       
   151     return (aIndex == iList->Index(iIdSpaceId, iMediaId));
       
   152     }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // Constructor
       
   156 // -----------------------------------------------------------------------------
       
   157 //
       
   158 EXPORT_C TGlxFirstThenLastIterator::TGlxFirstThenLastIterator()
       
   159     {
       
   160     TRACER("TGlxFirstThenLastIterator::TGlxFirstThenLastIterator");
       
   161     
       
   162     iCurrentItem = 0;
       
   163     iList = NULL;
       
   164   }
       
   165     
       
   166 // -----------------------------------------------------------------------------
       
   167 // Destructor
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 EXPORT_C TGlxFirstThenLastIterator::~TGlxFirstThenLastIterator()
       
   171     {
       
   172     TRACER("TGlxFirstThenLastIterator::~TGlxFirstThenLastIterator");
       
   173     
       
   174     }
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 // Set to first item
       
   178 // -----------------------------------------------------------------------------
       
   179 //
       
   180 void TGlxFirstThenLastIterator::SetToFirst(const MGlxMediaList* aList) 
       
   181     {
       
   182     TRACER("TGlxFirstThenLastIterator::SetToFirst");    
       
   183     __ASSERT_DEBUG(aList, Panic(EGlxPanicNullPointer));
       
   184 
       
   185     iList = aList;
       
   186     iCurrentItem = 0;
       
   187   }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // Return the next item index or KErrNotFound
       
   191 // -----------------------------------------------------------------------------
       
   192 //
       
   193 TInt TGlxFirstThenLastIterator::operator++(TInt) 
       
   194     {
       
   195     TRACER("TGlxFirstThenLastIterator::operator++");    
       
   196     __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
       
   197 
       
   198     TInt count = iList->Count();
       
   199     if (count <= 0)
       
   200         {
       
   201         return KErrNotFound;
       
   202         }
       
   203 
       
   204     if (iCurrentItem == 0) 
       
   205         {
       
   206         // Return first item index
       
   207        iCurrentItem++;
       
   208        return 0; 
       
   209         }
       
   210 
       
   211     if (iCurrentItem == 1) 
       
   212         {
       
   213         // Return last item index
       
   214         iCurrentItem++;
       
   215         return count - 1;
       
   216         }
       
   217     
       
   218   // At last item already
       
   219     return KErrNotFound; 
       
   220     }
       
   221 // -----------------------------------------------------------------------------
       
   222 // Return ETrue if index is within range, EFalse otherwise
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 TBool TGlxFirstThenLastIterator::InRange(TInt aIndex) const
       
   226     {
       
   227     TRACER("TGlxFirstThenLastIterator::InRange");
       
   228     __ASSERT_DEBUG(aIndex >= 0 && aIndex < iList->Count(), Panic(EGlxPanicIllegalArgument));
       
   229 
       
   230     // Return ETrue if first or last item
       
   231     return (aIndex == 0) || (aIndex == iList->Count() - 1);
       
   232     }
       
   233 
       
   234 // -----------------------------------------------------------------------------
       
   235 // Constructor
       
   236 // -----------------------------------------------------------------------------
       
   237 //
       
   238 EXPORT_C TGlxFromFocusOutwardIterator::TGlxFromFocusOutwardIterator()
       
   239     {
       
   240     TRACER("TGlxFromFocusOutwardIterator::TGlxFromFocusOutwardIterator");
       
   241     iCurrentItem = 0;
       
   242     iFrontOffset = 0;
       
   243     iRearOffset = 0;
       
   244     iList = NULL;
       
   245   }
       
   246     
       
   247 // -----------------------------------------------------------------------------
       
   248 // Destructor
       
   249 // -----------------------------------------------------------------------------
       
   250 //
       
   251 EXPORT_C TGlxFromFocusOutwardIterator::~TGlxFromFocusOutwardIterator()
       
   252     {
       
   253     TRACER("TGlxFromFocusOutwardIterator::~TGlxFromFocusOutwardIterator");
       
   254     } 
       
   255 
       
   256 // ----------------------------------------------------------------------------
       
   257 // Set range offsets
       
   258 // ----------------------------------------------------------------------------
       
   259 //
       
   260 EXPORT_C void TGlxFromFocusOutwardIterator::SetRangeOffsets(TInt aRearOffset,
       
   261     TInt aFrontOffset)
       
   262     { 
       
   263     TRACER("TGlxFromFocusOutwardIterator::SetRangeOffsets");
       
   264     __ASSERT_DEBUG(aRearOffset >= 0 && aFrontOffset >= 0, Panic(EGlxPanicIllegalArgument)); 
       
   265     iFrontOffset = aFrontOffset;
       
   266     iRearOffset = aRearOffset;
       
   267     iOriginalFrontOffset = iFrontOffset;
       
   268     iOriginalRearOffset = iRearOffset;    
       
   269     }
       
   270 
       
   271 // -----------------------------------------------------------------------------
       
   272 // Set to first item
       
   273 // -----------------------------------------------------------------------------
       
   274 //
       
   275 void TGlxFromFocusOutwardIterator::SetToFirst(const MGlxMediaList* aList) 
       
   276     {
       
   277     TRACER("TGlxFromFocusOutwardIterator::SetToFirst");
       
   278     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
   279 
       
   280     iList = aList;
       
   281     iCurrentItem = 0;
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // Return the item index or KErrNotFound, and goes to next
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 TInt TGlxFromFocusOutwardIterator::operator++(TInt) 
       
   289     {
       
   290     TRACER("TGlxFromFocusOutwardIterator::operator++");
       
   291     __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
       
   292 
       
   293     TInt count = iList->Count();
       
   294     if (count <= 0)
       
   295         {
       
   296         return KErrNotFound;
       
   297         }
       
   298   
       
   299     if (iOriginalFrontOffset > KMaxLowMemOffsetValue && 
       
   300         iOriginalRearOffset > KMaxLowMemOffsetValue)
       
   301         {
       
   302         TInt freeMemory = 0;
       
   303         HAL::Get( HALData::EMemoryRAMFree, freeMemory );    
       
   304         if ( freeMemory < KGlxUpperMemoryLimitForCacheSize &&
       
   305              freeMemory > KGlxLowerMemoryLimitForCacheSize )
       
   306             {
       
   307             iFrontOffset = KMaxLowMemOffsetValue;
       
   308             iRearOffset = KMaxLowMemOffsetValue;
       
   309             }
       
   310         else if ( freeMemory < KGlxLowerMemoryLimitForCacheSize )
       
   311             {
       
   312             iFrontOffset = KMinLowMemOffsetValue;
       
   313             iRearOffset = KMinLowMemOffsetValue;
       
   314             }
       
   315         else if (iFrontOffset != iOriginalFrontOffset 
       
   316                  && iRearOffset!= iOriginalRearOffset)
       
   317             {
       
   318             iFrontOffset = Max(iFrontOffset, iOriginalFrontOffset );
       
   319             iRearOffset = Max(iRearOffset, iOriginalRearOffset );
       
   320             }
       
   321         }
       
   322   
       
   323    // Check if out of bounds
       
   324     if (iFrontOffset + iRearOffset < iCurrentItem || count <= iCurrentItem)
       
   325         {
       
   326         return KErrNotFound;
       
   327         }
       
   328     
       
   329     // The ranges may be inequal, which means there won't be any jumping between
       
   330     // front and rear. 
       
   331     
       
   332     // |-------F----------------------|
       
   333     // |< jumping zone>|
       
   334 
       
   335     TInt index = iList->FocusIndex();
       
   336 
       
   337     TInt min = Min(iFrontOffset, iRearOffset);
       
   338     TInt jumpingZoneLength = min * 2;
       
   339     if (iCurrentItem <= jumpingZoneLength) 
       
   340         {
       
   341         // Still within the (rear-front-rear-front) jumping zone
       
   342         TInt distanceFromFocus = (iCurrentItem + 1) / 2;
       
   343         TBool rear = !(iCurrentItem & 1); // Rear if number is even
       
   344         if (rear) 
       
   345              {
       
   346              index -= distanceFromFocus; 
       
   347              }
       
   348         else 
       
   349              {
       
   350              index += distanceFromFocus; 
       
   351              }
       
   352         }
       
   353      else 
       
   354          {
       
   355          __ASSERT_DEBUG(iFrontOffset != iRearOffset, Panic(EGlxPanicLogicError));
       
   356     
       
   357          // index is currently focus index. Figure out how much need to move.
       
   358          TInt indexesFromFocus = iCurrentItem - min; 
       
   359          if (iRearOffset < iFrontOffset)
       
   360              {
       
   361              // Front range is longer than rear, so the item is on the front side
       
   362              index += indexesFromFocus;
       
   363              }
       
   364          else 
       
   365              {
       
   366              // Rear range is longer than front, so the item is on the rear side
       
   367              index -= indexesFromFocus;
       
   368              }
       
   369          }
       
   370 
       
   371       iCurrentItem++;
       
   372     
       
   373       // The index may be below 0 or above count. Normalise back to list indexes.
       
   374       return GlxListUtils::NormalizedIndex(index, count); 
       
   375       } 
       
   376   
       
   377 // -----------------------------------------------------------------------------
       
   378 // Return ETrue if index is within range, EFalse otherwise
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 TBool TGlxFromFocusOutwardIterator::InRange(TInt aIndex) const
       
   382     {
       
   383     TRACER("TGlxFromFocusOutwardIterator::InRange");
       
   384     TInt count = iList->Count();
       
   385   
       
   386     // Handle the case where range is longer than count separately, because looping will
       
   387     // confuse otherwise
       
   388     if (count <= iRearOffset + iFrontOffset) 
       
   389         {
       
   390         // Range is longer than count, must be in range
       
   391         return ETrue;
       
   392         }
       
   393   
       
   394     TInt focusIndex = iList->FocusIndex();
       
   395     TInt firstInRange = GlxListUtils::NormalizedIndex(focusIndex - iRearOffset, count);
       
   396     TInt lastInRange = GlxListUtils::NormalizedIndex(focusIndex + iFrontOffset, count);
       
   397   
       
   398     if (firstInRange <= lastInRange)
       
   399         {
       
   400         // Normal case:  |    F-------L   |
       
   401         return aIndex >= firstInRange && aIndex <= lastInRange;
       
   402         }
       
   403     else 
       
   404         {
       
   405         // Looping case: |----L      F----|
       
   406         return aIndex <= lastInRange || aIndex >= firstInRange;
       
   407         }
       
   408     }
       
   409 
       
   410 // -----------------------------------------------------------------------------
       
   411 // Constructor
       
   412 // -----------------------------------------------------------------------------
       
   413 //
       
   414 EXPORT_C TGlxFromIndexOutwardBlockyIterator::TGlxFromIndexOutwardBlockyIterator(
       
   415     const MGlxIndex& aIndexFunctor ) 
       
   416         : iIndexFunctor( aIndexFunctor )
       
   417     {
       
   418     TRACER("TGlxFromIndexOutwardBlockyIterator::TGlxFromIndexOutwardBlockyIterator");
       
   419             
       
   420     iCurrentItem = 0;
       
   421     iFrontOffset = 2 * KGlxBlockyIteratorDefaultGranularity;
       
   422     iRearOffset = 2 * KGlxBlockyIteratorDefaultGranularity;
       
   423     iList = NULL;
       
   424   }
       
   425     
       
   426 // -----------------------------------------------------------------------------
       
   427 // Destructor
       
   428 // -----------------------------------------------------------------------------
       
   429 //
       
   430 EXPORT_C TGlxFromIndexOutwardBlockyIterator::~TGlxFromIndexOutwardBlockyIterator()
       
   431     {
       
   432     TRACER("TGlxFromIndexOutwardBlockyIterator::~TGlxFromIndexOutwardBlockyIterator");
       
   433     
       
   434     } 
       
   435 
       
   436 // ----------------------------------------------------------------------------
       
   437 // Set range offsets
       
   438 // ----------------------------------------------------------------------------
       
   439 //
       
   440 EXPORT_C void TGlxFromIndexOutwardBlockyIterator::SetRangeOffsets(TInt aRearOffset,
       
   441     TInt aFrontOffset)
       
   442     { 
       
   443     TRACER("TGlxFromIndexOutwardBlockyIterator::SetRangeOffsets");
       
   444     
       
   445     __ASSERT_DEBUG(aRearOffset >= 0 && aFrontOffset >= 0, Panic(EGlxPanicIllegalArgument)); 
       
   446     iFrontOffset = Max(aFrontOffset, KGlxBlockyIteratorDefaultGranularity );
       
   447     iRearOffset = Max(aRearOffset, KGlxBlockyIteratorDefaultGranularity );
       
   448     }
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // Set to first item
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 void TGlxFromIndexOutwardBlockyIterator::SetToFirst(const MGlxMediaList* aList) 
       
   455     {
       
   456     TRACER("TGlxFromIndexOutwardBlockyIterator::SetToFirst");
       
   457     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
   458 
       
   459     iList = aList;
       
   460     iCurrentItem = 0;
       
   461     }
       
   462 
       
   463 // -----------------------------------------------------------------------------
       
   464 // Return the item index or KErrNotFound, and goes to next
       
   465 // -----------------------------------------------------------------------------
       
   466 //
       
   467 TInt TGlxFromIndexOutwardBlockyIterator::operator++(TInt) 
       
   468     {
       
   469     TRACER("TGlxFromIndexOutwardBlockyIterator::operator++");
       
   470     __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
       
   471 
       
   472     TInt count = iList->Count();
       
   473     if (count <= 0)
       
   474         {
       
   475         return KErrNotFound;
       
   476         }
       
   477   
       
   478    // Check if out of bounds
       
   479     if (iFrontOffset + iRearOffset < iCurrentItem || count <= iCurrentItem)
       
   480         {
       
   481         return KErrNotFound;
       
   482         }
       
   483     
       
   484     // The ranges may be inequal, which means there won't be any jumping between
       
   485     // front and rear. 
       
   486     
       
   487     // |-------F----------------------|
       
   488     // |< jumping zone>|
       
   489 
       
   490     TInt index = iIndexFunctor.Index();
       
   491     __ASSERT_ALWAYS( index >= 0 && index < iList->Count(), Panic( EGlxPanicIllegalState ) );
       
   492     index -= index % KGlxBlockyIteratorDefaultGranularity;
       
   493 
       
   494     TInt min = Min(iFrontOffset, iRearOffset);
       
   495     TInt jumpingZoneLength = min * 2;
       
   496     if (iCurrentItem <= jumpingZoneLength) 
       
   497         {
       
   498         // Still within the (rear-front-rear-front) jumping zone
       
   499         TInt distanceFromFocus = (iCurrentItem + 1) / 2;
       
   500         TBool rear = !(iCurrentItem & 1); // Rear if number is even
       
   501         if (rear) 
       
   502              {
       
   503              index -= distanceFromFocus; 
       
   504              }
       
   505         else 
       
   506              {
       
   507              index += distanceFromFocus; 
       
   508              }
       
   509         }
       
   510      else 
       
   511          {
       
   512          __ASSERT_DEBUG(iFrontOffset != iRearOffset, Panic(EGlxPanicLogicError));
       
   513     
       
   514          // index is currently focus index. Figure out how much need to move.
       
   515          TInt indexesFromFocus = iCurrentItem - min; 
       
   516          if (iRearOffset < iFrontOffset)
       
   517              {
       
   518              // Front range is longer than rear, so the item is on the front side
       
   519              index += indexesFromFocus;
       
   520              }
       
   521          else 
       
   522              {
       
   523              // Rear range is longer than front, so the item is on the rear side
       
   524              index -= indexesFromFocus;
       
   525              }
       
   526          }
       
   527 
       
   528       iCurrentItem++;
       
   529     
       
   530       // The index may be below 0 or above count. Normalise back to list indexes.
       
   531       return GlxListUtils::NormalizedIndex(index, count); 
       
   532       } 
       
   533   
       
   534 // -----------------------------------------------------------------------------
       
   535 // Return ETrue if index is within range, EFalse otherwise
       
   536 // -----------------------------------------------------------------------------
       
   537 //
       
   538 TBool TGlxFromIndexOutwardBlockyIterator::InRange(TInt aIndex) const
       
   539     {
       
   540     TRACER("TGlxFromIndexOutwardBlockyIterator::InRange");
       
   541     TInt count = iList->Count();
       
   542   
       
   543     // Handle the case where range is longer than count separately, because looping will
       
   544     // confuse otherwise
       
   545     if (count <= iRearOffset + iFrontOffset) 
       
   546         {
       
   547         // Range is longer than count, must be in range
       
   548         return ETrue;
       
   549         }
       
   550   
       
   551     TInt index = iIndexFunctor.Index();
       
   552     __ASSERT_ALWAYS( index >= 0 && index < iList->Count(), Panic( EGlxPanicIllegalState ) );
       
   553     index -= index % KGlxBlockyIteratorDefaultGranularity;
       
   554     TInt firstInRange = GlxListUtils::NormalizedIndex(index - iRearOffset, count);
       
   555     TInt lastInRange = GlxListUtils::NormalizedIndex(index + iFrontOffset, count);
       
   556   
       
   557     if (firstInRange <= lastInRange)
       
   558         {
       
   559         // Normal case:  |    F-------L   |
       
   560         return aIndex >= firstInRange && aIndex <= lastInRange;
       
   561         }
       
   562     else 
       
   563         {
       
   564         // Looping case: |----L      F----|
       
   565         return aIndex <= lastInRange || aIndex >= firstInRange;
       
   566         }
       
   567     }
       
   568 
       
   569 // -----------------------------------------------------------------------------
       
   570 // -----------------------------------------------------------------------------
       
   571 // -----------------------------------------------------------------------------
       
   572     
       
   573 // -----------------------------------------------------------------------------
       
   574 // Constructor
       
   575 // -----------------------------------------------------------------------------
       
   576 //
       
   577 EXPORT_C TGlxFromFocusOutwardBlockyIterator::TGlxFromFocusOutwardBlockyIterator()
       
   578         : TGlxFromIndexOutwardBlockyIterator(*static_cast<TGlxFromIndexOutwardBlockyIterator::MGlxIndex*>(this)  )
       
   579     {
       
   580     TRACER("TGlxFromIndexOutwardBlockyIterator::TGlxFromFocusOutwardBlockyIterator");
       
   581     }
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // Destructor
       
   585 // -----------------------------------------------------------------------------
       
   586 //
       
   587 EXPORT_C TGlxFromFocusOutwardBlockyIterator::~TGlxFromFocusOutwardBlockyIterator()
       
   588     {
       
   589     TRACER("TGlxFromIndexOutwardBlockyIterator::~TGlxFromFocusOutwardBlockyIterator");
       
   590     }
       
   591 
       
   592 // -----------------------------------------------------------------------------
       
   593 // Index
       
   594 // -----------------------------------------------------------------------------
       
   595 //
       
   596 TInt TGlxFromFocusOutwardBlockyIterator::Index() const
       
   597     {
       
   598     TRACER("TGlxFromIndexOutwardBlockyIterator::Index");
       
   599     return iList->FocusIndex();
       
   600     }
       
   601 
       
   602 // -----------------------------------------------------------------------------
       
   603 // -----------------------------------------------------------------------------
       
   604 // -----------------------------------------------------------------------------
       
   605 
       
   606 // -----------------------------------------------------------------------------
       
   607 // Constructor
       
   608 // -----------------------------------------------------------------------------
       
   609 //
       
   610 EXPORT_C TGlxFromManualIndexOutwardBlockyIterator::TGlxFromManualIndexOutwardBlockyIterator()
       
   611         : TGlxFromIndexOutwardBlockyIterator( *static_cast<TGlxFromIndexOutwardBlockyIterator::MGlxIndex*>(this) ), iIndex( 0 )
       
   612     {
       
   613     TRACER("TGlxFromManualIndexOutwardBlockyIterator::TGlxFromManualIndexOutwardBlockyIterator");
       
   614     }
       
   615     
       
   616 // -----------------------------------------------------------------------------
       
   617 // Destructor
       
   618 // -----------------------------------------------------------------------------
       
   619 //
       
   620 EXPORT_C TGlxFromManualIndexOutwardBlockyIterator::~TGlxFromManualIndexOutwardBlockyIterator()
       
   621     {
       
   622     TRACER("TGlxFromManualIndexOutwardBlockyIterator::~TGlxFromManualIndexOutwardBlockyIterator");
       
   623     }
       
   624    
       
   625 // -----------------------------------------------------------------------------
       
   626 // SetIndex
       
   627 // -----------------------------------------------------------------------------
       
   628 //
       
   629 EXPORT_C void TGlxFromManualIndexOutwardBlockyIterator::SetIndex( TInt aIndex )
       
   630     {
       
   631     TRACER("TGlxFromManualIndexOutwardBlockyIterator::SetIndex");
       
   632     
       
   633     __ASSERT_DEBUG( aIndex >= 0 && aIndex < iList->Count(), Panic( EGlxPanicIllegalArgument ) );
       
   634     iIndex = aIndex;
       
   635     }
       
   636     
       
   637 // -----------------------------------------------------------------------------
       
   638 // Index
       
   639 // -----------------------------------------------------------------------------
       
   640 //
       
   641 TInt TGlxFromManualIndexOutwardBlockyIterator::Index() const
       
   642     {
       
   643     TRACER("TGlxFromManualIndexOutwardBlockyIterator::Index");
       
   644     
       
   645     return iIndex;
       
   646     }
       
   647 
       
   648 // -----------------------------------------------------------------------------
       
   649 // -----------------------------------------------------------------------------
       
   650 // -----------------------------------------------------------------------------
       
   651     
       
   652 // -----------------------------------------------------------------------------
       
   653 // Constructor
       
   654 // -----------------------------------------------------------------------------
       
   655 //
       
   656 EXPORT_C TGlxSelectionIterator::TGlxSelectionIterator()
       
   657     {
       
   658     TRACER("TGlxSelectionIterator::TGlxSelectionIterator");
       
   659     
       
   660     iCurrentItem = 0;
       
   661     iList = NULL;
       
   662     iRange = KMaxTInt;
       
   663     iDisabledIfMoreThanRangeSelected = EFalse;
       
   664     }
       
   665     
       
   666 // -----------------------------------------------------------------------------
       
   667 // Destructor
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 EXPORT_C TGlxSelectionIterator::~TGlxSelectionIterator()
       
   671     {
       
   672     TRACER("TGlxSelectionIterator::~TGlxSelectionIterator");
       
   673     }
       
   674 
       
   675 // -----------------------------------------------------------------------------
       
   676 // Set to first item
       
   677 // -----------------------------------------------------------------------------
       
   678 //
       
   679 EXPORT_C void TGlxSelectionIterator::SetToFirst(const MGlxMediaList* aList) 
       
   680     {
       
   681     TRACER("TGlxSelectionIterator::SetToFirst");
       
   682     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
   683   
       
   684     iList = aList;
       
   685     iCurrentItem = 0;
       
   686     }
       
   687 
       
   688 // -----------------------------------------------------------------------------
       
   689 // Return the next item index or KErrNotFound
       
   690 // -----------------------------------------------------------------------------
       
   691 //
       
   692 EXPORT_C TInt TGlxSelectionIterator::operator++(TInt) 
       
   693     {
       
   694     TRACER("TGlxSelectionIterator::operator++");
       
   695     __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
       
   696 
       
   697     TInt result = KErrNotFound;
       
   698 
       
   699     TInt selectionCount = iList->SelectionCount();
       
   700   
       
   701     if (!iDisabledIfMoreThanRangeSelected || (selectionCount <= iRange))
       
   702     { 
       
   703     if (selectionCount == 0)
       
   704         {
       
   705         // If no items are selected, treat the focused index as the selection
       
   706         if ( iCurrentItem == 0 )
       
   707             {
       
   708             result = iList->FocusIndex();
       
   709             iCurrentItem++;
       
   710             }
       
   711         }
       
   712     else
       
   713         {
       
   714         if ( iCurrentItem < iRange && iCurrentItem < selectionCount )
       
   715             {
       
   716             result = iList->SelectedItemIndex(iCurrentItem);
       
   717             iCurrentItem++;
       
   718             }
       
   719         }
       
   720     }
       
   721   return result; 
       
   722   }
       
   723 
       
   724 // -----------------------------------------------------------------------------
       
   725 // TGlxSelectionIterator::InRange
       
   726 // -----------------------------------------------------------------------------
       
   727 //
       
   728 
       
   729 EXPORT_C TBool TGlxSelectionIterator::InRange(TInt aIndex) const
       
   730     {
       
   731     TRACER("TGlxSelectionIterator::InRange");
       
   732     __ASSERT_DEBUG(aIndex >= 0 && aIndex < iList->Count(), Panic(EGlxPanicIllegalArgument));
       
   733 
       
   734     TInt selectionCount = iList->SelectionCount();
       
   735     TBool inRange = EFalse;
       
   736   
       
   737     if (selectionCount)
       
   738         {
       
   739         TBool legalIndex = EFalse;
       
   740         if (selectionCount > iRange)
       
   741             {
       
   742             if (iDisabledIfMoreThanRangeSelected)
       
   743                 {
       
   744                 legalIndex = EFalse;
       
   745                 }
       
   746             else
       
   747                 {
       
   748                 legalIndex = (iList->SelectedItemIndex(iRange) > aIndex);
       
   749                 }
       
   750             }
       
   751         else
       
   752             {
       
   753             legalIndex = ETrue;
       
   754             }
       
   755     
       
   756         if(legalIndex)
       
   757             {
       
   758             inRange = iList->IsSelected(aIndex);
       
   759             }
       
   760        }
       
   761     else
       
   762        {
       
   763        if (!(iDisabledIfMoreThanRangeSelected && (iRange == 0)))
       
   764            {
       
   765            inRange = (aIndex == iList->FocusIndex());
       
   766            }
       
   767        }
       
   768     return inRange;
       
   769 }
       
   770 
       
   771 // -----------------------------------------------------------------------------
       
   772 // TGlxSelectionIterator::SetRange
       
   773 // -----------------------------------------------------------------------------
       
   774 //
       
   775 EXPORT_C void TGlxSelectionIterator::SetRange(TInt aMaxItems)
       
   776     {
       
   777     TRACER("TGlxSelectionIterator::SetRange");
       
   778     iRange = aMaxItems;
       
   779     }
       
   780 
       
   781 // -----------------------------------------------------------------------------
       
   782 // TGlxSelectionIterator::SetDisabledIfMoreThanRangeSelected
       
   783 // -----------------------------------------------------------------------------
       
   784 //
       
   785 EXPORT_C void TGlxSelectionIterator::SetDisabledIfMoreThanRangeSelected(TBool aDisabledIfMoreThanRangeSelected)
       
   786     {
       
   787     TRACER("TGlxSelectionIterator::SetDisabledIfMoreThanRangeSelected");
       
   788     iDisabledIfMoreThanRangeSelected = aDisabledIfMoreThanRangeSelected;
       
   789     }
       
   790 // -----------------------------------------------------------------------------
       
   791 // Constructor
       
   792 // -----------------------------------------------------------------------------
       
   793 //
       
   794 EXPORT_C TGlxExclusionIterator::TGlxExclusionIterator( MGlxMediaListIterator& aIncludedItemsIterator,
       
   795                                                        MGlxMediaListIterator& aExcludedItemsIterator )
       
   796                                                        :iIncludedItemsIterator( aIncludedItemsIterator ),
       
   797                                                        iExcludedItemsIterator( aExcludedItemsIterator )
       
   798     {           
       
   799     TRACER("TGlxExclusionIterator::TGlxExclusionIterator" );
       
   800     }
       
   801     
       
   802 // -----------------------------------------------------------------------------
       
   803 // Destructor
       
   804 // -----------------------------------------------------------------------------
       
   805 //
       
   806 EXPORT_C TGlxExclusionIterator::~TGlxExclusionIterator()
       
   807     {
       
   808     TRACER("TGlxExclusionIterator::~TGlxExclusionIterator");
       
   809     } 
       
   810     
       
   811 // -----------------------------------------------------------------------------
       
   812 // Set to first item
       
   813 // -----------------------------------------------------------------------------
       
   814 //
       
   815 EXPORT_C void TGlxExclusionIterator::SetToFirst(const MGlxMediaList* aList)
       
   816     {
       
   817     TRACER("TGlxExclusionIterator::SetToFirst");
       
   818     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
   819 
       
   820     //implementation delegates to both the iterators         
       
   821     iIncludedItemsIterator.SetToFirst( aList );
       
   822     iExcludedItemsIterator.SetToFirst( aList ); 
       
   823     }
       
   824     
       
   825 // -----------------------------------------------------------------------------
       
   826 // Return the next item index or KErrNotFound
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 TInt TGlxExclusionIterator::operator++(TInt ) 
       
   830     { 
       
   831     TRACER("TGlxExclusionIterator::operator++");
       
   832 
       
   833     // This method returns the next valid item of the iterator such that 
       
   834     // (1) The index is within the range of iIncludedItemsIterator
       
   835     // and
       
   836     // (2) The index is not in the range of iExcludedItemsIterator.
       
   837     // If iIncludedItemsIterator reaches its end in this process then we loop to the 
       
   838     // first item and repeat the above steps.
       
   839 
       
   840     TInt index = KErrNotFound; // assign initial value for maintenance safety
       
   841 
       
   842     do  {
       
   843         index = iIncludedItemsIterator++;
       
   844         } while ( KErrNotFound != index && iExcludedItemsIterator.InRange( index ) );
       
   845 
       
   846     return index;
       
   847     }
       
   848     
       
   849     
       
   850 // -----------------------------------------------------------------------------
       
   851 // Return ETrue if index is within range, EFalse otherwise
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 TBool TGlxExclusionIterator::InRange(TInt aIndex) const
       
   855     { 
       
   856     TRACER("TGlxExclusionIterator::InRange");
       
   857     
       
   858     // Verify that aIndex is 
       
   859     // (1) In the range of iIncludedItemsIterator 
       
   860     // and 
       
   861     // (2) Not in the range of iExcludedItemsIterator  
       
   862     
       
   863 
       
   864     return iIncludedItemsIterator.InRange(aIndex) &&
       
   865                     !iExcludedItemsIterator.InRange(aIndex); 
       
   866     }
       
   867 
       
   868 // -----------------------------------------------------------------------------
       
   869 // Constructor
       
   870 // -----------------------------------------------------------------------------
       
   871 //
       
   872 EXPORT_C TGlxFromManualIndexBlockyIterator::TGlxFromManualIndexBlockyIterator( )
       
   873     {
       
   874     TRACER("TGlxFromManualIndexBlockyIterator::TGlxFromManualIndexBlockyIterator");
       
   875     iDefaultVisItems = GlxListUtils::VisibleItemsGranularityL();       
       
   876     iCurrentItem = 0;
       
   877     iFrontOffset = 4 * iDefaultVisItems;
       
   878     iRearOffset = 2 * iDefaultVisItems;
       
   879     iOriginalFrontOffset = iFrontOffset;
       
   880     iOriginalRearOffset = iRearOffset;
       
   881     iList = NULL;
       
   882   }
       
   883     
       
   884 // -----------------------------------------------------------------------------
       
   885 // Destructor
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 EXPORT_C TGlxFromManualIndexBlockyIterator::~TGlxFromManualIndexBlockyIterator()
       
   889     {
       
   890     TRACER("TGlxFromManualIndexBlockyIterator::~TGlxFromManualIndexBlockyIterator");
       
   891     
       
   892     } 
       
   893 
       
   894 // ----------------------------------------------------------------------------
       
   895 // Set range offsets
       
   896 // ----------------------------------------------------------------------------
       
   897 //
       
   898 EXPORT_C void TGlxFromManualIndexBlockyIterator::SetRangeOffsets(TInt aRearOffset,
       
   899     TInt aFrontOffset)
       
   900     { 
       
   901     TRACER("TGlxFromManualIndexBlockyIterator::SetRangeOffsets");
       
   902     
       
   903     __ASSERT_DEBUG(aRearOffset >= 0 && aFrontOffset >= 0, Panic(EGlxPanicIllegalArgument)); 
       
   904     iFrontOffset = Max(aFrontOffset, iDefaultVisItems );
       
   905     iRearOffset = Max(aRearOffset, iDefaultVisItems );
       
   906     iOriginalFrontOffset = iFrontOffset;
       
   907     iOriginalRearOffset = iRearOffset;    
       
   908     }
       
   909 
       
   910 // -----------------------------------------------------------------------------
       
   911 // Set to first item
       
   912 // -----------------------------------------------------------------------------
       
   913 //
       
   914 void TGlxFromManualIndexBlockyIterator::SetToFirst(const MGlxMediaList* aList) 
       
   915     {
       
   916     TRACER("TGlxFromManualIndexBlockyIterator::SetToFirst");
       
   917     __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
       
   918 
       
   919     iList = aList;
       
   920     iCurrentItem = 0;
       
   921     }
       
   922 
       
   923 // -----------------------------------------------------------------------------
       
   924 // Return the item index or KErrNotFound, and goes to next
       
   925 // -----------------------------------------------------------------------------
       
   926 //
       
   927 TInt TGlxFromManualIndexBlockyIterator::operator++(TInt) 
       
   928     {
       
   929     TRACER("TGlxFromManualIndexBlockyIterator::operator++");
       
   930     __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
       
   931 
       
   932     TInt count = iList->Count();
       
   933     if (count <= 0)
       
   934         {
       
   935         return KErrNotFound;
       
   936         }
       
   937 
       
   938     if (iOriginalFrontOffset > KMaxLowMemOffsetValue* iDefaultVisItems &&
       
   939         iOriginalRearOffset > KMaxLowMemOffsetValue * iDefaultVisItems)
       
   940         {
       
   941         TInt freeMemory = 0;
       
   942         HAL::Get( HALData::EMemoryRAMFree, freeMemory );    
       
   943         if ( freeMemory < KGlxUpperMemoryLimitForCacheSize &&
       
   944              freeMemory > KGlxLowerMemoryLimitForCacheSize )
       
   945             {
       
   946             iFrontOffset = 2*iDefaultVisItems;
       
   947             iRearOffset = 3*iDefaultVisItems;
       
   948             }
       
   949         else if ( freeMemory < KGlxLowerMemoryLimitForCacheSize )
       
   950             {
       
   951             iFrontOffset = iDefaultVisItems;
       
   952             iRearOffset = iDefaultVisItems;
       
   953             }
       
   954         else if (iFrontOffset != iOriginalFrontOffset 
       
   955                  && iRearOffset!= iOriginalRearOffset)
       
   956             {
       
   957             iFrontOffset = Max(iFrontOffset, iOriginalFrontOffset );
       
   958             iRearOffset = Max(iRearOffset, iOriginalRearOffset );
       
   959             }
       
   960         }
       
   961   
       
   962    // Check if out of bounds
       
   963     if (iFrontOffset + iRearOffset < iCurrentItem || count <= iCurrentItem)
       
   964         {
       
   965         return KErrNotFound;
       
   966         }
       
   967     
       
   968     // The ranges may be inequal, which means there won't be any jumping between
       
   969     // front and rear. 
       
   970     
       
   971     // |-------F----------------------|
       
   972     // |< jumping zone>|
       
   973 
       
   974     TInt visIndex = iList->VisibleWindowIndex();
       
   975     TInt index = visIndex;
       
   976     TInt listCount = iList->Count();
       
   977     __ASSERT_ALWAYS( index >= 0 && index <= listCount, Panic( EGlxPanicIllegalState ) );
       
   978     //Inorder to ensure that the start of refresh of thumbnails is contained in
       
   979     //in the current visible window. We set the startIndex to center element of 
       
   980     //the current visible window.
       
   981     TInt startIndex = index + iDefaultVisItems/2;
       
   982     if (listCount < iDefaultVisItems)
       
   983         {
       
   984         startIndex = listCount/2;
       
   985         }
       
   986     
       
   987     index = ( (startIndex) <= (listCount)) ? startIndex : listCount;	    	
       
   988 
       
   989     TInt min = Min(iFrontOffset, iRearOffset);
       
   990     TInt jumpingZoneLength = min * 2;
       
   991     if (iCurrentItem <= jumpingZoneLength) 
       
   992         {
       
   993         // Still within the (rear-front-rear-front) jumping zone
       
   994         TInt distanceFromFocus = (iCurrentItem + 1) / 2;
       
   995         TBool rear = !(iCurrentItem & 1); // Rear if number is even
       
   996         // Check if out of bounds
       
   997         if (rear) 
       
   998              {
       
   999              if (index - distanceFromFocus <= visIndex - iRearOffset)
       
  1000                  {
       
  1001                  return KErrNotFound;
       
  1002                  }
       
  1003              index -= distanceFromFocus; 
       
  1004              }
       
  1005         else 
       
  1006              {
       
  1007              if (index + distanceFromFocus >= visIndex + iFrontOffset)
       
  1008                  {
       
  1009                  return KErrNotFound;
       
  1010                  }
       
  1011              index += distanceFromFocus; 
       
  1012              }
       
  1013         }
       
  1014      else 
       
  1015          {
       
  1016          __ASSERT_DEBUG(iFrontOffset != iRearOffset, Panic(EGlxPanicLogicError));
       
  1017     
       
  1018          // index is currently visible index. Figure out how much need to move.
       
  1019          TInt indexesFromFocus = iCurrentItem - min; 
       
  1020          if (iRearOffset < iFrontOffset)
       
  1021              {
       
  1022              // Front range is longer than rear, so the item is on the front side
       
  1023              index += indexesFromFocus;
       
  1024              }
       
  1025          else 
       
  1026              {
       
  1027              // Rear range is longer than front, so the item is on the rear side
       
  1028              index -= indexesFromFocus;
       
  1029              }
       
  1030          }
       
  1031 
       
  1032       iCurrentItem++;
       
  1033     
       
  1034       // The index may be below 0 or above count. Normalise back to list indexes.
       
  1035       return GlxListUtils::NormalizedIndex(index, count); 
       
  1036       } 
       
  1037   
       
  1038 // -----------------------------------------------------------------------------
       
  1039 // Return ETrue if index is within range, EFalse otherwise
       
  1040 // -----------------------------------------------------------------------------
       
  1041 //
       
  1042 TBool TGlxFromManualIndexBlockyIterator::InRange(TInt aIndex) const
       
  1043     {
       
  1044     TRACER("TGlxFromManualIndexBlockyIterator::InRange");
       
  1045     TInt count = iList->Count();
       
  1046   
       
  1047     // Handle the case where range is longer than count separately, because looping will
       
  1048     // confuse otherwise
       
  1049     if (count <= iRearOffset + iFrontOffset) 
       
  1050         {
       
  1051         // Range is longer than count, must be in range
       
  1052         return ETrue;
       
  1053         }
       
  1054   
       
  1055     TInt index = iList->VisibleWindowIndex();
       
  1056     __ASSERT_ALWAYS( index >= 0 && index < iList->Count(), Panic( EGlxPanicIllegalState ) );
       
  1057     
       
  1058     TInt firstInRange = GlxListUtils::NormalizedIndex(index - iRearOffset, count);
       
  1059     TInt lastInRange = GlxListUtils::NormalizedIndex(index + iFrontOffset, count);
       
  1060   
       
  1061     if (firstInRange <= lastInRange)
       
  1062         {
       
  1063         // Normal case:  |    F-------L   |
       
  1064         return aIndex >= firstInRange && aIndex <= lastInRange;
       
  1065         }
       
  1066     else 
       
  1067         {
       
  1068         // Looping case: |----L      F----|
       
  1069         return aIndex <= lastInRange || aIndex >= firstInRange;
       
  1070         }
       
  1071     }