widgetmodel/alfwidgetmodel/src/alfmodel.cpp
changeset 17 3eca7e70b1b8
parent 3 4526337fb576
equal deleted inserted replaced
3:4526337fb576 17:3eca7e70b1b8
     1 /*
       
     2 * Copyright (c) 2006 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:   Model Class used by widgets.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 //INCLUDES 
       
    22 #include <alf/ialfmodelchangeobserver.h> 
       
    23 #include <osn/alfptrvector.h>
       
    24 #include <memory>
       
    25 
       
    26 #include <alf/alfmodel.h>
       
    27 #include "alf/alfmodeloperation.h"
       
    28 #include <alf/alfvarianttype.h>
       
    29 #include <alf/alfexceptions.h>
       
    30 //#include "alf/alfperf.h"
       
    31 #include <osn/osnnew.h>
       
    32 
       
    33 using osncore::AlfPtrVector;
       
    34 using std::auto_ptr;
       
    35 
       
    36 // Forward declared inside the Alf namespace
       
    37 namespace Alf
       
    38     {
       
    39     
       
    40     
       
    41 class AlfModelImpl
       
    42     {
       
    43 public :
       
    44 	AlfModelImpl():mDataSource(0)
       
    45 	    {
       
    46 	    }
       
    47 
       
    48 	~AlfModelImpl()
       
    49 	    {
       
    50         delete mDataSource;
       
    51 	    mObserverArray.clear();
       
    52 		}
       
    53 		
       
    54     /**
       
    55      * Array of Observers for the Model individual observers not owned
       
    56      */
       
    57     AlfPtrVector<IAlfModelChangeObserver> mObserverArray;
       
    58     
       
    59     /**
       
    60      * Data Source for the Model owned
       
    61      */ 
       
    62     IAlfVariantType* mDataSource;
       
    63     };
       
    64 
       
    65 
       
    66 ////////////////////// AlfModel //////////////////////
       
    67 
       
    68 // ============================ MEMBER FUNCTIONS ==============================
       
    69 
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // Description : Constructor - 
       
    73 // ---------------------------------------------------------------------------
       
    74 //
       
    75 OSN_EXPORT AlfModel::AlfModel()
       
    76     {
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // Description : Constructor - 
       
    81 // Data Source for the model is passed
       
    82 // ---------------------------------------------------------------------------
       
    83 //
       
    84 OSN_EXPORT AlfModel::AlfModel( IAlfVariantType* aDataSource )
       
    85     {
       
    86     mData.reset( new(EMM) AlfModelImpl() );
       
    87     mData->mDataSource  = aDataSource;  
       
    88     mData->mObserverArray.setAutoDelete(false);
       
    89     }
       
    90 
       
    91 // ---------------------------------------------------------------------------
       
    92 // Description : Class Destructor
       
    93 // ---------------------------------------------------------------------------
       
    94 //
       
    95 OSN_EXPORT AlfModel::~AlfModel()
       
    96     {
       
    97     }
       
    98 
       
    99 // ---------------------------------------------------------------------------
       
   100 // Description : Adds model change observers
       
   101 // ---------------------------------------------------------------------------
       
   102 //
       
   103 OSN_EXPORT void AlfModel::addModelChangeObserver(
       
   104     IAlfModelChangeObserver& aObserver)
       
   105     {
       
   106     if(mData->mObserverArray.findRef(&aObserver)<0)
       
   107     	{
       
   108 	    mData->mObserverArray.resize(mData->mObserverArray.count()+1);
       
   109 	    mData->mObserverArray.insert(mData->mObserverArray.count(),
       
   110 	                                 &aObserver);
       
   111     	aObserver.modelChanged( *this );
       
   112     	}
       
   113     }
       
   114     
       
   115     
       
   116     
       
   117 // ---------------------------------------------------------------------------
       
   118 // Description : Removes model change observers
       
   119 // ---------------------------------------------------------------------------
       
   120 //
       
   121 OSN_EXPORT void AlfModel::removeModelChangeObserver(
       
   122     IAlfModelChangeObserver& aObserver)
       
   123     {
       
   124     for ( int i = 0; i < mData->mObserverArray.count(); ++i )
       
   125     	{
       
   126     	if(mData->mObserverArray[i]==&aObserver)
       
   127     	 {
       
   128     	  mData->mObserverArray.remove( i );
       
   129 		  return;
       
   130     	 }
       
   131     	}
       
   132     }
       
   133 
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // Description : Sets the data for the model
       
   137 // ---------------------------------------------------------------------------
       
   138 //
       
   139 OSN_EXPORT void AlfModel::setData(IAlfVariantType* aData)
       
   140     {
       
   141     if( mData->mDataSource != 0 )
       
   142         {
       
   143         delete mData->mDataSource;
       
   144         mData->mDataSource=0;
       
   145         }
       
   146     mData->mDataSource = aData;
       
   147 
       
   148     for ( int i = 0; i < mData->mObserverArray.count(); ++i )
       
   149         {
       
   150         mData->mObserverArray[i]->modelChanged( *this );
       
   151         }
       
   152     }
       
   153 
       
   154 // ---------------------------------------------------------------------------
       
   155 // Description : Returns the Data Source
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 OSN_EXPORT IAlfVariantType* AlfModel::data() const
       
   159     {
       
   160     return  mData->mDataSource;
       
   161     }
       
   162 
       
   163 // ---------------------------------------------------------------------------
       
   164 // Description : notifies, that the model is changed.
       
   165 // ---------------------------------------------------------------------------
       
   166 //    
       
   167 OSN_EXPORT void AlfModel::notifyModelChanged()
       
   168     {
       
   169     //Notify all the observers
       
   170     for ( int i = 0; i < mData->mObserverArray.count(); ++i )
       
   171         {
       
   172         mData->mObserverArray[i]->modelChanged(*this);
       
   173         }    
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 // Description : Clears the Data Source
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 OSN_EXPORT void AlfModel::clearModel()
       
   181     {
       
   182     //Delete the Model
       
   183     if( mData->mDataSource != 0 )
       
   184         {
       
   185         delete mData->mDataSource;
       
   186         mData->mDataSource=0;        
       
   187         }
       
   188     //Notify all the observers
       
   189     for ( int i = 0; i < mData->mObserverArray.count(); ++i )
       
   190         {
       
   191         mData->mObserverArray[i]->modelChanged(*this);
       
   192         }
       
   193     }
       
   194 
       
   195 // ---------------------------------------------------------------------------
       
   196 // From class IAlfInterfaceBase.
       
   197 // Static getter for interfaces provided by the widget,
       
   198 // the control, or the model.
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 OSN_EXPORT IAlfInterfaceBase* AlfModel::makeInterface( const IfId& aType)
       
   202     {
       
   203     UString param(aType.mImplementationId);
       
   204     if ( param == IAlfModel::type().mImplementationId )
       
   205         {
       
   206         return this;
       
   207         }
       
   208     return 0;
       
   209     }
       
   210 
       
   211 //----------------------------------------------------------------------------
       
   212 //Add a  number of data fields in the model data. All model change
       
   213 //observers are notified about the change.  Internal API not exported
       
   214 //-----------------------------------------------------------------------------
       
   215 void AlfModel::addData(AlfModelOperation* aAddOperation)
       
   216     {
       
   217     IAlfVariantType* newData = 0;
       
   218     IAlfVariantType* parentData = 0;
       
   219     try
       
   220         {
       
   221         //ALF_PERF_START( perfdata, "AlfModel-AddData-Adding")
       
   222         newData = aAddOperation->getNewData();     
       
   223         parentData  = aAddOperation->parentData(*data());
       
   224         int index = aAddOperation->index();
       
   225         
       
   226         if(parentData->type()== IAlfVariantType::EBranch &&
       
   227                newData->type() == IAlfVariantType::EMap )
       
   228             {
       
   229             // This is actually the same as updating the data,
       
   230             // since we can not have multiple branch or child data maps
       
   231             if ( index == 0 )
       
   232                 {
       
   233                 // Set data for the branch
       
   234                 parentData->branch()->setData( newData->map() );
       
   235                 }
       
   236             else if ( index == 1 )
       
   237                 {
       
   238                 // Set data for the branch children
       
   239                 parentData->branch()->setChildData( newData->map() );
       
   240                 }
       
   241             }
       
   242         else if(parentData->type()== IAlfVariantType::EMap)
       
   243             {
       
   244             parentData->map()->addItem( newData,
       
   245                                    aAddOperation->newDataName() );
       
   246             }
       
   247         else if(parentData->type()== IAlfVariantType::EContainer )
       
   248             {
       
   249             parentData->container()->addItem(index, newData);
       
   250             }
       
   251         //ALF_PERF_STOP( perfdata, "AlfModel-AddData-Adding")
       
   252         }
       
   253 	catch(AlfDataException& e)	        
       
   254         {
       
   255         newData = 0;
       
   256         parentData = 0;
       
   257         ALF_THROW(AlfDataException,EInvalidModelOperation,"AlfModel")
       
   258         // Note the aAddOperation is not deleted. In case of exception the user
       
   259         // should delete this object 
       
   260         }
       
   261     }
       
   262     
       
   263 //-----------------------------------------------------------------------------
       
   264 //Remove a  number of data fields in the model data. All model change
       
   265 //observers are notified about the change.
       
   266 //----------------------------------------------------------------------------- 
       
   267 void AlfModel::removeData(AlfModelOperation* aRemoveOperation)
       
   268     {
       
   269     IAlfVariantType* parentData = 0;
       
   270 
       
   271     try
       
   272         {
       
   273         //ALF_PERF_START( perfdata, "AlfModel-RemoveData-Removing")
       
   274         parentData  = aRemoveOperation->parentData(*data());         
       
   275         int index = aRemoveOperation->index();
       
   276 
       
   277         if(parentData->type()== IAlfVariantType::EBranch )
       
   278             {
       
   279             if ( index == 0 )
       
   280                 {
       
   281                 // Remove the branch data
       
   282                 parentData->branch()->setData( 0 );
       
   283                 }
       
   284             else if ( index == 1 )
       
   285                 {
       
   286                 // Remove the branch children data
       
   287                 parentData->branch()->setChildData( 0 );
       
   288                 }
       
   289             }
       
   290         else if(parentData->type()== IAlfVariantType::EMap)
       
   291             {
       
   292             parentData->map()->removeItem(index);
       
   293             }
       
   294         else if(parentData->type()== IAlfVariantType::EContainer )
       
   295             {
       
   296             parentData->container()->removeItem(index);
       
   297             }    
       
   298         //ALF_PERF_STOP( perfdata, "AlfModel-RemoveData-Removing")
       
   299         }
       
   300     catch(AlfDataException& e)
       
   301         {
       
   302         parentData = 0;
       
   303         ALF_THROW(AlfDataException,EInvalidModelOperation,"AlfModel")
       
   304         // Note the aRemoveOperation is not deleted. In case of exception the
       
   305         // user should delete this object	
       
   306         }
       
   307     }
       
   308 
       
   309 
       
   310 void AlfModel::updateData(AlfModelOperation* aUpdateOperation)
       
   311     {
       
   312     IAlfVariantType* newData = 0;
       
   313     IAlfVariantType* parentData = 0;
       
   314 
       
   315     try
       
   316         {
       
   317         //ALF_PERF_START( perfdata, "AlfModel-UpdateData-Updating")
       
   318         newData= aUpdateOperation->getNewData();
       
   319 
       
   320         parentData  = aUpdateOperation->parentData(*data());
       
   321         int index = aUpdateOperation->index();
       
   322 
       
   323         if(parentData->type()== IAlfVariantType::EBranch &&
       
   324                 newData->type() == IAlfVariantType::EMap )
       
   325             {
       
   326             if ( index == 0 )
       
   327                 {
       
   328                 // Update the branch data
       
   329                 parentData->branch()->setData( newData->map() );
       
   330                 }
       
   331             else if ( index == 1 )
       
   332                 {
       
   333                 // Update the data for the branch children
       
   334                 parentData->branch()->setChildData( newData->map() );
       
   335                 }
       
   336             }
       
   337         else if(parentData->type()== IAlfVariantType::EMap)
       
   338             {
       
   339             parentData->map()->replaceItem(index, newData);
       
   340             }
       
   341         else if(parentData->type()== IAlfVariantType::EContainer )
       
   342             {
       
   343             parentData->container()->replaceItem(index,newData);
       
   344             }
       
   345         //ALF_PERF_STOP( perfdata, "AlfModel-UpdateData-Updating")
       
   346         }
       
   347     catch(AlfDataException& e)
       
   348         {
       
   349         parentData=0;
       
   350         newData=0;
       
   351         ALF_THROW(AlfDataException,EInvalidModelOperation,"AlfModel")
       
   352         //Note the aUpdateOperation is not deleted. In case of exception the user should delete this object
       
   353         }
       
   354     }
       
   355 
       
   356 //----------------------------------------------------------------------------
       
   357 //Add a  number of data fields in the model data. All model change
       
   358 //observers are notified about the change. 
       
   359 //----------------------------------------------------------------------------- 
       
   360 OSN_EXPORT void AlfModel::addData(
       
   361     int aNumContainerIndices, int* aContainerIndices, IAlfVariantType* aData)
       
   362     {
       
   363     auto_ptr<AlfModelOperation> op( AlfModelOperation::create(
       
   364     AlfModelOperation::EOperationAdd,
       
   365     aNumContainerIndices,
       
   366     aContainerIndices,
       
   367     aData ) );
       
   368 
       
   369     executeOperation( op.get() );
       
   370     }
       
   371 
       
   372 //-----------------------------------------------------------------------------
       
   373 //Remove a  number of data fields in the model data. All model change
       
   374 //observers are notified about the change.
       
   375 //----------------------------------------------------------------------------- 
       
   376 OSN_EXPORT void AlfModel::removeData(
       
   377     int aNumContainerIndices, int* aContainerIndices)
       
   378     {
       
   379     auto_ptr<AlfModelOperation> op( AlfModelOperation::create(
       
   380     AlfModelOperation::EOperationRemove,
       
   381     aNumContainerIndices,
       
   382     aContainerIndices ) );
       
   383 
       
   384     executeOperation( op.get() );
       
   385     }
       
   386 
       
   387 //-----------------------------------------------------------------------------
       
   388 //Remove a  number of data fields in the model data. All model change
       
   389 //observers are notified about the change.
       
   390 //----------------------------------------------------------------------------- 
       
   391 OSN_EXPORT void AlfModel::updateData(
       
   392     int aNumContainerIndices, int* aContainerIndices, IAlfVariantType* aData)
       
   393     {
       
   394     auto_ptr<AlfModelOperation> op( AlfModelOperation::create(
       
   395     AlfModelOperation::EOperationUpdate,
       
   396     aNumContainerIndices,
       
   397     aContainerIndices,
       
   398     aData ) );
       
   399 
       
   400     executeOperation( op.get() );
       
   401     }
       
   402 
       
   403 //-----------------------------------------------------------------------------
       
   404     /**
       
   405     *  Api for executing batch operations
       
   406     * 
       
   407     *  @param aOperationsArray  - An RPOinterArray containing the list of 
       
   408     *                             operations to be executed in batch.
       
   409     *  @since S60 ?S60_version 
       
   410     */  
       
   411 //----------------------------------------------------------------------------- 
       
   412 OSN_EXPORT void AlfModel::executeOperations(
       
   413     AlfPtrVector<AlfModelOperation>&  aOperationsArray)
       
   414     {
       
   415     int index = 0;
       
   416     int count = aOperationsArray.count();  
       
   417     int obsvrCount = mData->mObserverArray.count();
       
   418     AlfModelOperation* tempOperation=0;
       
   419 
       
   420     for ( index = 0; index < obsvrCount; index++ )
       
   421         {
       
   422         mData->mObserverArray[index]->dataChanging( aOperationsArray );
       
   423         }
       
   424 
       
   425     for ( index = 0; index < count; index++ )
       
   426         {
       
   427         tempOperation = aOperationsArray[index];
       
   428         switch( tempOperation->operation() )
       
   429             {
       
   430             case AlfModelOperation::EOperationAdd:                 
       
   431                  this->addData( tempOperation );
       
   432                 break;
       
   433             case AlfModelOperation::EOperationRemove:                   
       
   434                  this->removeData( tempOperation );
       
   435                 break;
       
   436             case AlfModelOperation::EOperationUpdate:
       
   437                  this->updateData( tempOperation );
       
   438             default:
       
   439                 break;
       
   440          
       
   441             }
       
   442         }
       
   443 
       
   444     for ( index = 0; index < obsvrCount; index++ )
       
   445         {
       
   446         mData->mObserverArray[index]->dataChanged();
       
   447         }
       
   448     }
       
   449 
       
   450 //-----------------------------------------------------------------------------
       
   451     /**
       
   452     *  Api for executing one operation at a Time
       
   453     * 
       
   454     *  @param aOperation    - An Operation to be executed on the model.
       
   455     *  @since S60 ?S60_version 
       
   456     */  
       
   457 //----------------------------------------------------------------------------- 
       
   458 OSN_EXPORT void AlfModel::executeOperation(AlfModelOperation* aOperation)
       
   459     {
       
   460     int index = 0;
       
   461     int obsvrCount = mData->mObserverArray.count();
       
   462 
       
   463     for ( index = 0; index < obsvrCount; index++ )
       
   464         {
       
   465         mData->mObserverArray[index]->dataChanging( *aOperation );
       
   466         }
       
   467 
       
   468     switch(aOperation->operation())
       
   469         {
       
   470         case AlfModelOperation::EOperationAdd:                 
       
   471              this->addData(aOperation);
       
   472             break;
       
   473         case AlfModelOperation::EOperationRemove:                   
       
   474              this->removeData(aOperation);
       
   475             break;
       
   476         case AlfModelOperation::EOperationUpdate:
       
   477              this->updateData(aOperation);
       
   478         default:
       
   479             break;
       
   480         }
       
   481 
       
   482     for ( index = 0; index < obsvrCount; index++ )
       
   483         {
       
   484         mData->mObserverArray[index]->dataChanged();
       
   485         }
       
   486     }
       
   487 } // Alf