--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/medialists/src/glxthumbnailcontext.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,685 @@
+/*
+* 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: Fetch context to retrieve thumbnails
+*
+*/
+
+
+
+
+
+#include <mpxmediadrmdefs.h>
+#include <glxresolutionutility.h>
+#include <glxdrmutility.h>
+#include <glxthumbnailattributeinfo.h>
+#include <mpxmediacollectiondetaildefs.h> // for KMPXMediaColDetailSpaceId
+#include <glxtracer.h>
+#include <glxlog.h>
+
+#include "glxattributecontext.h"
+#include "glxthumbnailcontext.h"
+#include "glxmedialist.h"
+#include "glxerrormanager.h"
+#include "glxthumbnailutility.h"
+#include "mglxcache.h"
+#include "glxlistutils.h"
+
+/**
+ * Scoring for thumbnail provision order
+ * Having no thumbnail is the most important, so it gets the highest bit
+ * Proximity to focus is the final (lowest priority) criteria)
+ */
+const TUint KTNScoreNoThumbnail = 0x80000000;
+// bits 0 to 24 are reserved for distance from focus (excessive, but free...)
+const TUint KTNScoreMaxForDistanceFromFocus = 0x00FFFFFF;
+
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxThumbnailContext* CGlxThumbnailContext::NewL(MGlxMediaListIterator*
+ aIterator)
+ {
+ TRACER( "CGlxThumbnailContext::NewL");
+
+ CGlxThumbnailContext* self = new(ELeave)CGlxThumbnailContext(aIterator);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxThumbnailContext::CGlxThumbnailContext(MGlxMediaListIterator* aIterator) :
+ iIterator(aIterator)
+ {
+ TRACER( "CGlxThumbnailContext::CGlxThumbnailContext");
+
+ __ASSERT_DEBUG(aIterator, Panic(EGlxPanicNullPointer));
+ }
+
+// -----------------------------------------------------------------------------
+// ConstructL (2nd phase construction)
+// -----------------------------------------------------------------------------
+//
+void CGlxThumbnailContext::ConstructL()
+ {
+ TRACER( "CGlxThumbnailContext::ConstructL");
+
+ iCache = MGlxCache::InstanceL();
+ iResolutionUtility = CGlxResolutionUtility::InstanceL();
+ iResolutionUtility->AddObserverL( *this );
+
+ iDrmUtility = CGlxDRMUtility::InstanceL();
+
+ // create attribute context for DRM attributes
+ iDrmFetchContext = new (ELeave) CGlxAttributeContext(iIterator);
+ iDrmFetchContext->AddAttributeL(KMPXMediaDrmProtected);
+#ifdef RD_MDS_2_5
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralDRMRightsValid);
+#endif
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralCategory);
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralUri);
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralSize);
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralLastModifiedDate);
+ // add size attribute
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralDimensions);
+ // add to speed up details retrieval
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralTitle);
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralDate);
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralDrive);
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralFramecount);
+ //Need to implement IdSpaceId() functionality.
+ iDrmFetchContext->AddAttributeL(KMPXMediaColDetailSpaceId);
+ // Attributes required to launch Options
+ iDrmFetchContext->AddAttributeL(KMPXMediaGeneralMimeType);
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralLocation);
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralSystemItem);
+ iDrmFetchContext->AddAttributeL(KGlxMediaGeneralSlideshowableContent);
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxThumbnailContext::~CGlxThumbnailContext()
+ {
+ TRACER( "CGlxThumbnailContext::~CGlxThumbnailContext");
+
+ delete iDrmFetchContext;
+
+ if ( iDrmUtility )
+ {
+ iDrmUtility->Close();
+ }
+
+ iSpecs.Close();
+
+ if ( iResolutionUtility )
+ {
+ iResolutionUtility->RemoveObserver( *this );
+ iResolutionUtility->Close();
+ }
+
+ if ( iCache )
+ {
+ iCache->Close();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Adds a new fetch specification for an item
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxThumbnailContext::AddSpecForItemL(
+ TInt aWidth, TInt aHeight, TInt aFocusOffset )
+ {
+ TRACER( "CGlxThumbnailContext::AddSpecForItemL");
+
+ TReal32 width( aWidth );
+ TReal32 height( aHeight );
+
+ TAssignedFetchSpec spec;
+ spec.iPossWidth = iResolutionUtility->PixelsToPoss( width );
+ spec.iPossHeight = iResolutionUtility->PixelsToPoss( height );
+ spec.iFocusOffset = aFocusOffset;
+
+ // Has this focus index has already been added?
+ #ifdef _DEBUG
+ TIdentityRelation<TAssignedFetchSpec> match (&TAssignedFetchSpec::Match);
+ #endif
+ __ASSERT_DEBUG(iSpecs.Find(spec, match) == KErrNotFound, Panic(EGlxPanicAlreadyAdded));
+
+ iSpecs.AppendL(spec);
+ }
+
+// -----------------------------------------------------------------------------
+// Sets the default fetch specification
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxThumbnailContext::SetDefaultSpec(TInt aWidth, TInt aHeight)
+ {
+ TRACER( "CGlxThumbnailContext::SetDefaultSpec");
+
+ iDefaultSpecSize = TSize(aWidth, aHeight);
+
+ TReal32 width( aWidth );
+ TReal32 height( aHeight );
+
+ iDefaultSpec.iPossWidth = iResolutionUtility->PixelsToPoss( width );
+ iDefaultSpec.iPossHeight = iResolutionUtility->PixelsToPoss( height );
+ }
+
+// ---------------------------------------------------------------------------
+// SetHighQualityOnly
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGlxThumbnailContext::SetHighQualityOnly(
+ TBool aHighQualityOnly )
+ {
+ TRACER( "CGlxThumbnailContext::SetHighQualityOnly");
+
+ iHighQualityOnly = aHighQualityOnly;
+ }
+
+// -----------------------------------------------------------------------------
+// Get all attributes required for the item (whether the are fetched or not)
+// From MGlxFetchContext
+// -----------------------------------------------------------------------------
+//
+void CGlxThumbnailContext::AllAttributesL(const MGlxMediaList* aList, TInt aListIndex,
+ RArray<TMPXAttribute>& aAttributes) const
+ {
+ TRACER( "CGlxThumbnailContext::AllAttributesL");
+
+ if (!iIterator)
+ {
+ return;
+ }
+
+ // add attributes from owned attribute context
+ iDrmFetchContext->AllAttributesL(aList,aListIndex, aAttributes);
+
+ // No requests outside range
+ iIterator->SetToFirst(aList);
+ if (!iIterator->InRange(aListIndex))
+ {
+ return;
+ }
+ TBool drmValid = EFalse;
+ TSize size = iDefaultSpecSize;
+ const TGlxMedia& item( aList->Item( aListIndex ) );
+ if( item.GetDrmProtected(drmValid) && drmValid)
+ {
+ drmValid = CheckDRMStatusL( aListIndex, aList, size );
+ }
+
+ TLinearOrder<TMPXAttribute> orderer (&CGlxMediaList::AttributeOrder);
+ // Always want high quality thumbnail
+ TMPXAttribute attr( KGlxMediaIdThumbnail,
+ GlxFullThumbnailAttributeId( ETrue, size.iWidth, size.iHeight ) );
+ aAttributes.InsertInOrderAllowRepeatsL( attr , orderer);
+
+ // If don't have high quality thumbnail, find closest available thumbnail
+
+ const CGlxMedia* properties = item.Properties();
+ if ( properties && !properties->IsSupported( attr ) )
+ {
+ TMPXAttribute attr2;
+
+ if ( item.GetClosestThumbnail( attr2, size, drmValid ) )
+ {
+ aAttributes.InsertInOrderAllowRepeatsL( attr2 , orderer );
+ }
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// Get attributes request for the item
+// From MGlxFetchContext
+// -----------------------------------------------------------------------------
+//
+TInt CGlxThumbnailContext::AttributeRequestL(const MGlxMediaList* aList,
+ RArray<TInt>& aItemIndices, RArray<TMPXAttribute>& aAttributes,
+ CMPXAttributeSpecs*& aDetailedSpecs) const
+ {
+ TRACER( "CGlxThumbnailContext::AttributeRequestL");
+
+ // Fetch the visible items attribs & thumbnail first.
+ TInt error = KErrNone;
+ TInt listIndex = SelectItemL(aList, error);
+ if ((listIndex >= 0 && aList->Item(listIndex).Uri().Length() == 0) ||
+ aList->Count() <= GlxListUtils::VisibleItemsGranularityL())
+ {
+ TInt reqCount = iDrmFetchContext->AttributeRequestL(aList,
+ aItemIndices, aAttributes, aDetailedSpecs);
+
+ // if owned context requires DRM atributes need to request those 1st
+ if ( reqCount != 0 )
+ {
+ GLX_DEBUG2("CGlxThumbnailContext::AttributeRequestL() reqCount=%d", reqCount);
+ return reqCount;
+ }
+ }
+
+ // Select an item to process
+ error = KErrNone;
+ listIndex = SelectItemL(aList, error);
+ if (KErrNotFound != listIndex)
+ {
+ GLX_DEBUG2("CGlxThumbnailContext::AttributeRequestL() listIndex=%d", listIndex);
+ const TGlxMedia& item = aList->Item( listIndex );
+ TSize size = iDefaultSpecSize;
+
+ TBool drmValid = EFalse;
+ if( item.GetDrmProtected(drmValid) && drmValid)
+ {
+ CheckDRMStatusL( listIndex, aList, size );
+ }
+
+ // Request high quality thumbnail if already have any thumbnail
+ TBool quality = iHighQualityOnly
+ || HasFullThumbnail( aList->Item( listIndex ) );
+
+ GLX_DEBUG2("CGlxThumbnailContext::AttributeRequestL() quality=%d", quality);
+ TMPXAttribute attr( KGlxMediaIdThumbnail,
+ GlxFullThumbnailAttributeId(
+ quality, size.iWidth, size.iHeight ) );
+
+ aAttributes.AppendL(attr);
+
+ aItemIndices.AppendL(listIndex);
+
+ // Allocate CMPXAttributeSpecs
+ CMPXAttributeSpecs* attributeSpecs = CMPXAttributeSpecs::NewL();
+ CleanupStack::PushL(attributeSpecs);
+
+ attributeSpecs->SetTObjectValueL(
+ TMPXAttribute( KGlxMediaIdThumbnail,
+ KGlxAttribSpecThumbnailSize ), size );
+
+ attributeSpecs->SetTObjectValueL(
+ TMPXAttribute( KGlxMediaIdThumbnail,
+ KGlxAttribSpecThumbnailQualityOverSpeed ), quality );
+
+
+ aDetailedSpecs = attributeSpecs;
+
+ // Pop from stack
+ CleanupStack::Pop(attributeSpecs);
+ }
+ else
+ {
+ // If an error was found, return KErrGeneral
+ if (error != KErrNone)
+ {
+ return KErrGeneral;
+ }
+ }
+
+ return aItemIndices.Count();
+ }
+
+// -----------------------------------------------------------------------------
+// Number of current requests
+// From MGlxFetchContext
+// -----------------------------------------------------------------------------
+TInt CGlxThumbnailContext::RequestCountL(const MGlxMediaList* aList) const
+ {
+ TRACER( "CGlxThumbnailContext::RequestCountL");
+
+ RArray<TInt> itemIndices;
+ CleanupClosePushL(itemIndices);
+
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL(attributes);
+
+ CMPXAttributeSpecs* attrSpecs = NULL;
+
+ TInt requestCount = AttributeRequestL(aList, itemIndices, attributes, attrSpecs);
+
+ delete attrSpecs;
+
+ CleanupStack::PopAndDestroy(&attributes);
+ CleanupStack::PopAndDestroy(&itemIndices);
+
+ return requestCount;
+ }
+
+// -----------------------------------------------------------------------------
+// HandleResolutionChanged
+// -----------------------------------------------------------------------------
+//
+void CGlxThumbnailContext::HandleResolutionChangedL()
+ {
+ TRACER( "CGlxThumbnailContext::HandleResolutionChanged");
+
+ // Ask cache manager to refresh, to fetch thumbnails in new size
+ iCache->RefreshL();
+ }
+
+// -----------------------------------------------------------------------------
+// SelectItemL
+// -----------------------------------------------------------------------------
+//
+TInt CGlxThumbnailContext::SelectItemL(const MGlxMediaList* aList, TInt& aError) const
+ {
+ TRACER( "CGlxThumbnailContext::SelectItemL");
+
+ // Order of priorities when selecting the item: (highest priority rule first)
+ // Items with no thumbnail before items with thumbnail
+ // Items closer to the focus before
+
+ TInt count = aList->Count();
+ if (0 == count || !iIterator)
+ {
+ return KErrNotFound;
+ }
+
+ // Iterate through range from iterator in search of the highest scoring thumbnail
+ TUint bestScore = 0;
+ TInt bestIndex = KErrNotFound;
+ iIterator->SetToFirst(aList);
+ TInt distanceFromFirst = 0;
+ TInt i;
+ while (KErrNotFound != (i = (*iIterator)++))
+ {
+ // Calculate the score for this item
+ TUint score = GetThumbnailScoreL(i, aList, distanceFromFirst, aError);
+ __ASSERT_DEBUG(score != bestScore || score == 0, Panic(EGlxPanicLogicError)); // For safety, cannot allow two items with the same score
+ if (score > bestScore)
+ {
+ bestScore = score;
+ bestIndex = i;
+ }
+
+ distanceFromFirst++;
+ }
+
+ return bestIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// GetThumbnailScoreL
+// -----------------------------------------------------------------------------
+//
+TUint CGlxThumbnailContext::GetThumbnailScoreL(TInt aListIndex, const MGlxMediaList* aList,
+ TInt aDistance, TInt& aError) const
+ {
+ TRACER( "CGlxThumbnailContext::GetThumbnailScoreL");
+
+ const TGlxMedia& item = aList->Item(aListIndex);
+ const CGlxMedia* properties = item.Properties();
+
+ // Check for the static item in the list.
+ // defualt icons needs to be displayed for static items.
+ if(item.IsStatic())
+ {
+ return 0;
+ }
+
+ TBool thumbnail = HasFullThumbnail( item );
+ TUint score = 0;
+
+ if ( properties )
+ {
+ TSize size = iDefaultSpecSize;
+
+ TBool drmValid = EFalse;
+ if( item.GetDrmProtected(drmValid) && drmValid)
+ {
+ CheckDRMStatusL( aListIndex, aList, size );
+ }
+
+ // Want high quality thumbnail if already have any thumbnail
+ TBool quality = iHighQualityOnly || thumbnail;
+ TMPXAttribute attr( KGlxMediaIdThumbnail,
+ GlxFullThumbnailAttributeId(
+ quality, size.iWidth, size.iHeight ) );
+
+ // Items that are "perfect" are skipped
+ if ( quality && properties->IsSupported( attr ) )
+ {
+ return 0;
+ }
+
+ // Items for which fetching thumbnail failed are skipped
+ TInt error = GlxErrorManager::HasAttributeErrorL( properties, attr );
+ if ( error != KErrNone )
+ {
+ aError = error;
+ return 0;
+ }
+ }
+
+ // Score on not having any thumbnail
+ if ( !thumbnail )
+ {
+ score |= KTNScoreNoThumbnail;
+ }
+
+ // Score on proximity to focus
+ score |= KTNScoreMaxForDistanceFromFocus - aDistance; // More distance, less points
+
+ __ASSERT_DEBUG(score != 0, Panic(EGlxPanicLogicError));
+
+ return score;
+ }
+
+// -----------------------------------------------------------------------------
+// SpecForIndex
+// -----------------------------------------------------------------------------
+//
+const CGlxThumbnailContext::TFetchSpec& CGlxThumbnailContext::SpecForIndex(
+ TInt aListIndex, const MGlxMediaList* aList) const
+ {
+ TRACER( "CGlxThumbnailContext::SpecForIndex");
+
+ __ASSERT_DEBUG(aList, Panic(EGlxPanicNullPointer));
+
+ TInt count = aList->Count();
+ TInt offset = Abs(aListIndex - aList->FocusIndex());
+
+ if ( offset > count / 2 )
+ {
+ offset = count - offset;
+ }
+
+ // Use specific context if one exists
+ TAssignedFetchSpec spec;
+ spec.iFocusOffset = offset;
+ TInt index = iSpecs.Find(spec, TAssignedFetchSpec::Match);
+ if ( KErrNotFound != index )
+ {
+ return iSpecs[index];
+ }
+
+ return iDefaultSpec;
+ }
+
+// ---------------------------------------------------------------------------
+// SizeFromSpec
+// ---------------------------------------------------------------------------
+//
+TSize CGlxThumbnailContext::SizeFromSpec( const TFetchSpec& aSpec ) const
+ {
+ TRACER( "CGlxThumbnailContext::SizeFromSpec");
+
+ TReal32 width = iResolutionUtility->PossToPixels( aSpec.iPossWidth );
+ TReal32 height = iResolutionUtility->PossToPixels( aSpec.iPossHeight );
+
+ // Round to the nearest integers
+ return TSize( width + 0.5F, height + 0.5F );
+ }
+
+// -----------------------------------------------------------------------------
+// Compares two specs by focus offset.
+// -----------------------------------------------------------------------------
+//
+TBool CGlxThumbnailContext::TAssignedFetchSpec::Match(
+ const TAssignedFetchSpec& aSpec1, const TAssignedFetchSpec& aSpec2 )
+ {
+ TRACER( "CGlxThumbnailContext::TAssignedFetchSpec::Match");
+
+ return aSpec1.iFocusOffset == aSpec2.iFocusOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// HasFullThumbnail
+// -----------------------------------------------------------------------------
+//
+TBool CGlxThumbnailContext::HasFullThumbnail( const TGlxMedia& aItem ) const
+ {
+ TRACER( "CGlxThumbnailContext::HasFullThumbnail");
+
+ const CGlxMedia* properties = aItem.Properties();
+
+ if ( properties )
+ {
+ TInt count = properties->Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( GlxThumbnailUtility::IsFullThumbnail(
+ properties->Attribute( i ) ) )
+ {
+ return ETrue;
+ }
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// Check DRM status of specified item
+// -----------------------------------------------------------------------------
+//
+TBool CGlxThumbnailContext::CheckDRMStatusL( TInt aListIndex,
+ const MGlxMediaList* aList, TSize& aSize ) const
+ {
+ TRACER( "CGlxThumbnailContext::CheckDRMStatusL");
+
+ const TGlxMedia& item = aList->Item( aListIndex );
+ TBool valid = EFalse;
+
+ aSize = SizeFromSpec( SpecForIndex( aListIndex, aList ) );
+
+ TGlxMediaGeneralRightsValidity isValid = EGlxDrmRightsValidityUnknown;
+ item.GetDrmValidity(isValid);
+ if ( EGlxDrmRightsValidityUnknown == isValid )
+ {
+ // check rights
+ TMPXGeneralCategory cat = item.Category();
+ const TDesC& uri = item.Uri();
+ if ( uri.Length() && cat != EMPXNoCategory )
+ {
+ valid = iDrmUtility->CheckOpenRightsL( uri, ( cat == EMPXImage ) );
+ CGlxMedia* properties = const_cast<CGlxMedia*>(item.Properties());
+ if( valid )
+ {
+
+ isValid = EGlxDrmRightsValid;
+ }
+ else
+ {
+
+ isValid = EGlxDrmRightsInvalid;
+ }
+ properties->SetTObjectValueL(KGlxMediaGeneralDRMRightsValid, isValid);
+ }
+ }
+ else if ( EGlxDrmRightsValid == isValid )
+ {
+ valid = ETrue;
+ }
+ if ( !valid )
+ {
+ // modify spec to request 'small' thumbnail
+ TSize size;
+ // ignore success/failure return - accept default
+ item.GetDimensions(size);
+
+ TSize thumbnailSize = iDrmUtility->DRMThumbnailSize( size );
+
+ // only update spec if either dimension of required DRM thumbnail
+ // is smaller than correspnding spec dimension (so don't request
+ // a new thumbnail if existing one if of appropriate size )
+ if( thumbnailSize.iWidth < aSize.iWidth
+ || thumbnailSize.iHeight < aSize.iHeight )
+ {
+ aSize = thumbnailSize;
+ }
+ }
+ return valid;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// CGlxDefaultThumbnailContext
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+
+// -----------------------------------------------------------------------------
+// NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxDefaultThumbnailContext* CGlxDefaultThumbnailContext::NewL()
+ {
+ TRACER( "CGlxDefaultThumbnailContext::NewL");
+
+ CGlxDefaultThumbnailContext* obj = new (ELeave) CGlxDefaultThumbnailContext();
+ CleanupStack::PushL(obj);
+ obj->ConstructL();
+ CleanupStack::Pop(obj);
+ return obj;
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// Sets the iterator of base class to be TGlxFromFocusOutwardIterator
+// -----------------------------------------------------------------------------
+//
+CGlxDefaultThumbnailContext::CGlxDefaultThumbnailContext() :
+ CGlxThumbnailContext(&iFromFocusIterator)
+ {
+ TRACER( "CGlxDefaultThumbnailContext::CGlxDefaultThumbnailContext");
+
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxDefaultThumbnailContext::~CGlxDefaultThumbnailContext()
+ {
+ TRACER( "CGlxDefaultThumbnailContext::~CGlxDefaultThumbnailContext");
+
+ }
+
+// ----------------------------------------------------------------------------
+// Set range offsets
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxDefaultThumbnailContext::SetRangeOffsets(TInt aFrontOffset, TInt aRearOffset)
+ {
+ TRACER( "CGlxDefaultThumbnailContext::SetRangeOffsets");
+
+ iFromFocusIterator.SetRangeOffsets(aFrontOffset, aRearOffset);
+ }