emailcontacts/contactactionmenu/src/cfsccontactactionmenuimpl.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2008 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:  Implementation of the class CFscContactActionMenuImpl.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCUDES
       
    20 #include "emailtrace.h"
       
    21 #include <ecom/implementationproxy.h>
       
    22 #include "cfsccontactactionservice.h"
       
    23 #include <eikbtgpc.h>
       
    24 #include <avkon.rsg>
       
    25 #include <avkon.hrh>
       
    26 #include <AknsUtils.h>
       
    27 #include <aknnotewrappers.h> 
       
    28 #include <textresolver.h> 
       
    29 
       
    30 #include "cfsccontactactionmenuimpl.h"
       
    31 #include "fsccontactactionmenuuids.hrh"
       
    32 #include "cfsccontactactionmenumodelimpl.h"
       
    33 #include "tfsccontactactionmenuconstructparameters.h"
       
    34 #include "cfsccontactactionmenulist.h"
       
    35 #include "cfsccontactactionmenuitemimpl.h"
       
    36 #include "cfsccontactactionmenucasitemimpl.h"
       
    37 
       
    38 const TImplementationProxy ImplementationTable[] =
       
    39     {
       
    40     IMPLEMENTATION_PROXY_ENTRY( KFscContactActionMenuImplImpUid, 
       
    41                                 CFscContactActionMenuImpl::NewL )
       
    42     };
       
    43       
       
    44     
       
    45 // ======== LOCAL FUNCTIONS ========
       
    46 
       
    47 // ======== MEMBER FUNCTIONS ========
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // CFscContactActionMenuImpl::NewL
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 CFscContactActionMenuImpl* CFscContactActionMenuImpl::NewL(
       
    54     TAny* aParams )
       
    55     {
       
    56     FUNC_LOG;
       
    57 
       
    58     TFscContactActionMenuConstructParameters* params = 
       
    59         reinterpret_cast< TFscContactActionMenuConstructParameters* >( aParams );
       
    60 
       
    61     CFscContactActionMenuImpl* self = 
       
    62         new (ELeave) CFscContactActionMenuImpl( *params );
       
    63     CleanupStack::PushL( self );
       
    64     self->ConstructL( *params );
       
    65     CleanupStack::Pop( self );
       
    66         
       
    67     return self;
       
    68     }
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 // CFscContactActionMenuImpl::~CFscContactActionMenuImpl
       
    72 // ---------------------------------------------------------------------------
       
    73 //
       
    74 CFscContactActionMenuImpl::~CFscContactActionMenuImpl()
       
    75     {
       
    76     FUNC_LOG;
       
    77     delete iModel;
       
    78     delete iList;
       
    79     delete iWait;
       
    80     delete iTextResolver;
       
    81     delete iDummyMenuItem;
       
    82     }
       
    83 
       
    84 // ---------------------------------------------------------------------------
       
    85 // CFscContactActionMenuImpl::ExecuteL
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 TFscActionMenuResult CFscContactActionMenuImpl::ExecuteL( 
       
    89     TFscContactActionMenuPosition aPosition, TInt aIndex, MFsActionMenuPositionGiver* aPositionGiver)
       
    90     {
       
    91     FUNC_LOG;
       
    92           
       
    93     // Initialise some member variables
       
    94     iExit = EFalse;
       
    95     iMenuResult = EFscMenuDismissed;
       
    96     iError = KErrNone;
       
    97     
       
    98     // Check if menu is empty
       
    99     if ( iModel->VisibleItemCount() > 0 )
       
   100         {         
       
   101         iList = CFscContactActionMenuList::NewL( 
       
   102             this, iModel, ( iMode == EFscContactActionMenuModeAI ), aPositionGiver, iOpenedFromMR );
       
   103         // Execute menu
       
   104         TRAP( iError, DoExecuteL( aPosition, aIndex ) );
       
   105 
       
   106         // Delete iList
       
   107         iSelectedItemIndex = iList->SelectedItemIndex();
       
   108         delete iList;
       
   109         iList = NULL;
       
   110 
       
   111         User::LeaveIfError( iError );
       
   112         }
       
   113 
       
   114     return iMenuResult;
       
   115     }
       
   116 
       
   117 // ---------------------------------------------------------------------------
       
   118 // CFscContactActionMenuImpl::Dismiss
       
   119 // ---------------------------------------------------------------------------
       
   120 //
       
   121 void CFscContactActionMenuImpl::Dismiss( TBool aSlide )
       
   122     {
       
   123     FUNC_LOG;
       
   124     iExit = !aSlide;
       
   125     iMenuResult = EFscMenuDismissed;
       
   126     // cancel action execution if running
       
   127     // needs to be canceled to close select popup dialog
       
   128     if ( iIsActionExecuting )
       
   129         {
       
   130         iModel->Service()->CancelExecute();
       
   131         iIsActionExecuting = EFalse;
       
   132         }
       
   133      
       
   134     DoDismiss();
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // CFscContactActionMenuImpl::Model
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 MFscContactActionMenuModel& CFscContactActionMenuImpl::Model()
       
   142     {
       
   143     FUNC_LOG;
       
   144     return *iModel; 
       
   145     }
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 // CFscContactActionMenuImpl::FocusedItemIndex
       
   149 // ---------------------------------------------------------------------------
       
   150 //
       
   151 TInt CFscContactActionMenuImpl::FocusedItemIndex()
       
   152     {
       
   153     FUNC_LOG;
       
   154     TInt result = iSelectedItemIndex;
       
   155     if ( iList != NULL )
       
   156         {
       
   157         result = iList->SelectedItemIndex();
       
   158         }
       
   159     return result;
       
   160     }
       
   161 
       
   162 // ---------------------------------------------------------------------------
       
   163 // CFscContactActionMenuImpl::FocusedItem
       
   164 // ---------------------------------------------------------------------------
       
   165 //
       
   166 CFscContactActionMenuItem& CFscContactActionMenuImpl::FocusedItem()
       
   167     {
       
   168     FUNC_LOG;
       
   169     TInt i = FocusedItemIndex();
       
   170     TInt err = KErrNone;
       
   171     
       
   172     CFscContactActionMenuItem* focusedItem = NULL;
       
   173     
       
   174     TRAP( err, focusedItem = &(iModel->ItemL( i )) );
       
   175     if ( err != KErrNone )
       
   176         {
       
   177         CCoeEnv::Static()->HandleError( err );
       
   178         focusedItem = iDummyMenuItem;
       
   179         }
       
   180     
       
   181     return *focusedItem;
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------------------------
       
   185 // CFscContactActionMenuImpl::HandleListEvent
       
   186 // ---------------------------------------------------------------------------
       
   187 //
       
   188 void CFscContactActionMenuImpl::HandleListEvent( 
       
   189     TFscContactActionMenuListEvent aEvent,
       
   190     TInt aError )
       
   191     {
       
   192     FUNC_LOG;
       
   193     switch ( aEvent )
       
   194         {
       
   195         case EFscMenuEventItemClicked:
       
   196             {
       
   197             HandleItemClick();
       
   198             break;
       
   199             }
       
   200         case EFscMenuEventError:
       
   201             {
       
   202             iError = aError;
       
   203             //break not needed because menu will be dismissed
       
   204             }
       
   205         case EFscMenuEventExitKey:
       
   206             {
       
   207             iExit = ETrue;
       
   208             //break not needed because menu will be dismissed
       
   209             }
       
   210         case EFscMenuEventCloseKey:
       
   211             {
       
   212             iMenuResult = EFscMenuDismissed;
       
   213             DoDismiss();
       
   214             break;
       
   215             }
       
   216         case EFscMenuEventMenuHidden:
       
   217             {
       
   218             StopWait();
       
   219             
       
   220             // Hide Cba and fade
       
   221             HideMenuCba();
       
   222             iFader.FadeBehindPopup( this, iList, EFalse );
       
   223             break;
       
   224             }
       
   225         case EFscMenuLayoutChanged:
       
   226             {
       
   227             Dismiss( iExit );
       
   228             break;
       
   229             }
       
   230         default:
       
   231             {
       
   232             // nothing to do here
       
   233             break;
       
   234             }    
       
   235         }
       
   236     } 
       
   237 
       
   238 // ---------------------------------------------------------------------------
       
   239 // CFscContactActionMenuImpl::CountFadedComponents
       
   240 // ---------------------------------------------------------------------------
       
   241 //
       
   242 TBool CFscContactActionMenuImpl::IsOperationCompleted()
       
   243     {
       
   244     FUNC_LOG;
       
   245     return isExecuteCompleted;
       
   246     }
       
   247 
       
   248 // ---------------------------------------------------------------------------
       
   249 // CFscContactActionMenuImpl::SetOpenedFromMR
       
   250 // ---------------------------------------------------------------------------
       
   251 // 
       
   252 void CFscContactActionMenuImpl::SetOpenedFromMR( TBool aOpenedFromMR )
       
   253     {
       
   254     iOpenedFromMR = aOpenedFromMR;
       
   255     }
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 // CFscContactActionMenuImpl::CountFadedComponents
       
   259 // ---------------------------------------------------------------------------
       
   260 //
       
   261 TInt CFscContactActionMenuImpl::CountFadedComponents()
       
   262     {
       
   263     FUNC_LOG;
       
   264     TInt count = 1;
       
   265     if ( iList )
       
   266         {
       
   267         count++;
       
   268         }
       
   269     return count;
       
   270     }
       
   271 
       
   272 // ---------------------------------------------------------------------------
       
   273 // CFscContactActionMenuImpl::FadedComponent
       
   274 // ---------------------------------------------------------------------------
       
   275 //
       
   276 CCoeControl* CFscContactActionMenuImpl::FadedComponent(TInt aIndex)
       
   277     {
       
   278     FUNC_LOG;
       
   279     CCoeControl* cntrl = NULL;
       
   280     switch (aIndex)
       
   281         {
       
   282         case 0:
       
   283             {
       
   284             cntrl = iButtonGroupContainer;
       
   285             break;
       
   286             }        
       
   287         case 1:
       
   288             {
       
   289             cntrl = iList;
       
   290             break;
       
   291             }
       
   292         default:
       
   293             {
       
   294             cntrl = NULL;
       
   295             break;
       
   296             }
       
   297         }
       
   298     return cntrl;    
       
   299     }
       
   300 
       
   301 // ---------------------------------------------------------------------------
       
   302 // CFscContactActionMenuImpl::FadedComponent
       
   303 // ---------------------------------------------------------------------------
       
   304 //
       
   305 void CFscContactActionMenuImpl::HandleGainingForeground()
       
   306     {
       
   307     FUNC_LOG;
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // CFscContactActionMenuImpl::FadedComponent
       
   312 // ---------------------------------------------------------------------------
       
   313 //
       
   314 void CFscContactActionMenuImpl::HandleLosingForeground()
       
   315     {
       
   316     FUNC_LOG;
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // CFscContactActionMenuImpl::ProcessCommandL
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 void CFscContactActionMenuImpl::ProcessCommandL(TInt aCommandId)
       
   324     {
       
   325     FUNC_LOG;
       
   326     if ( isExecuteCompleted )
       
   327         {
       
   328         switch ( aCommandId )
       
   329             {
       
   330             case EAknSoftkeyCancel:
       
   331                 {
       
   332                 iMenuResult = EFscMenuDismissed;
       
   333                 DoDismiss();
       
   334                 break;
       
   335                 }
       
   336             case EAknSoftkeySelect:
       
   337                 {
       
   338                 HandleItemClick();
       
   339                 break;
       
   340                 }
       
   341             default:
       
   342                 {
       
   343                 // Nothing to do
       
   344                 break;
       
   345                 }    
       
   346             }
       
   347         }
       
   348     }
       
   349     
       
   350 // ---------------------------------------------------------------------------
       
   351 // CFscContactActionMenuImpl::CFscContactActionMenuImpl
       
   352 // ---------------------------------------------------------------------------
       
   353 //
       
   354 CFscContactActionMenuImpl::CFscContactActionMenuImpl( 
       
   355     const TFscContactActionMenuConstructParameters& aParams ) 
       
   356     : CFscContactActionMenu(), iMode(aParams.iMode),
       
   357       iSelectedItemIndex( 0 ), isExecuteCompleted( ETrue ),
       
   358       iOpenedFromMR( EFalse )
       
   359     {
       
   360     FUNC_LOG;
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // CFscContactActionMenuImpl::ConstructL
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 void CFscContactActionMenuImpl::ConstructL(
       
   368     const TFscContactActionMenuConstructParameters& aParams )
       
   369     {
       
   370     FUNC_LOG;
       
   371     iModel = CFscContactActionMenuModelImpl::NewL( aParams.iService );
       
   372     iWait = new ( ELeave ) CActiveSchedulerWait();
       
   373     iTextResolver = CTextResolver::NewL( *CCoeEnv::Static() );
       
   374     iDummyMenuItem = CFscContactActionMenuItemImpl::NewL();
       
   375     iDummyMenuItem->SetImplementationUid( KNullUid );
       
   376     }   
       
   377 
       
   378 // ---------------------------------------------------------------------------
       
   379 // CFscContactActionMenuImpl::DoExecuteL
       
   380 // ---------------------------------------------------------------------------
       
   381 //
       
   382 void CFscContactActionMenuImpl::DoExecuteL( 
       
   383     TFscContactActionMenuPosition aPosition,
       
   384     TInt aIndex )
       
   385     {
       
   386     FUNC_LOG;
       
   387     
       
   388     // Show list
       
   389     iList->ShowL( aPosition, aIndex );
       
   390     ShowMenuCbaL();
       
   391     iFader.FadeBehindPopup( this, iList, ETrue );
       
   392     
       
   393     // Wait untill dialog is hidden again
       
   394     StartWait(); 
       
   395     
       
   396     }
       
   397 
       
   398 // ---------------------------------------------------------------------------
       
   399 // CFscContactActionMenuImpl::DoDismiss
       
   400 // ---------------------------------------------------------------------------
       
   401 //
       
   402 void CFscContactActionMenuImpl::DoDismiss()
       
   403     {
       
   404     FUNC_LOG;
       
   405     if ( iList )
       
   406         {
       
   407         iList->Hide( !iExit ); // If no instant exit, slide
       
   408         }
       
   409     }
       
   410 
       
   411 // ---------------------------------------------------------------------------
       
   412 // CFscContactActionMenuImpl::StartWait
       
   413 // ---------------------------------------------------------------------------
       
   414 //
       
   415 void CFscContactActionMenuImpl::StartWait()
       
   416     {
       
   417     FUNC_LOG;
       
   418     iWait->Start();
       
   419     }
       
   420 
       
   421 // ---------------------------------------------------------------------------
       
   422 // CFscContactActionMenuImpl::StopWait
       
   423 // ---------------------------------------------------------------------------
       
   424 //
       
   425 void CFscContactActionMenuImpl::StopWait()
       
   426     {
       
   427     FUNC_LOG;
       
   428     if ( iWait->IsStarted() )
       
   429         {
       
   430         iWait->AsyncStop();
       
   431         }
       
   432     }
       
   433 
       
   434 // ---------------------------------------------------------------------------
       
   435 // CFscContactActionMenuImpl::ShowMenuCbaL
       
   436 // ---------------------------------------------------------------------------
       
   437 //
       
   438 void CFscContactActionMenuImpl::ShowMenuCbaL()
       
   439     {
       
   440     FUNC_LOG;
       
   441     
       
   442     TInt cbaResource = 0;
       
   443     if ( iList->ItemCount() > 0)
       
   444         {
       
   445         cbaResource = R_AVKON_SOFTKEYS_SELECT_CANCEL__SELECT;
       
   446         }
       
   447     else
       
   448         {
       
   449         cbaResource = R_AVKON_SOFTKEYS_CANCEL;
       
   450         }    
       
   451     
       
   452     iButtonGroupContainer = CEikButtonGroupContainer::NewL( 
       
   453         CEikButtonGroupContainer::ECba,
       
   454         CEikButtonGroupContainer::EHorizontal,
       
   455         this, cbaResource, *iList, 
       
   456         CEikButtonGroupContainer::EDelayActivation );
       
   457         
       
   458     }
       
   459 
       
   460 // ---------------------------------------------------------------------------
       
   461 // CFscContactActionMenuImpl::HideMenuCba
       
   462 // ---------------------------------------------------------------------------
       
   463 //
       
   464 void CFscContactActionMenuImpl::HideMenuCba()
       
   465     {
       
   466     FUNC_LOG;
       
   467     delete iButtonGroupContainer;
       
   468     iButtonGroupContainer = NULL;
       
   469     }  
       
   470 
       
   471 // ---------------------------------------------------------------------------
       
   472 // CFscContactActionMenuImpl::HandleItemClick
       
   473 // ---------------------------------------------------------------------------
       
   474 //
       
   475 void CFscContactActionMenuImpl::HandleItemClick()
       
   476     {
       
   477     FUNC_LOG;
       
   478     
       
   479     TInt selectedItemIndex = FocusedItemIndex();
       
   480     TInt itemCount = iModel->VisibleItemCount();
       
   481     if ( selectedItemIndex >= 0 && selectedItemIndex < itemCount )
       
   482         {
       
   483         // Check type of selected item
       
   484         CFscContactActionMenuItem* baseItem = NULL;
       
   485         TRAP( iError, baseItem = &iModel->VisibleItemL( selectedItemIndex ) );
       
   486         
       
   487 		if ( iError == KErrNone )
       
   488 		    {
       
   489             // Check type of selected item
       
   490             CFscContactActionMenuCasItemImpl* item =
       
   491                 dynamic_cast<CFscContactActionMenuCasItemImpl*>( baseItem );
       
   492             if ( item != NULL )
       
   493                 {
       
   494                 iMenuResult = EFscCasItemSelectedAndExecuting;
       
   495                 TUid actionUid = item->ImplementationUid();
       
   496                 isExecuteCompleted = EFalse;
       
   497                 iIsActionExecuting = ETrue;
       
   498                 TRAP( iError,
       
   499                     iModel->Service()->ExecuteL( actionUid, this ) );
       
   500                 }
       
   501             else
       
   502                 {
       
   503                 // Custom item is not executed by the menu
       
   504                 iMenuResult = EFscCustomItemSelected;
       
   505                 DoDismiss();
       
   506                 }
       
   507 		    }
       
   508 
       
   509 		if ( iError != KErrNone )
       
   510             {
       
   511             // Show error note
       
   512             TPtrC buf;
       
   513             buf.Set( iTextResolver->ResolveErrorString( iError ) );
       
   514             if ( buf.Length() > 0 )
       
   515                 {
       
   516                 CAknWarningNote* note = new CAknWarningNote();
       
   517                 
       
   518                 if ( note )
       
   519                     {
       
   520                     // If error string was found and note execution is 
       
   521                     // successfull iError will be KErrNone. Otherwise 
       
   522                     // iError will be delivered to the client application
       
   523                     TRAP( iError, note->ExecuteLD( buf ) );
       
   524                     }
       
   525                 else
       
   526                     {
       
   527                     iError = KErrNoMemory;
       
   528                     }
       
   529                 }
       
   530             }
       
   531         }
       
   532     else
       
   533         {
       
   534         iMenuResult = EFscMenuDismissed;
       
   535         }
       
   536         
       
   537     }
       
   538 
       
   539 
       
   540 // ---------------------------------------------------------------------------
       
   541 // From MFscContactActionServiceObserver.
       
   542 // Called when QueryActionsL method is complete.
       
   543 // ---------------------------------------------------------------------------
       
   544 //
       
   545 void CFscContactActionMenuImpl::QueryActionsComplete()
       
   546     {
       
   547     FUNC_LOG;
       
   548     // CAS observer method implementation - not used in this component
       
   549     }
       
   550 
       
   551 // ---------------------------------------------------------------------------
       
   552 // From MFscContactActionServiceObserver.
       
   553 // Called when QueryActionsL method failed.
       
   554 // ---------------------------------------------------------------------------
       
   555 //
       
   556 void CFscContactActionMenuImpl::QueryActionsFailed( TInt /*aError*/ )
       
   557     {
       
   558     FUNC_LOG;
       
   559     // CAS observer method implementation - not used in this component
       
   560     }
       
   561     
       
   562 // ---------------------------------------------------------------------------
       
   563 // From MFscContactActionServiceObserver.
       
   564 // Called when ExecuteL method is complete.
       
   565 // ---------------------------------------------------------------------------
       
   566 //
       
   567 void CFscContactActionMenuImpl::ExecuteComplete()
       
   568     {
       
   569     FUNC_LOG;
       
   570     isExecuteCompleted = ETrue;
       
   571     iIsActionExecuting = EFalse;
       
   572     iMenuResult = EFscCasItemSelectedAndExecuted;
       
   573     DoDismiss();
       
   574     }
       
   575      
       
   576 // ---------------------------------------------------------------------------
       
   577 // From MFscContactActionServiceObserver.
       
   578 // Called when ExecuteL method failed.
       
   579 // ---------------------------------------------------------------------------
       
   580 //
       
   581 void CFscContactActionMenuImpl::ExecuteFailed( TInt aError )
       
   582     {
       
   583     FUNC_LOG;
       
   584     iError = aError;
       
   585     isExecuteCompleted = ETrue;
       
   586     
       
   587     //Fix for: EJKA-7KAEVA
       
   588     if ( KErrCancel != iError )
       
   589         {
       
   590         // Show error note
       
   591         TPtrC buf;
       
   592         buf.Set( iTextResolver->ResolveErrorString( iError ) );
       
   593         if ( buf.Length() > 0 )
       
   594             {
       
   595             CAknWarningNote* note = new CAknWarningNote();
       
   596         
       
   597             if ( note )
       
   598                 {
       
   599                 // If error string was found and note execution is 
       
   600                 // successfull iError will be KErrNone. Otherwise 
       
   601                 // iError will be delivered to the client application
       
   602                 TRAP( iError, note->ExecuteLD( buf ) );
       
   603                 }
       
   604             else
       
   605                 {
       
   606                 iError = KErrNoMemory;
       
   607                 }
       
   608             }
       
   609         }
       
   610     else
       
   611         {
       
   612         iError = KErrNone;
       
   613         iIsActionExecuting = EFalse;
       
   614         iMenuResult = EFscMenuDismissed;
       
   615         }
       
   616     DoDismiss();
       
   617     }
       
   618     
       
   619 // ---------------------------------------------------------------------------
       
   620 // CFscContactActionMenuImpl::UpdateFadeColors
       
   621 // ---------------------------------------------------------------------------
       
   622 //
       
   623 void CFscContactActionMenuImpl::UpdateFadeColors()
       
   624     {
       
   625     FUNC_LOG;
       
   626     
       
   627     }
       
   628     
       
   629 // ======== GLOBAL FUNCTIONS ========
       
   630 
       
   631 // ---------------------------------------------------------------------------
       
   632 // ImplementationGroupProxy
       
   633 // ---------------------------------------------------------------------------
       
   634 //
       
   635 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( 
       
   636     TInt& aTableCount )
       
   637     {
       
   638     aTableCount = sizeof( ImplementationTable ) / 
       
   639         sizeof( TImplementationProxy );
       
   640     return ImplementationTable;
       
   641     }
       
   642