--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/medialists/src/glxmedialistiterator.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,1071 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Item ordered for traversing lists
+*
+*/
+
+
+
+
+#include "mglxmedialist.h"
+#include "glxlistutils.h"
+#include "glxmedialistiterator.h"
+
+#include <glxtracer.h>
+#include <glxlog.h>
+#include <hal.h>
+
+const TInt KSequentialIteratorInitialValue = -1;
+// Default granularity of items to request for
+const TUint KGlxBlockyIteratorDefaultGranularity = 15;
+
+const TInt KGlxLowerMemoryLimitForCacheSize = 15000000;
+const TInt KGlxUpperMemoryLimitForCacheSize = 25000000;
+
+const TInt KMaxLowMemOffsetValue = 3;
+const TInt KMinLowMemOffsetValue = 1;
+
+EXPORT_C TGlxSequentialIterator::TGlxSequentialIterator()
+ {
+ TRACER("TGlxSequentialIterator::TGlxSequentialIterator");
+
+ iList = NULL;
+ iCurrentItem = KSequentialIteratorInitialValue;
+ iRange = KMaxTInt; // To support full list length iteration,if range is not set
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+void TGlxSequentialIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxSequentialIterator::SetToFirst");
+
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+ iList = aList;
+ iCurrentItem = KSequentialIteratorInitialValue;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the next item index or KErrNotFound
+// -----------------------------------------------------------------------------
+//
+TInt TGlxSequentialIterator::operator++(TInt)
+ {
+ TRACER("TGlxSequentialIterator::operator++");
+
+ iCurrentItem++;
+ if (iCurrentItem < iList->Count() && iCurrentItem < iRange )
+ {
+ return iCurrentItem;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxSequentialIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxSequentialIterator::InRange");
+
+ return (aIndex < iRange && aIndex < iList->Count() && aIndex >= 0);
+ }
+// -----------------------------------------------------------------------------
+// SetRange
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxSequentialIterator::SetRange( TInt aRange )
+ {
+ TRACER("TGlxSequentialIterator::SetRange");
+
+ iRange = aRange;
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxSpecificIdIterator::TGlxSpecificIdIterator(const TGlxIdSpaceId& aIdSpaceId, TGlxMediaId aMediaId)
+ : iMediaId(aMediaId), iIdSpaceId(aIdSpaceId), iFinished(EFalse)
+ {
+ TRACER("TGlxSpecificIdIterator::TGlxSpecificIdIterator");
+
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+void TGlxSpecificIdIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxSpecificIdIterator::SetToFirst");
+
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+ iList = aList;
+ iFinished = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the next item index or KErrNotFound
+// -----------------------------------------------------------------------------
+//
+TInt TGlxSpecificIdIterator::operator++(TInt)
+ {
+ TRACER("TGlxSpecificIdIterator::operator++");
+
+ if (iFinished)
+ {
+ return KErrNotFound;
+ }
+ else
+ {
+ iFinished = ETrue;
+ return iList->Index(iIdSpaceId, iMediaId);
+ }
+ }
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxSpecificIdIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxSpecificIdIterator::InRange");
+
+ return (aIndex == iList->Index(iIdSpaceId, iMediaId));
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFirstThenLastIterator::TGlxFirstThenLastIterator()
+ {
+ TRACER("TGlxFirstThenLastIterator::TGlxFirstThenLastIterator");
+
+ iCurrentItem = 0;
+ iList = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFirstThenLastIterator::~TGlxFirstThenLastIterator()
+ {
+ TRACER("TGlxFirstThenLastIterator::~TGlxFirstThenLastIterator");
+
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+void TGlxFirstThenLastIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxFirstThenLastIterator::SetToFirst");
+ __ASSERT_DEBUG(aList, Panic(EGlxPanicNullPointer));
+
+ iList = aList;
+ iCurrentItem = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the next item index or KErrNotFound
+// -----------------------------------------------------------------------------
+//
+TInt TGlxFirstThenLastIterator::operator++(TInt)
+ {
+ TRACER("TGlxFirstThenLastIterator::operator++");
+ __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
+
+ TInt count = iList->Count();
+ if (count <= 0)
+ {
+ return KErrNotFound;
+ }
+
+ if (iCurrentItem == 0)
+ {
+ // Return first item index
+ iCurrentItem++;
+ return 0;
+ }
+
+ if (iCurrentItem == 1)
+ {
+ // Return last item index
+ iCurrentItem++;
+ return count - 1;
+ }
+
+ // At last item already
+ return KErrNotFound;
+ }
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxFirstThenLastIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxFirstThenLastIterator::InRange");
+ __ASSERT_DEBUG(aIndex >= 0 && aIndex < iList->Count(), Panic(EGlxPanicIllegalArgument));
+
+ // Return ETrue if first or last item
+ return (aIndex == 0) || (aIndex == iList->Count() - 1);
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromFocusOutwardIterator::TGlxFromFocusOutwardIterator()
+ {
+ TRACER("TGlxFromFocusOutwardIterator::TGlxFromFocusOutwardIterator");
+ iCurrentItem = 0;
+ iFrontOffset = 0;
+ iRearOffset = 0;
+ iList = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromFocusOutwardIterator::~TGlxFromFocusOutwardIterator()
+ {
+ TRACER("TGlxFromFocusOutwardIterator::~TGlxFromFocusOutwardIterator");
+ }
+
+// ----------------------------------------------------------------------------
+// Set range offsets
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxFromFocusOutwardIterator::SetRangeOffsets(TInt aRearOffset,
+ TInt aFrontOffset)
+ {
+ TRACER("TGlxFromFocusOutwardIterator::SetRangeOffsets");
+ __ASSERT_DEBUG(aRearOffset >= 0 && aFrontOffset >= 0, Panic(EGlxPanicIllegalArgument));
+ iFrontOffset = aFrontOffset;
+ iRearOffset = aRearOffset;
+ iOriginalFrontOffset = iFrontOffset;
+ iOriginalRearOffset = iRearOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+void TGlxFromFocusOutwardIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxFromFocusOutwardIterator::SetToFirst");
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+
+ iList = aList;
+ iCurrentItem = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the item index or KErrNotFound, and goes to next
+// -----------------------------------------------------------------------------
+//
+TInt TGlxFromFocusOutwardIterator::operator++(TInt)
+ {
+ TRACER("TGlxFromFocusOutwardIterator::operator++");
+ __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
+
+ TInt count = iList->Count();
+ if (count <= 0)
+ {
+ return KErrNotFound;
+ }
+
+ if (iOriginalFrontOffset > KMaxLowMemOffsetValue &&
+ iOriginalRearOffset > KMaxLowMemOffsetValue)
+ {
+ TInt freeMemory = 0;
+ HAL::Get( HALData::EMemoryRAMFree, freeMemory );
+ if ( freeMemory < KGlxUpperMemoryLimitForCacheSize &&
+ freeMemory > KGlxLowerMemoryLimitForCacheSize )
+ {
+ iFrontOffset = KMaxLowMemOffsetValue;
+ iRearOffset = KMaxLowMemOffsetValue;
+ }
+ else if ( freeMemory < KGlxLowerMemoryLimitForCacheSize )
+ {
+ iFrontOffset = KMinLowMemOffsetValue;
+ iRearOffset = KMinLowMemOffsetValue;
+ }
+ else if (iFrontOffset != iOriginalFrontOffset
+ && iRearOffset!= iOriginalRearOffset)
+ {
+ iFrontOffset = Max(iFrontOffset, iOriginalFrontOffset );
+ iRearOffset = Max(iRearOffset, iOriginalRearOffset );
+ }
+ }
+
+ // Check if out of bounds
+ if (iFrontOffset + iRearOffset < iCurrentItem || count <= iCurrentItem)
+ {
+ return KErrNotFound;
+ }
+
+ // The ranges may be inequal, which means there won't be any jumping between
+ // front and rear.
+
+ // |-------F----------------------|
+ // |< jumping zone>|
+
+ TInt index = iList->FocusIndex();
+
+ TInt min = Min(iFrontOffset, iRearOffset);
+ TInt jumpingZoneLength = min * 2;
+ if (iCurrentItem <= jumpingZoneLength)
+ {
+ // Still within the (rear-front-rear-front) jumping zone
+ TInt distanceFromFocus = (iCurrentItem + 1) / 2;
+ TBool rear = !(iCurrentItem & 1); // Rear if number is even
+ if (rear)
+ {
+ index -= distanceFromFocus;
+ }
+ else
+ {
+ index += distanceFromFocus;
+ }
+ }
+ else
+ {
+ __ASSERT_DEBUG(iFrontOffset != iRearOffset, Panic(EGlxPanicLogicError));
+
+ // index is currently focus index. Figure out how much need to move.
+ TInt indexesFromFocus = iCurrentItem - min;
+ if (iRearOffset < iFrontOffset)
+ {
+ // Front range is longer than rear, so the item is on the front side
+ index += indexesFromFocus;
+ }
+ else
+ {
+ // Rear range is longer than front, so the item is on the rear side
+ index -= indexesFromFocus;
+ }
+ }
+
+ iCurrentItem++;
+
+ // The index may be below 0 or above count. Normalise back to list indexes.
+ return GlxListUtils::NormalizedIndex(index, count);
+ }
+
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxFromFocusOutwardIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxFromFocusOutwardIterator::InRange");
+ TInt count = iList->Count();
+
+ // Handle the case where range is longer than count separately, because looping will
+ // confuse otherwise
+ if (count <= iRearOffset + iFrontOffset)
+ {
+ // Range is longer than count, must be in range
+ return ETrue;
+ }
+
+ TInt focusIndex = iList->FocusIndex();
+ TInt firstInRange = GlxListUtils::NormalizedIndex(focusIndex - iRearOffset, count);
+ TInt lastInRange = GlxListUtils::NormalizedIndex(focusIndex + iFrontOffset, count);
+
+ if (firstInRange <= lastInRange)
+ {
+ // Normal case: | F-------L |
+ return aIndex >= firstInRange && aIndex <= lastInRange;
+ }
+ else
+ {
+ // Looping case: |----L F----|
+ return aIndex <= lastInRange || aIndex >= firstInRange;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromIndexOutwardBlockyIterator::TGlxFromIndexOutwardBlockyIterator(
+ const MGlxIndex& aIndexFunctor )
+ : iIndexFunctor( aIndexFunctor )
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::TGlxFromIndexOutwardBlockyIterator");
+
+ iCurrentItem = 0;
+ iFrontOffset = 2 * KGlxBlockyIteratorDefaultGranularity;
+ iRearOffset = 2 * KGlxBlockyIteratorDefaultGranularity;
+ iList = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromIndexOutwardBlockyIterator::~TGlxFromIndexOutwardBlockyIterator()
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::~TGlxFromIndexOutwardBlockyIterator");
+
+ }
+
+// ----------------------------------------------------------------------------
+// Set range offsets
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxFromIndexOutwardBlockyIterator::SetRangeOffsets(TInt aRearOffset,
+ TInt aFrontOffset)
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::SetRangeOffsets");
+
+ __ASSERT_DEBUG(aRearOffset >= 0 && aFrontOffset >= 0, Panic(EGlxPanicIllegalArgument));
+ iFrontOffset = Max(aFrontOffset, KGlxBlockyIteratorDefaultGranularity );
+ iRearOffset = Max(aRearOffset, KGlxBlockyIteratorDefaultGranularity );
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+void TGlxFromIndexOutwardBlockyIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::SetToFirst");
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+
+ iList = aList;
+ iCurrentItem = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the item index or KErrNotFound, and goes to next
+// -----------------------------------------------------------------------------
+//
+TInt TGlxFromIndexOutwardBlockyIterator::operator++(TInt)
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::operator++");
+ __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
+
+ TInt count = iList->Count();
+ if (count <= 0)
+ {
+ return KErrNotFound;
+ }
+
+ // Check if out of bounds
+ if (iFrontOffset + iRearOffset < iCurrentItem || count <= iCurrentItem)
+ {
+ return KErrNotFound;
+ }
+
+ // The ranges may be inequal, which means there won't be any jumping between
+ // front and rear.
+
+ // |-------F----------------------|
+ // |< jumping zone>|
+
+ TInt index = iIndexFunctor.Index();
+ __ASSERT_ALWAYS( index >= 0 && index < iList->Count(), Panic( EGlxPanicIllegalState ) );
+ index -= index % KGlxBlockyIteratorDefaultGranularity;
+
+ TInt min = Min(iFrontOffset, iRearOffset);
+ TInt jumpingZoneLength = min * 2;
+ if (iCurrentItem <= jumpingZoneLength)
+ {
+ // Still within the (rear-front-rear-front) jumping zone
+ TInt distanceFromFocus = (iCurrentItem + 1) / 2;
+ TBool rear = !(iCurrentItem & 1); // Rear if number is even
+ if (rear)
+ {
+ index -= distanceFromFocus;
+ }
+ else
+ {
+ index += distanceFromFocus;
+ }
+ }
+ else
+ {
+ __ASSERT_DEBUG(iFrontOffset != iRearOffset, Panic(EGlxPanicLogicError));
+
+ // index is currently focus index. Figure out how much need to move.
+ TInt indexesFromFocus = iCurrentItem - min;
+ if (iRearOffset < iFrontOffset)
+ {
+ // Front range is longer than rear, so the item is on the front side
+ index += indexesFromFocus;
+ }
+ else
+ {
+ // Rear range is longer than front, so the item is on the rear side
+ index -= indexesFromFocus;
+ }
+ }
+
+ iCurrentItem++;
+
+ // The index may be below 0 or above count. Normalise back to list indexes.
+ return GlxListUtils::NormalizedIndex(index, count);
+ }
+
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxFromIndexOutwardBlockyIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::InRange");
+ TInt count = iList->Count();
+
+ // Handle the case where range is longer than count separately, because looping will
+ // confuse otherwise
+ if (count <= iRearOffset + iFrontOffset)
+ {
+ // Range is longer than count, must be in range
+ return ETrue;
+ }
+
+ TInt index = iIndexFunctor.Index();
+ __ASSERT_ALWAYS( index >= 0 && index < iList->Count(), Panic( EGlxPanicIllegalState ) );
+ index -= index % KGlxBlockyIteratorDefaultGranularity;
+ TInt firstInRange = GlxListUtils::NormalizedIndex(index - iRearOffset, count);
+ TInt lastInRange = GlxListUtils::NormalizedIndex(index + iFrontOffset, count);
+
+ if (firstInRange <= lastInRange)
+ {
+ // Normal case: | F-------L |
+ return aIndex >= firstInRange && aIndex <= lastInRange;
+ }
+ else
+ {
+ // Looping case: |----L F----|
+ return aIndex <= lastInRange || aIndex >= firstInRange;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromFocusOutwardBlockyIterator::TGlxFromFocusOutwardBlockyIterator()
+ : TGlxFromIndexOutwardBlockyIterator(*static_cast<TGlxFromIndexOutwardBlockyIterator::MGlxIndex*>(this) )
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::TGlxFromFocusOutwardBlockyIterator");
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromFocusOutwardBlockyIterator::~TGlxFromFocusOutwardBlockyIterator()
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::~TGlxFromFocusOutwardBlockyIterator");
+ }
+
+// -----------------------------------------------------------------------------
+// Index
+// -----------------------------------------------------------------------------
+//
+TInt TGlxFromFocusOutwardBlockyIterator::Index() const
+ {
+ TRACER("TGlxFromIndexOutwardBlockyIterator::Index");
+ return iList->FocusIndex();
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromManualIndexOutwardBlockyIterator::TGlxFromManualIndexOutwardBlockyIterator()
+ : TGlxFromIndexOutwardBlockyIterator( *static_cast<TGlxFromIndexOutwardBlockyIterator::MGlxIndex*>(this) ), iIndex( 0 )
+ {
+ TRACER("TGlxFromManualIndexOutwardBlockyIterator::TGlxFromManualIndexOutwardBlockyIterator");
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromManualIndexOutwardBlockyIterator::~TGlxFromManualIndexOutwardBlockyIterator()
+ {
+ TRACER("TGlxFromManualIndexOutwardBlockyIterator::~TGlxFromManualIndexOutwardBlockyIterator");
+ }
+
+// -----------------------------------------------------------------------------
+// SetIndex
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxFromManualIndexOutwardBlockyIterator::SetIndex( TInt aIndex )
+ {
+ TRACER("TGlxFromManualIndexOutwardBlockyIterator::SetIndex");
+
+ __ASSERT_DEBUG( aIndex >= 0 && aIndex < iList->Count(), Panic( EGlxPanicIllegalArgument ) );
+ iIndex = aIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// Index
+// -----------------------------------------------------------------------------
+//
+TInt TGlxFromManualIndexOutwardBlockyIterator::Index() const
+ {
+ TRACER("TGlxFromManualIndexOutwardBlockyIterator::Index");
+
+ return iIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxSelectionIterator::TGlxSelectionIterator()
+ {
+ TRACER("TGlxSelectionIterator::TGlxSelectionIterator");
+
+ iCurrentItem = 0;
+ iList = NULL;
+ iRange = KMaxTInt;
+ iDisabledIfMoreThanRangeSelected = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxSelectionIterator::~TGlxSelectionIterator()
+ {
+ TRACER("TGlxSelectionIterator::~TGlxSelectionIterator");
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxSelectionIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxSelectionIterator::SetToFirst");
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+
+ iList = aList;
+ iCurrentItem = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the next item index or KErrNotFound
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt TGlxSelectionIterator::operator++(TInt)
+ {
+ TRACER("TGlxSelectionIterator::operator++");
+ __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
+
+ TInt result = KErrNotFound;
+
+ TInt selectionCount = iList->SelectionCount();
+
+ if (!iDisabledIfMoreThanRangeSelected || (selectionCount <= iRange))
+ {
+ if (selectionCount == 0)
+ {
+ // If no items are selected, treat the focused index as the selection
+ if ( iCurrentItem == 0 )
+ {
+ result = iList->FocusIndex();
+ iCurrentItem++;
+ }
+ }
+ else
+ {
+ if ( iCurrentItem < iRange && iCurrentItem < selectionCount )
+ {
+ result = iList->SelectedItemIndex(iCurrentItem);
+ iCurrentItem++;
+ }
+ }
+ }
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// TGlxSelectionIterator::InRange
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C TBool TGlxSelectionIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxSelectionIterator::InRange");
+ __ASSERT_DEBUG(aIndex >= 0 && aIndex < iList->Count(), Panic(EGlxPanicIllegalArgument));
+
+ TInt selectionCount = iList->SelectionCount();
+ TBool inRange = EFalse;
+
+ if (selectionCount)
+ {
+ TBool legalIndex = EFalse;
+ if (selectionCount > iRange)
+ {
+ if (iDisabledIfMoreThanRangeSelected)
+ {
+ legalIndex = EFalse;
+ }
+ else
+ {
+ legalIndex = (iList->SelectedItemIndex(iRange) > aIndex);
+ }
+ }
+ else
+ {
+ legalIndex = ETrue;
+ }
+
+ if(legalIndex)
+ {
+ inRange = iList->IsSelected(aIndex);
+ }
+ }
+ else
+ {
+ if (!(iDisabledIfMoreThanRangeSelected && (iRange == 0)))
+ {
+ inRange = (aIndex == iList->FocusIndex());
+ }
+ }
+ return inRange;
+}
+
+// -----------------------------------------------------------------------------
+// TGlxSelectionIterator::SetRange
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxSelectionIterator::SetRange(TInt aMaxItems)
+ {
+ TRACER("TGlxSelectionIterator::SetRange");
+ iRange = aMaxItems;
+ }
+
+// -----------------------------------------------------------------------------
+// TGlxSelectionIterator::SetDisabledIfMoreThanRangeSelected
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxSelectionIterator::SetDisabledIfMoreThanRangeSelected(TBool aDisabledIfMoreThanRangeSelected)
+ {
+ TRACER("TGlxSelectionIterator::SetDisabledIfMoreThanRangeSelected");
+ iDisabledIfMoreThanRangeSelected = aDisabledIfMoreThanRangeSelected;
+ }
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxExclusionIterator::TGlxExclusionIterator( MGlxMediaListIterator& aIncludedItemsIterator,
+ MGlxMediaListIterator& aExcludedItemsIterator )
+ :iIncludedItemsIterator( aIncludedItemsIterator ),
+ iExcludedItemsIterator( aExcludedItemsIterator )
+ {
+ TRACER("TGlxExclusionIterator::TGlxExclusionIterator" );
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxExclusionIterator::~TGlxExclusionIterator()
+ {
+ TRACER("TGlxExclusionIterator::~TGlxExclusionIterator");
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxExclusionIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxExclusionIterator::SetToFirst");
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+
+ //implementation delegates to both the iterators
+ iIncludedItemsIterator.SetToFirst( aList );
+ iExcludedItemsIterator.SetToFirst( aList );
+ }
+
+// -----------------------------------------------------------------------------
+// Return the next item index or KErrNotFound
+// -----------------------------------------------------------------------------
+//
+TInt TGlxExclusionIterator::operator++(TInt )
+ {
+ TRACER("TGlxExclusionIterator::operator++");
+
+ // This method returns the next valid item of the iterator such that
+ // (1) The index is within the range of iIncludedItemsIterator
+ // and
+ // (2) The index is not in the range of iExcludedItemsIterator.
+ // If iIncludedItemsIterator reaches its end in this process then we loop to the
+ // first item and repeat the above steps.
+
+ TInt index = KErrNotFound; // assign initial value for maintenance safety
+
+ do {
+ index = iIncludedItemsIterator++;
+ } while ( KErrNotFound != index && iExcludedItemsIterator.InRange( index ) );
+
+ return index;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxExclusionIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxExclusionIterator::InRange");
+
+ // Verify that aIndex is
+ // (1) In the range of iIncludedItemsIterator
+ // and
+ // (2) Not in the range of iExcludedItemsIterator
+
+
+ return iIncludedItemsIterator.InRange(aIndex) &&
+ !iExcludedItemsIterator.InRange(aIndex);
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromManualIndexBlockyIterator::TGlxFromManualIndexBlockyIterator( )
+ {
+ TRACER("TGlxFromManualIndexBlockyIterator::TGlxFromManualIndexBlockyIterator");
+ iDefaultVisItems = GlxListUtils::VisibleItemsGranularityL();
+ iCurrentItem = 0;
+ iFrontOffset = 4 * iDefaultVisItems;
+ iRearOffset = 2 * iDefaultVisItems;
+ iOriginalFrontOffset = iFrontOffset;
+ iOriginalRearOffset = iRearOffset;
+ iList = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGlxFromManualIndexBlockyIterator::~TGlxFromManualIndexBlockyIterator()
+ {
+ TRACER("TGlxFromManualIndexBlockyIterator::~TGlxFromManualIndexBlockyIterator");
+
+ }
+
+// ----------------------------------------------------------------------------
+// Set range offsets
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void TGlxFromManualIndexBlockyIterator::SetRangeOffsets(TInt aRearOffset,
+ TInt aFrontOffset)
+ {
+ TRACER("TGlxFromManualIndexBlockyIterator::SetRangeOffsets");
+
+ __ASSERT_DEBUG(aRearOffset >= 0 && aFrontOffset >= 0, Panic(EGlxPanicIllegalArgument));
+ iFrontOffset = Max(aFrontOffset, iDefaultVisItems );
+ iRearOffset = Max(aRearOffset, iDefaultVisItems );
+ iOriginalFrontOffset = iFrontOffset;
+ iOriginalRearOffset = iRearOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// Set to first item
+// -----------------------------------------------------------------------------
+//
+void TGlxFromManualIndexBlockyIterator::SetToFirst(const MGlxMediaList* aList)
+ {
+ TRACER("TGlxFromManualIndexBlockyIterator::SetToFirst");
+ __ASSERT_DEBUG(aList != NULL, Panic(EGlxPanicNullPointer));
+
+ iList = aList;
+ iCurrentItem = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// Return the item index or KErrNotFound, and goes to next
+// -----------------------------------------------------------------------------
+//
+TInt TGlxFromManualIndexBlockyIterator::operator++(TInt)
+ {
+ TRACER("TGlxFromManualIndexBlockyIterator::operator++");
+ __ASSERT_DEBUG(iList != NULL, Panic(EGlxPanicNullPointer));
+
+ TInt count = iList->Count();
+ if (count <= 0)
+ {
+ return KErrNotFound;
+ }
+
+ if (iOriginalFrontOffset > KMaxLowMemOffsetValue* iDefaultVisItems &&
+ iOriginalRearOffset > KMaxLowMemOffsetValue * iDefaultVisItems)
+ {
+ TInt freeMemory = 0;
+ HAL::Get( HALData::EMemoryRAMFree, freeMemory );
+ if ( freeMemory < KGlxUpperMemoryLimitForCacheSize &&
+ freeMemory > KGlxLowerMemoryLimitForCacheSize )
+ {
+ iFrontOffset = 2*iDefaultVisItems;
+ iRearOffset = 3*iDefaultVisItems;
+ }
+ else if ( freeMemory < KGlxLowerMemoryLimitForCacheSize )
+ {
+ iFrontOffset = iDefaultVisItems;
+ iRearOffset = iDefaultVisItems;
+ }
+ else if (iFrontOffset != iOriginalFrontOffset
+ && iRearOffset!= iOriginalRearOffset)
+ {
+ iFrontOffset = Max(iFrontOffset, iOriginalFrontOffset );
+ iRearOffset = Max(iRearOffset, iOriginalRearOffset );
+ }
+ }
+
+ // Check if out of bounds
+ if (iFrontOffset + iRearOffset < iCurrentItem || count <= iCurrentItem)
+ {
+ return KErrNotFound;
+ }
+
+ // The ranges may be inequal, which means there won't be any jumping between
+ // front and rear.
+
+ // |-------F----------------------|
+ // |< jumping zone>|
+
+ TInt visIndex = iList->VisibleWindowIndex();
+ TInt index = visIndex;
+ TInt listCount = iList->Count();
+ __ASSERT_ALWAYS( index >= 0 && index <= listCount, Panic( EGlxPanicIllegalState ) );
+ //Inorder to ensure that the start of refresh of thumbnails is contained in
+ //in the current visible window. We set the startIndex to center element of
+ //the current visible window.
+ TInt startIndex = index + iDefaultVisItems/2;
+ if (listCount < iDefaultVisItems)
+ {
+ startIndex = listCount/2;
+ }
+
+ index = ( (startIndex) <= (listCount)) ? startIndex : listCount;
+
+ TInt min = Min(iFrontOffset, iRearOffset);
+ TInt jumpingZoneLength = min * 2;
+ if (iCurrentItem <= jumpingZoneLength)
+ {
+ // Still within the (rear-front-rear-front) jumping zone
+ TInt distanceFromFocus = (iCurrentItem + 1) / 2;
+ TBool rear = !(iCurrentItem & 1); // Rear if number is even
+ // Check if out of bounds
+ if (rear)
+ {
+ if (index - distanceFromFocus <= visIndex - iRearOffset)
+ {
+ return KErrNotFound;
+ }
+ index -= distanceFromFocus;
+ }
+ else
+ {
+ if (index + distanceFromFocus >= visIndex + iFrontOffset)
+ {
+ return KErrNotFound;
+ }
+ index += distanceFromFocus;
+ }
+ }
+ else
+ {
+ __ASSERT_DEBUG(iFrontOffset != iRearOffset, Panic(EGlxPanicLogicError));
+
+ // index is currently visible index. Figure out how much need to move.
+ TInt indexesFromFocus = iCurrentItem - min;
+ if (iRearOffset < iFrontOffset)
+ {
+ // Front range is longer than rear, so the item is on the front side
+ index += indexesFromFocus;
+ }
+ else
+ {
+ // Rear range is longer than front, so the item is on the rear side
+ index -= indexesFromFocus;
+ }
+ }
+
+ iCurrentItem++;
+
+ // The index may be below 0 or above count. Normalise back to list indexes.
+ return GlxListUtils::NormalizedIndex(index, count);
+ }
+
+// -----------------------------------------------------------------------------
+// Return ETrue if index is within range, EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool TGlxFromManualIndexBlockyIterator::InRange(TInt aIndex) const
+ {
+ TRACER("TGlxFromManualIndexBlockyIterator::InRange");
+ TInt count = iList->Count();
+
+ // Handle the case where range is longer than count separately, because looping will
+ // confuse otherwise
+ if (count <= iRearOffset + iFrontOffset)
+ {
+ // Range is longer than count, must be in range
+ return ETrue;
+ }
+
+ TInt index = iList->VisibleWindowIndex();
+ __ASSERT_ALWAYS( index >= 0 && index < iList->Count(), Panic( EGlxPanicIllegalState ) );
+
+ TInt firstInRange = GlxListUtils::NormalizedIndex(index - iRearOffset, count);
+ TInt lastInRange = GlxListUtils::NormalizedIndex(index + iFrontOffset, count);
+
+ if (firstInRange <= lastInRange)
+ {
+ // Normal case: | F-------L |
+ return aIndex >= firstInRange && aIndex <= lastInRange;
+ }
+ else
+ {
+ // Looping case: |----L F----|
+ return aIndex <= lastInRange || aIndex >= firstInRange;
+ }
+ }