srsf/profileobserverplugin/src/vcommandprofileobserver.cpp
branchRCL_3
changeset 19 e36f3802f733
parent 0 bf1d17376201
equal deleted inserted replaced
18:cad71a31b7fc 19:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2006-2007 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:  implements profile changes handling
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <aknlists.h>
       
    20 #include <bautils.h> 
       
    21 
       
    22 #include <ProEngFactory.h>
       
    23 #include <MProEngProfileNameArray.h>
       
    24 
       
    25 #include <vcprofileobserver.rsg>
       
    26 #include <mmfcontrollerpluginresolver.h> // For CleanupResetAndDestroyPushL
       
    27 
       
    28 #include "vcommandprofileobserver.h"
       
    29 #include "rubydebug.h"
       
    30 
       
    31 
       
    32 // ============================ CONSTANTS ===============================
       
    33 
       
    34 _LIT( KResourceFile, "z:\\resource\\vcprofileobserver.rsc" );
       
    35 
       
    36 // UID of the profiles application
       
    37 const TUid KUidAppProfiles = { 0x100058F8 };
       
    38 
       
    39 // Executable for changing profiles.
       
    40 const TUid KProfileChangerUid = { 0x10281D15 };
       
    41 
       
    42 // Starting id for profile command arguments
       
    43 const TInt KProfileCommandArgumentBase = 200;
       
    44 
       
    45 // File name to read the icon from
       
    46 _LIT( KIconFile, "Z:\\resource\\apps\\vcommand.mif" );
       
    47 
       
    48 // Index of the profile folder icon in the default folder icon file
       
    49 // @see CVCFolderIcon::NewL
       
    50 const TInt KProfileFolderIconIndex = 5;
       
    51 
       
    52 // ============================ MEMBER FUNCTIONS ===============================
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CVCommandProfileObserver::CVCommandProfileObserver
       
    56 // C++ default constructor can NOT contain any code, that
       
    57 // might leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CVCommandProfileObserver::CVCommandProfileObserver()
       
    61  : iProfileUpdateError( EFalse )
       
    62     {
       
    63     }
       
    64  
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CVCommandProfileObserver::ConstructL
       
    68 // Symbian 2nd phase constructor can leave.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 void CVCommandProfileObserver::ConstructL()
       
    72     {  
       
    73     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::ConstructL()" );
       
    74     
       
    75     iService = CVCommandHandler::NewL();  
       
    76 
       
    77     iProfileEngine = ProEngFactory::NewEngineL();
       
    78     iNameArray = iProfileEngine->ProfileNameArrayLC();     
       
    79     CleanupStack::Pop(); // we can't popup C-class with M-class argument
       
    80      
       
    81     LoadProfileDataL();
       
    82     SyncVCommandProfilesL();
       
    83     
       
    84     // Create the profile engine notify handler only after construction of
       
    85     // other parts have been completed successfully. This way, should
       
    86     // construction fail, we avoid the situation where a callback is executed
       
    87     // on a partially contructed object
       
    88     iNotifyHandler = ProEngFactory::NewNotifyHandlerL();
       
    89     iNotifyHandler->RequestProfileNameArrayNotificationsL( *this );
       
    90     }
       
    91  
       
    92    
       
    93 // -----------------------------------------------------------------------------
       
    94 // CVCommandProfileObserver::NewL
       
    95 // Two-phased constructor.
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 CVCommandProfileObserver* CVCommandProfileObserver::NewL() 
       
    99     {
       
   100     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::NewL()" );
       
   101     
       
   102     CVCommandProfileObserver* self = new( ELeave ) CVCommandProfileObserver();
       
   103     
       
   104     CleanupStack::PushL( self );
       
   105     self->ConstructL();
       
   106     CleanupStack::Pop( self );
       
   107     
       
   108     return self;
       
   109     }
       
   110  
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CVCommandProfileObserver::~CVCommandProfileObserver
       
   114 // Destructor.
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 CVCommandProfileObserver::~CVCommandProfileObserver()
       
   118     {
       
   119     RUBY_DEBUG0( "CVCommandProfileObserver::~CVCommandProfileObserver()" );
       
   120     
       
   121     if( iProfileEngine ) 
       
   122         {
       
   123         iProfileEngine->Release();    
       
   124         }
       
   125     iProfileEngine = NULL;
       
   126      
       
   127     if( iNameArray ) 
       
   128         {
       
   129         delete iNameArray;
       
   130         iNameArray = NULL;
       
   131         }
       
   132        
       
   133     DeleteCache();
       
   134         
       
   135     delete iService;
       
   136     
       
   137     if ( iNotifyHandler )
       
   138         {
       
   139         iNotifyHandler->CancelProfileNameArrayNotifications();
       
   140         }
       
   141     delete iNotifyHandler;
       
   142     delete iProfileFolder;
       
   143     delete iFolderTitle;
       
   144     delete iProfileTooltip;
       
   145     
       
   146     iAddedCommands.ResetAndDestroy();
       
   147     iAddedCommands.Close();    
       
   148     } 
       
   149   
       
   150  
       
   151 // -----------------------------------------------------------------------------
       
   152 // CVCommandProfileObserver::SyncVCommandProfilesL
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void CVCommandProfileObserver::SyncVCommandProfilesL()
       
   156     {
       
   157     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::SyncVCommandProfilesL()" );
       
   158     
       
   159     if( !iNameArray || iNameArray->MdcaCount() <= 0 ) 
       
   160         {
       
   161         return;
       
   162         }
       
   163     
       
   164     // Form the set of commands that should be in
       
   165     RVCommandArray profileEngineCommands;
       
   166     CleanupResetAndDestroyPushL( profileEngineCommands );
       
   167     for( TInt i = 0; i < iNameArray->MdcaCount(); i++ )
       
   168         {
       
   169         TInt index = iNameArray->FindByName( iNameArray->MdcaPoint( i ) );
       
   170         TInt profileId = iNameArray->ProfileId( index );
       
   171         CVCommand* command = CreateProfileCommandL( iNameArray->MdcaPoint( i ), profileId );
       
   172         profileEngineCommands.AppendL( command );
       
   173         }
       
   174     
       
   175     // delete cache and force iCommands to be reloaded
       
   176     //
       
   177     DeleteCache();
       
   178 
       
   179     const CVCommandArray& storedCommands = ListVCommandsL();
       
   180     CVCommandArray* deduction = storedCommands.ProduceUntrainSetByRunnablesLC( profileEngineCommands );
       
   181     CVCommandArray* addition = storedCommands.ProduceTrainSetByRunnablesLC( profileEngineCommands );
       
   182     
       
   183     iService->RemoveCommandsL( deduction->PointerArray(), ETrue );
       
   184     iService->AddCommandsL( addition->PointerArray(), ETrue );
       
   185     CleanupStack::PopAndDestroy( addition );
       
   186     CleanupStack::PopAndDestroy( deduction );
       
   187     
       
   188     CleanupStack::PopAndDestroy( &profileEngineCommands );
       
   189     
       
   190     }
       
   191 
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CVCommandProfileObserver::HandleProfileNameArrayModificationL
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 // Assume that there will be only one change each time this function is called.
       
   198 //
       
   199 void CVCommandProfileObserver::HandleProfileNameArrayModificationL()
       
   200     {
       
   201     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::HandleProfileNameArrayModificationL()" );
       
   202     
       
   203     // delete cache and force iCommands to be reloaded
       
   204     //
       
   205     DeleteCache();
       
   206     
       
   207     // new array of profile names
       
   208     MProEngProfileNameArray* nameArray = iProfileEngine->ProfileNameArrayLC();
       
   209           
       
   210     // copy profile names to two descriptor arrays
       
   211     //
       
   212     CDesC16ArrayFlat* oldNames = new ( ELeave ) CDesCArrayFlat( iNameArray->MdcaCount() );   
       
   213     CleanupStack::PushL( oldNames );
       
   214     
       
   215     CDesC16ArrayFlat* newNames = new ( ELeave ) CDesCArrayFlat( nameArray->MdcaCount() );
       
   216     CleanupStack::PushL( newNames );
       
   217         
       
   218     for( TInt i = 0; i < iNameArray->MdcaCount(); i++ )
       
   219         {
       
   220         oldNames->AppendL( iNameArray->MdcaPoint( i ) );
       
   221         }
       
   222     for( TInt j = 0; j < nameArray->MdcaCount(); j++ )
       
   223         {
       
   224         newNames->AppendL( nameArray->MdcaPoint( j ) );
       
   225         }
       
   226  
       
   227          
       
   228     // Find changes by deleting equivalent commands from both descriptor arrays.
       
   229     //
       
   230     for( TInt i = 0; i < newNames->MdcaCount(); i++ ) // go through the new names
       
   231         {
       
   232         TName searchStr = newNames->MdcaPoint( i );
       
   233         TInt index;
       
   234         
       
   235         oldNames->Find( searchStr, index, ECmpNormal );
       
   236         
       
   237         if( index != oldNames->MdcaCount() ) // String was found
       
   238             {
       
   239             oldNames->Delete( index );
       
   240             newNames->Delete( i );
       
   241             i--;
       
   242             }
       
   243         }
       
   244       
       
   245       
       
   246     // profile name has been edited
       
   247     //
       
   248     if( newNames->MdcaCount() == oldNames->MdcaCount() ) 
       
   249         {
       
   250     
       
   251         // now we should have a pair of original and changed name
       
   252         //
       
   253         if( newNames->MdcaCount() == 1 ) // let's edit the profile name (old name, new name)
       
   254             {
       
   255             TRAPD( error, EditProfileNameL( oldNames->MdcaPoint( 0 ), newNames->MdcaPoint( 0 ) ) );
       
   256             if ( error == KErrGeneral )
       
   257                 {
       
   258                 CleanupStack::PopAndDestroy( newNames );    
       
   259                 CleanupStack::PopAndDestroy( oldNames );
       
   260                 CleanupStack::Pop(); // nameArray ( M-class pointer )
       
   261         
       
   262                 delete iNameArray;        
       
   263                 iNameArray = nameArray;
       
   264         
       
   265                 User::Leave( error );
       
   266                 }
       
   267             }
       
   268         }
       
   269     // new profile(s) has been added
       
   270     //
       
   271     else if( newNames->MdcaCount() > oldNames->MdcaCount() ) 
       
   272         {
       
   273         AddNewProfilesL( *newNames, *nameArray );
       
   274         }
       
   275     // profile(s) has been deleted
       
   276     //
       
   277     else 
       
   278         {
       
   279         RemoveProfilesL( *oldNames );
       
   280         }
       
   281     
       
   282     // update old profile names
       
   283     //
       
   284     CleanupStack::PopAndDestroy( newNames );    
       
   285     CleanupStack::PopAndDestroy( oldNames );    
       
   286     CleanupStack::Pop(); // nameArray ( M-class pointer )
       
   287     
       
   288     delete iNameArray;
       
   289     iNameArray = nameArray;
       
   290     
       
   291     if ( iProfileUpdateError )
       
   292         {
       
   293         iProfileUpdateError = EFalse;
       
   294         
       
   295         HandleProfileNameArrayModificationL();
       
   296         }
       
   297     }
       
   298 
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CVCommandProfileObserver::HandleProfileNameArrayNotificationError
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 void CVCommandProfileObserver::HandleProfileNameArrayNotificationError( TInt aError ) 
       
   305     {
       
   306     RUBY_ERROR1( "HandleProfileNameArrayNotificationError: %d", aError );
       
   307     
       
   308     if ( aError == KErrLocked )
       
   309         {
       
   310         iProfileUpdateError = ETrue;
       
   311         }
       
   312     }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // CVCommandProfileObserver::LoadProfileDataL
       
   316 // -----------------------------------------------------------------------------
       
   317 //
       
   318 void CVCommandProfileObserver::LoadProfileDataL()
       
   319     {
       
   320     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::LoadProfileDataL()" );
       
   321     
       
   322     RFs fs;
       
   323     CleanupClosePushL( fs );
       
   324     User::LeaveIfError( fs.Connect() );
       
   325     
       
   326     RResourceFile resourceFile;
       
   327     TResourceReader theReader;
       
   328     
       
   329     TFileName name;
       
   330     name.Append( KResourceFile );
       
   331 
       
   332     BaflUtils::NearestLanguageFile( fs, name );
       
   333 
       
   334     if ( !BaflUtils::FileExists( fs, name ) )
       
   335         {
       
   336         User::Leave( KErrNotFound );
       
   337         }
       
   338     
       
   339     resourceFile.OpenL( fs, name );
       
   340     CleanupClosePushL( resourceFile );
       
   341 
       
   342     // Leaves 'res' to cleanupstack
       
   343     HBufC8* res = resourceFile.AllocReadLC( VCPROFILEOBSERVERINFO );
       
   344     theReader.SetBuffer( res );
       
   345 
       
   346     iProfileFolder = theReader.ReadHBufCL();
       
   347     iFolderTitle = theReader.ReadHBufCL();
       
   348     iProfileTooltip = theReader.ReadHBufCL();
       
   349     
       
   350     // Cleanup res 
       
   351     CleanupStack::PopAndDestroy( res );
       
   352     CleanupStack::PopAndDestroy( &resourceFile );
       
   353     CleanupStack::PopAndDestroy( &fs );
       
   354     }
       
   355     
       
   356     
       
   357 // -----------------------------------------------------------------------------
       
   358 // CVCommandProfileObserver::ListVCommandsL
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 const CVCommandArray& CVCommandProfileObserver::ListVCommandsL()
       
   362     {
       
   363     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::ListVCommandsL()" );
       
   364     
       
   365     if( !iCommands )
       
   366         {
       
   367         iCommands = iService->ListCommandsL();
       
   368         }
       
   369         
       
   370     return *iCommands;
       
   371     }
       
   372  
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // CVCommandProfileObserver::DeleteCache
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 void CVCommandProfileObserver::DeleteCache()
       
   379     {
       
   380     RUBY_DEBUG0( "CVCommandProfileObserver::DeleteCache()" );
       
   381     
       
   382     // delete cache and force iCommands to be reloaded
       
   383     //
       
   384     delete iCommands;
       
   385     iCommands = NULL;
       
   386     }
       
   387  
       
   388  
       
   389 // -----------------------------------------------------------------------------
       
   390 // CVCommandProfileObserver::AddNewProfileL
       
   391 // Adds new profile to VCommandhandler.
       
   392 // -----------------------------------------------------------------------------
       
   393 //
       
   394 void CVCommandProfileObserver::AddNewProfileL( const TDesC& aNewName,
       
   395                                                TInt aProfileId,
       
   396                                                TBool aCommit )
       
   397     {
       
   398     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::AddNewProfileL()" );
       
   399     
       
   400     // if profile name doesn't exists
       
   401     //
       
   402     if( FindProfileIndexL( aNewName ) == KErrNotFound )
       
   403         {
       
   404         CVCommand* initialCommand = CreateProfileCommandL( aNewName, aProfileId );
       
   405         CleanupStack::PushL( initialCommand );
       
   406 
       
   407         if ( aCommit )
       
   408             {
       
   409             iService->AddCommandL( *initialCommand );
       
   410             CleanupStack::PopAndDestroy( initialCommand );
       
   411 
       
   412             // delete cache and force iCommands to be reloaded
       
   413             //
       
   414             DeleteCache();
       
   415             }
       
   416         else
       
   417             {
       
   418             iAddedCommands.AppendL( initialCommand );
       
   419         
       
   420             CleanupStack::Pop( initialCommand );            
       
   421             }
       
   422         }
       
   423     }
       
   424     
       
   425 // -----------------------------------------------------------------------------
       
   426 // CVCommandProfileObserver::AddNewProfilesL
       
   427 // Adds new profiles to VCommandhandler.
       
   428 // -----------------------------------------------------------------------------
       
   429 //
       
   430 void CVCommandProfileObserver::AddNewProfilesL( const CDesC16ArrayFlat& aNames,
       
   431                                                 const MProEngProfileNameArray& aProfileNames,
       
   432                                                 TBool aCommit )
       
   433     {
       
   434     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::AddNewProfilesL()" );
       
   435     
       
   436     RVCommandArray commands;
       
   437     CleanupClosePushL( commands );
       
   438     CleanupResetAndDestroyPushL( commands );
       
   439     
       
   440     for( TInt i = 0; i < aNames.MdcaCount(); i++ )
       
   441         {
       
   442         TInt index = aProfileNames.FindByName( aNames.MdcaPoint(i) );
       
   443         TInt profileId = aProfileNames.ProfileId( index );
       
   444         
       
   445         // if profile name doesn't exists
       
   446         //
       
   447         if( FindProfileIndexL( aNames.MdcaPoint(i) ) == KErrNotFound )
       
   448             {
       
   449             CVCommand* initialCommand = CreateProfileCommandL( aNames.MdcaPoint(i), profileId );
       
   450             CleanupStack::PushL( initialCommand );
       
   451 
       
   452             if ( aCommit )
       
   453                 {
       
   454                 commands.Append( initialCommand );
       
   455                 }
       
   456             else
       
   457                 {
       
   458                 iAddedCommands.AppendL( initialCommand );
       
   459                 }
       
   460                 
       
   461             CleanupStack::Pop( initialCommand );  
       
   462             }
       
   463         }
       
   464     
       
   465     if ( aCommit )
       
   466         {
       
   467         iService->AddCommandsL( commands );
       
   468                 
       
   469         // delete cache and force iCommands to be reloaded
       
   470         //
       
   471         DeleteCache();
       
   472         }
       
   473 
       
   474     CleanupStack::PopAndDestroy( &commands );
       
   475     CleanupStack::PopAndDestroy( &commands );
       
   476     }
       
   477     
       
   478 // -----------------------------------------------------------------------------
       
   479 // CVCommandProfileObserver::CreateProfileCommandL
       
   480 // Creates a VCommand for the given profile attributes
       
   481 // -----------------------------------------------------------------------------
       
   482 CVCommand* CVCommandProfileObserver::CreateProfileCommandL( const TDesC& profileName, TInt aProfileId ) const
       
   483         {
       
   484         CVCFolderInfo* folderInfo = CVCFolderInfo::NewL( iFolderTitle->Des(), 
       
   485                                                          iProfileFolder->Des(), 0, 
       
   486                                                          KProfileFolderIconIndex,
       
   487                                                          KIconFile );
       
   488         CleanupStack::PushL( folderInfo );
       
   489         CVCCommandUi* commandUi = CVCCommandUi::NewL( profileName,
       
   490                                                       *folderInfo, ETrue,
       
   491                                                       iProfileTooltip->Des(),
       
   492                                                       KUidAppProfiles );
       
   493         CleanupStack::PopAndDestroy( folderInfo );
       
   494         CleanupStack::PushL( commandUi );
       
   495 
       
   496         TBuf8<10>  idDescriptor;
       
   497         idDescriptor.Num( KProfileCommandArgumentBase + aProfileId );
       
   498         CVCRunnable* runnable = CVCRunnable::NewL( KProfileChangerUid, idDescriptor.Left( idDescriptor.Length() ) );
       
   499         CleanupStack::PushL( runnable );
       
   500     
       
   501         CVCommand* command = CVCommand::NewL( profileName,
       
   502                                               *runnable,
       
   503                                               *commandUi );
       
   504         CleanupStack::PopAndDestroy( runnable );
       
   505         CleanupStack::PopAndDestroy( commandUi );
       
   506         return command;
       
   507         }
       
   508 
       
   509 // -----------------------------------------------------------------------------
       
   510 // CVCommandProfileObserver::RemoveProfileL
       
   511 // Removes profile from VCommandhandler.
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 void CVCommandProfileObserver::RemoveProfileL( const TDesC& aName )
       
   515     {
       
   516     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::RemoveProfileL()" );
       
   517     
       
   518     TInt idx = 0;
       
   519     while( ( idx = FindProfileIndexL( aName ) ) != KErrNotFound )  
       
   520         {
       
   521         iService->RemoveCommandL( ListVCommandsL()[ idx ] );
       
   522         
       
   523         // delete cache and force iCommands to be reloaded
       
   524         //
       
   525         DeleteCache(); 
       
   526         }
       
   527     }
       
   528     
       
   529 // -----------------------------------------------------------------------------
       
   530 // CVCommandProfileObserver::RemoveProfilesL
       
   531 // Removes profiles from VCommandhandler.
       
   532 // -----------------------------------------------------------------------------
       
   533 //
       
   534 void CVCommandProfileObserver::RemoveProfilesL( const CDesC16ArrayFlat& aNames )
       
   535     {
       
   536     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::RemoveProfilesL()" );
       
   537 
       
   538     RVCommandArray commands;
       
   539     CleanupClosePushL( commands );
       
   540     
       
   541     for( TInt i = 0; i < aNames.MdcaCount(); i++ )
       
   542         {
       
   543         TInt idx = 0;
       
   544         while( ( idx = FindProfileIndexL( aNames.MdcaPoint(i) ) ) != KErrNotFound )  
       
   545             {
       
   546             commands.Append( &ListVCommandsL()[ idx ] );
       
   547             break;
       
   548             }
       
   549         }
       
   550 
       
   551     iService->RemoveCommandsL( commands );
       
   552 
       
   553     // delete cache and force iCommands to be reloaded
       
   554     //
       
   555     DeleteCache();
       
   556     
       
   557     CleanupStack::PopAndDestroy( &commands );
       
   558     }
       
   559 
       
   560 
       
   561 // -----------------------------------------------------------------------------
       
   562 // CVCommandProfileObserver::EditProfileNameL
       
   563 // Edits the profile name.
       
   564 // -----------------------------------------------------------------------------
       
   565 //
       
   566 void CVCommandProfileObserver::EditProfileNameL( const TDesC& aOldName, const TDesC& aNewName )
       
   567     {
       
   568     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::EditProfileNameL()" );
       
   569     
       
   570     // Get profile id
       
   571     TInt idx = iNameArray->FindByName( aOldName );
       
   572     TInt profileId = iNameArray->ProfileId( idx );
       
   573     
       
   574     idx = FindProfileIndexL( aOldName );
       
   575     
       
   576     // this finds always user edited one, if one exists
       
   577     //
       
   578     if( idx == KErrNotFound )
       
   579         {
       
   580         // for some reason profile doesn't exist in voice command list
       
   581         // so let's add it
       
   582         //
       
   583         return AddNewProfileL( aNewName, profileId ); 
       
   584         }
       
   585     
       
   586     const CVCommand& oldCmd = ListVCommandsL()[ idx ];
       
   587         
       
   588     CVCCommandUi* commandUi = CVCCommandUi::NewL( aNewName, 
       
   589                                                          oldCmd.CommandUi().FolderInfo(), ETrue, 
       
   590                                                          oldCmd.CommandUi().Tooltip(), 
       
   591                                                          oldCmd.CommandUi().IconUid() );
       
   592     CleanupStack::PushL( commandUi );
       
   593                                                       
       
   594     TBuf8<10>  idDescriptor;
       
   595     idDescriptor.Num( profileId );
       
   596     CVCRunnable* runnable = CVCRunnable::NewL( oldCmd.Runnable() );
       
   597     CleanupStack::PushL( runnable );
       
   598     
       
   599     CVCommand* command = CVCommand::NewL( aNewName, *runnable, *commandUi );
       
   600     CleanupStack::PopAndDestroy( runnable );
       
   601     CleanupStack::PopAndDestroy( commandUi );
       
   602     CleanupStack::PushL( command );
       
   603         
       
   604     // Delete old command
       
   605     iService->RemoveCommandL( oldCmd );
       
   606       
       
   607     // delete cache and force iCommands to be reloaded
       
   608     //
       
   609     DeleteCache(); 
       
   610       
       
   611     while( ( idx = FindProfileIndexL( aOldName ) ) != KErrNotFound ) 
       
   612         {
       
   613         iService->RemoveCommandL( ListVCommandsL()[ idx ] );
       
   614         DeleteCache(); 
       
   615         }
       
   616         
       
   617     // Add new command
       
   618     //    
       
   619     iService->AddCommandL( *command );
       
   620     CleanupStack::PopAndDestroy( command ); 
       
   621     
       
   622     // delete cache and force iCommands to be reloaded
       
   623     //
       
   624     DeleteCache(); 
       
   625     }
       
   626 
       
   627 
       
   628 // ---------------------------------------------------------
       
   629 // CVCommandProfileObserver::FindProfileIndexL
       
   630 // ---------------------------------------------------------
       
   631 //
       
   632 // Assumes that profiles are in a folder called GetProfileFolderName().
       
   633 //
       
   634 // Finds always the user edited command if it exists.
       
   635 //
       
   636 TInt CVCommandProfileObserver::FindProfileIndexL( const TDesC& aName )
       
   637     {
       
   638     RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::FindProfileIndexL()" );
       
   639     
       
   640     TInt retval = KErrNotFound;
       
   641     
       
   642     for( TInt i = 0; i < ListVCommandsL().Count(); i++ ) 
       
   643         {
       
   644         if( ListVCommandsL()[ i ].CommandUi().FolderInfo().Title() == iFolderTitle->Des() && 
       
   645             aName == ListVCommandsL()[ i ].CommandUi().WrittenText() ) 
       
   646             {
       
   647             retval = i;
       
   648             
       
   649             // user edited command
       
   650             //
       
   651             if( ListVCommandsL()[ i ].SpokenText() != 
       
   652                 ListVCommandsL()[ i ].CommandUi().WrittenText() ) 
       
   653                 {
       
   654                 break;
       
   655                 }
       
   656             }
       
   657         }
       
   658     return retval;    
       
   659     }
       
   660 
       
   661 
       
   662 // End of File
       
   663