mulwidgets/muldatamodel/src/mulpullmode.cpp
branchRCL_3
changeset 26 0e9bb658ef58
parent 0 e83bab7cf002
--- /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 <mul/imulmodelprovider.h>
+
+
+#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<IMulModelProvider*>( &aModelProvider );
+	MUL_LOG_ENTRY_EXIT("MUL::MulPullModeImpl::MulPullModeImpl()");
+	mModelProvider.reset( new (ELeave) MulAsyncDataProvider( const_cast<IMulModelProvider&>(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<MulVisualItem> 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<MulVisualItem> 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