diff -r 4ea6f81c838a -r 0e9bb658ef58 mulwidgets/muldatamodel/src/mulpullmode.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mulwidgets/muldatamodel/src/mulpullmode.cpp Wed Sep 01 12:23:18 2010 +0100 @@ -0,0 +1,467 @@ +/* +* Copyright (c) 2007-2008 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: Implementation of Pull Mode +* +*/ + + +//Includes +#include "mulpullmode.h" + +#include + + +#include "mulassert.h" +#include "mulcachemanager.h" +#include "muldatawindow.h" +#include "mulpagedatawindow.h" +#include "mul/mulmodelutility.h" +#include "mullog.h" +#include "mulasyncdataprovider.h" + +namespace Alf + { + +// --------------------------------------------------------------------------- +// MulPullMode() +// --------------------------------------------------------------------------- +// +MulPullMode::MulPullMode(MulPageDataWindow& aDataWindow, + const IMulModelProvider& aModelProvider) + :MulPushMode( aDataWindow ) + { + //mModelProvider = const_cast( &aModelProvider ); + MUL_LOG_ENTRY_EXIT("MUL::MulPullModeImpl::MulPullModeImpl()"); + mModelProvider.reset( new (ELeave) MulAsyncDataProvider( const_cast(aModelProvider), aDataWindow )); + } + +// --------------------------------------------------------------------------- +// ~MulPullMode() +// --------------------------------------------------------------------------- +// +MulPullMode::~MulPullMode() + { + // No implementation is required. + MUL_LOG_ENTRY_EXIT("MUL::MulPullModeImpl::~MulPullModeImpl()"); + } + +// ------------------------ From IMulModel ----------------------------------- + +// --------------------------------------------------------------------------- +// Update +// --------------------------------------------------------------------------- +// +void MulPullMode::Update(int aIndex, int aCount, const MulDataPath& /*aPath*/) + { + // throw exception if index is out of bound + __MUL_ASSERT( aIndex >= 0 && aCount > 0 && aIndex+aCount <= mCacheManager->ExpandedNodeCount(), KLInvalidArgument ); + + int startIndex = aIndex; + int range = 0; + bool firstTime = true; + for(int i = aIndex; i < aCount+aIndex ; ++i) + { + if( mDataWindow.IsItemInDataWindow(i) ) + { + range++; + firstTime = true; + } + else + { + if(firstTime) + { + firstTime = false; + if(range>0) + { + ProvideData(startIndex,range); + range = 0; + } + } + startIndex = i + 1; + } + } + ProvideData(startIndex,range); + } + +// --------------------------------------------------------------------------- +// Refresh +// --------------------------------------------------------------------------- +// +void MulPullMode::Refresh( int aCount, const MulDataPath& aPath ) + { + int modelCountBefore = mCacheManager->ExpandedNodeCount(); + + // remove all old nodes + for(int currentIndex = 0; currentIndex < modelCountBefore; currentIndex++) + { + mCacheManager->RemoveVisualItem(aPath,0); + } + + //mCacheManager->RemoveVisalItem(0, aCount, aPath ); + + // insert new nodes + mCacheManager->CreateNodes( 0, aCount, aPath ); + + int modelCount = mCacheManager->ExpandedNodeCount(); + // update alf model accordingly + if(mDataWindow.IsWindowEnabled()) + { + if(modelCountBefore == modelCount) + { + Update(0,aCount,aPath); + } + else + { + ModelCountChanged(modelCountBefore,modelCount); + } + } + } + +// --------------------------------------------------------------------------- +// SetData +// --------------------------------------------------------------------------- +// +void MulPullMode::SetData(int aIndex, auto_ptr aVisualItem,const MulDataPath& aPath) + { + MUL_LOG_ENTRY_EXIT("MUL::MulPullModeImpl::SetData()"); + + __MUL_ASSERT( aIndex >= 0 && aIndex < Count(aPath),_L("Invalid Argument.")); + + //Set data to model + if( mDataWindow.IsItemInDataWindow( aIndex ) ) + { + MulPushMode::SetData( aIndex, aVisualItem, aPath ); + } + } + +// --------------------------------------------------------------------------- +// SetTemplate +// --------------------------------------------------------------------------- +// +void MulPullMode::SetTemplate( mulwidget::TLogicalTemplate aTemplateId ) + { + mDefaultTemplate = aTemplateId; + + MulDataPath path ; + if( mDataWindow.IsWindowEnabled() ) + { + int topOffset = mDataWindow.TopOffset(); + int bottomOffset = mDataWindow.BottomOffset(); + for( int i = topOffset ; i <= bottomOffset ; i++ ) + { + MulPushMode::SetTemplate( i, mDefaultTemplate, path); + } + + int rearTopOffset = mDataWindow.RearTopOffset(); + int rearBottomOffset = mDataWindow.RearBottomOffset(); + for( int i = rearTopOffset; i <= rearBottomOffset && i >= 0 ; i++ ) + { + MulPushMode::SetTemplate( i, mDefaultTemplate, path); + } + } + } + +// --------------------------------------------------------------------------- +// WindowSiftedDown +// --------------------------------------------------------------------------- +// +void MulPullMode::WindowSiftedDown() + { + MUL_LOG_ENTRY_EXIT("MUL::MulPullModeImpl::WindowSiftedDown"); + + // If the complete datawindow is invalid. +// if(mDataWindow.TopOffset() - mDataWindow.OldTopOffset() > mDataWindow.ActualBufferSize() +// && mDataWindow.OldTopOffset() != KNotInitialized) + //if(mDataWindow.TopOffset() - mDataWindow.OldTopOffset() > mDataWindow.ActualBufferSize() ) + int oldTopOffset = mDataWindow.OldTopOffset(); + int oldBottomOffset = mDataWindow.OldBottomOffset(); + int topOffset = mDataWindow.TopOffset(); + int bottomOffset = mDataWindow.BottomOffset(); + int oldRearTopOffset = mDataWindow.OldRearTopOffset(); + int oldRearBottomOffset = mDataWindow.OldRearBottomOffset(); + + if( ( oldTopOffset == KNotInitialized && oldBottomOffset == KNotInitialized ) || + ( topOffset - oldTopOffset >= mDataWindow.ActualBufferSize()) || + ( oldRearTopOffset != KNotInitialized && + ( topOffset - oldTopOffset >= ( mDataWindow.WindowSize() + mDataWindow.BufferSize() ) ) + ) ) + { + //remove old data from cache + for( int i = oldTopOffset ; i <= oldBottomOffset && i >= 0 ; i++ ) + { + mCacheManager->RemoveVisualItem( i ); + } + + for( int i = oldRearTopOffset; i <= oldRearBottomOffset && i >= 0 ; i++ ) + { + mCacheManager->RemoveVisualItem( i ); + } + + int startIndex = topOffset; + int range = bottomOffset - startIndex + 1; + + MUL_LOG_INFO2("MUL::MulPullModeImpl::WindowSiftedUp ProvideData startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + else + { + //remove extra items from top and add new items at bottom + for( int i = oldTopOffset ; i >= 0 && i < topOffset ; i++ ) + { + //remove item from top + mCacheManager->RemoveVisualItem( i ); + } + + int startIndex = oldBottomOffset +1 ; + int range = ( bottomOffset - oldBottomOffset ); + MUL_LOG_INFO2("MUL::MulPullModeImpl::DataWindowUpdated ProvideData startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + } + +// --------------------------------------------------------------------------- +// WindowSiftedUp +// --------------------------------------------------------------------------- +// +void MulPullMode::WindowSiftedUp() + { + MUL_LOG_ENTRY_EXIT("MUL::MulPullModeImpl::WindowSiftedUp "); + // If the complete datawindow is invalid. +// if(mDataWindow.OldBottomOffset() - mDataWindow.BottomOffset() > mDataWindow.ActualBufferSize() +// && mDataWindow.OldBottomOffset() != KNotInitialized) + + if( mDataWindow.OldBottomOffset() - mDataWindow.BottomOffset() >= mDataWindow.ActualBufferSize() || + ( mDataWindow.OldRearBottomOffset() != KNotInitialized && + ( mDataWindow.OldBottomOffset() - mDataWindow.BottomOffset() >= ( mDataWindow.WindowSize() + mDataWindow.BufferSize() ) ) + ) ) + { + //remove old data from cache + for( int i = mDataWindow.OldTopOffset() ; i <= mDataWindow.OldBottomOffset() && i >= 0 ; i++ ) + { + mCacheManager->RemoveVisualItem( i ); + } + + for( int i = mDataWindow.OldRearTopOffset( ); i <= mDataWindow.OldRearBottomOffset() && i >= 0 ; i++ ) + { + mCacheManager->RemoveVisualItem( i ); + } + + int startIndex = mDataWindow.TopOffset(); + int range = mDataWindow.BottomOffset() - startIndex + 1; + + MUL_LOG_INFO2("MUL::MulPullModeImpl::WindowSiftedUp ProvideData startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + else + { + //remove extra items from bottom and add at top + for( int i = mDataWindow.BottomOffset() ; i < mDataWindow.OldBottomOffset() ; i++ ) + { + mCacheManager->RemoveVisualItem(i+1); + } + + int startIndex = mDataWindow.TopOffset(); + int range = mDataWindow.OldTopOffset() - mDataWindow.TopOffset(); + + MUL_LOG_INFO2("MUL::MulPullModeImpl::WindowSiftedUp ProvideData startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + } + +// --------------------------------------------------------------------------- +// ProvideData +// --------------------------------------------------------------------------- +// +void MulPullMode::ProvideData(int aStartIndex, int aRange) + { + //call provide data for visible window first then for buffer + if( aRange > 0 ) + { + // check if the current higlighted item is there in the data asked for + if( mDataWindow.Highlight() >= aStartIndex && + mDataWindow.Highlight() < aStartIndex+aRange ) + { + mModelProvider->ProvideData( mDataWindow.Highlight(), 1 ,MulDataPath(),true ); + } + //__MUL_ASSERT( ( aRange % 18 ) == 0, _L("Invalid Renage") ); + //check that visible data is there in provide data call + if( aStartIndex < mDataWindow.TopWindowOffset() && + aStartIndex+aRange > mDataWindow.BottomWindowOffset() ) + { + { + //request visible item + int startIndex = mDataWindow.TopWindowOffset(); + int range = ( mDataWindow.BottomWindowOffset() - mDataWindow.TopWindowOffset() ) + 1 ; + + MUL_LOG_INFO2("MUL::MulPullModeImpl::ProvideData visible buffer startIndex:%d,range:%d",startIndex,range); + mModelProvider->ProvideData(startIndex, range ,MulDataPath() ); + } + + { + //request item from top + int startIndex = aStartIndex; + int range = mDataWindow.TopWindowOffset() - startIndex; + + MUL_LOG_INFO2("MUL::MulPullModeImpl::ProvideData top buffer startIndex:%d,range:%d",startIndex,range); + mModelProvider->ProvideData(startIndex, range ,MulDataPath() ); + } + + { + //request item from bottom + int startIndex = mDataWindow.BottomWindowOffset() + 1 ; + int range = ( aStartIndex + aRange - 1) - mDataWindow.BottomWindowOffset(); + + MUL_LOG_INFO2("MUL::MulPullModeImpl::ProvideData bottom buffer startIndex:%d,range:%d",startIndex,range); + mModelProvider->ProvideData(startIndex, range ,MulDataPath() ); + } + } + else + { + //there is not provide data pending for visible window + mModelProvider->ProvideData(aStartIndex, aRange ,MulDataPath() ); + } + } + } + +// --------------------------------------------------------------------------- +// ModelCountChanged +// --------------------------------------------------------------------------- +// +void MulPullMode::ModelCountChanged(int aOldCount, int aNewCount) + { + MUL_LOG_ENTRY_EXIT("MUL::MulPullMode::AdjustOffsetAndData()"); + + MUL_LOG_INFO1("MUL::MulPullMode::AdjustAlfModelData() modelCount:%d", aNewCount ); + + MulPushMode::ModelCountChanged( aOldCount, aNewCount ); + + // fetch data for the new buffers + if( mDataWindow.RearTopOffset() != KNotInitialized && + mDataWindow.RearBottomOffset() != KNotInitialized ) + { + if(mDataWindow.RearTopOffset() == 0) + { + //updating all buffer + ProvideData( mDataWindow.RearTopOffset() , mDataWindow.RearBottomOffset() - + mDataWindow.RearTopOffset() + 1); + + ProvideData( mDataWindow.TopOffset() , mDataWindow.BottomOffset() - + mDataWindow.TopOffset() + 1); + } + else + { + ProvideData( mDataWindow.TopOffset() , mDataWindow.BottomOffset() - + mDataWindow.TopOffset() + 1); + + ProvideData( mDataWindow.RearTopOffset() , mDataWindow.RearBottomOffset() - + mDataWindow.RearTopOffset() + 1); + } + } + else + { + ProvideData( mDataWindow.TopOffset() , mDataWindow.BottomOffset() - + mDataWindow.TopOffset() + 1); + } + } + +// --------------------------------------------------------------------------- +// DataWindowUpdated +// --------------------------------------------------------------------------- +// +void MulPullMode::DataWindowUpdated() + { + //here sequence of Function call are important dont change function call sequences + //UpdateLoopBuffer must be called first + if( mDataWindow.RearTopOffset() != KNotInitialized && + mDataWindow.OldRearTopOffset() != KNotInitialized ) //there is looping on + { + UpdateLoopBuffer(); + //returning from here only dont need to do any thing else + return ; + } + //window shifted down + if( mDataWindow.OldBottomOffset() < mDataWindow.BottomOffset() ) + { + WindowSiftedDown(); + } + //window shifted up + else if( mDataWindow.OldTopOffset() > mDataWindow.TopOffset()) + { + WindowSiftedUp(); + } + + //add buffer in looping case + if(mDataWindow.RearTopOffset() != KNotInitialized && mDataWindow.RearBottomOffset() != KNotInitialized) //rear offset changed + { + // here ask data from top to bottom + int startIndex = mDataWindow.RearTopOffset() ; + int range = mDataWindow.RearBottomOffset() - mDataWindow.RearTopOffset() + 1; + + MUL_LOG_INFO2("MUL::MulPullMode::DataWindowUpdated startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + } + +// --------------------------------------------------------------------------- +// UpdateLoopBuffer +// --------------------------------------------------------------------------- +// +void MulPullMode::UpdateLoopBuffer() + { + MUL_LOG_ENTRY_EXIT("MUL::MulPushMode::UpdateLoopBuffer"); + if( mDataWindow.RearTopOffset() < mDataWindow.OldRearTopOffset() ) + { + int startIndex = mDataWindow.TopOffset(); + int range = mDataWindow.OldRearTopOffset() - startIndex; + + MUL_LOG_INFO2("MUL::MulPushMode::UpdateLoopBuffer startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + else + { + int startIndex = mDataWindow.OldRearBottomOffset()+1 ; + int range = mDataWindow.BottomOffset() - startIndex + 1; + + MUL_LOG_INFO2("MUL::MulPushMode::UpdateLoopBuffer startIndex:%d,range:%d",startIndex,range); + ProvideData(startIndex,range); + } + } + +// --------------------------------------------------------------------------- +// Item +// --------------------------------------------------------------------------- +// +const MulVisualItem& MulPullMode::Item( int aAbsoluteIndex ) + { + MulVisualItem* visualItem = mCacheManager->Data( aAbsoluteIndex ); + if( !visualItem ) + { + if( mDataWindow.IsItemInDataWindow(aAbsoluteIndex) ) + { + std::auto_ptr dummyItem = MulModelUtility::CreateVisualItem( Template() ); + visualItem = dummyItem.get(); + mCacheManager->AddVisualItem(dummyItem, MulDataPath() ,aAbsoluteIndex ); + } + else + { + throw std::invalid_argument(KInvalidArgument); + } + } + return *visualItem; + } + + + } // namespace Alf + +//End of file