diff -r 8ce15fced3a6 -r cad71a31b7fc srsf/profileobserverplugin/src/vcommandprofileobserver.cpp --- a/srsf/profileobserverplugin/src/vcommandprofileobserver.cpp Thu Aug 19 09:56:14 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* -* Copyright (c) 2006-2007 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: implements profile changes handling -* -*/ - - -#include -#include - -#include -#include - -#include -#include // For CleanupResetAndDestroyPushL - -#include "vcommandprofileobserver.h" -#include "rubydebug.h" - - -// ============================ CONSTANTS =============================== - -_LIT( KResourceFile, "z:\\resource\\vcprofileobserver.rsc" ); - -// UID of the profiles application -const TUid KUidAppProfiles = { 0x100058F8 }; - -// Executable for changing profiles. -const TUid KProfileChangerUid = { 0x10281D15 }; - -// Starting id for profile command arguments -const TInt KProfileCommandArgumentBase = 200; - -// File name to read the icon from -_LIT( KIconFile, "Z:\\resource\\apps\\vcommand.mif" ); - -// Index of the profile folder icon in the default folder icon file -// @see CVCFolderIcon::NewL -const TInt KProfileFolderIconIndex = 5; - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::CVCommandProfileObserver -// C++ default constructor can NOT contain any code, that -// might leave. -// ----------------------------------------------------------------------------- -// -CVCommandProfileObserver::CVCommandProfileObserver() - : iProfileUpdateError( EFalse ) - { - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::ConstructL -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::ConstructL() - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::ConstructL()" ); - - iService = CVCommandHandler::NewL(); - - iProfileEngine = ProEngFactory::NewEngineL(); - iNameArray = iProfileEngine->ProfileNameArrayLC(); - CleanupStack::Pop(); // we can't popup C-class with M-class argument - - LoadProfileDataL(); - SyncVCommandProfilesL(); - - // Create the profile engine notify handler only after construction of - // other parts have been completed successfully. This way, should - // construction fail, we avoid the situation where a callback is executed - // on a partially contructed object - iNotifyHandler = ProEngFactory::NewNotifyHandlerL(); - iNotifyHandler->RequestProfileNameArrayNotificationsL( *this ); - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::NewL -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -CVCommandProfileObserver* CVCommandProfileObserver::NewL() - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::NewL()" ); - - CVCommandProfileObserver* self = new( ELeave ) CVCommandProfileObserver(); - - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - - return self; - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::~CVCommandProfileObserver -// Destructor. -// ----------------------------------------------------------------------------- -// -CVCommandProfileObserver::~CVCommandProfileObserver() - { - RUBY_DEBUG0( "CVCommandProfileObserver::~CVCommandProfileObserver()" ); - - if( iProfileEngine ) - { - iProfileEngine->Release(); - } - iProfileEngine = NULL; - - if( iNameArray ) - { - delete iNameArray; - iNameArray = NULL; - } - - DeleteCache(); - - delete iService; - - if ( iNotifyHandler ) - { - iNotifyHandler->CancelProfileNameArrayNotifications(); - } - delete iNotifyHandler; - delete iProfileFolder; - delete iFolderTitle; - delete iProfileTooltip; - - iAddedCommands.ResetAndDestroy(); - iAddedCommands.Close(); - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::SyncVCommandProfilesL -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::SyncVCommandProfilesL() - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::SyncVCommandProfilesL()" ); - - if( !iNameArray || iNameArray->MdcaCount() <= 0 ) - { - return; - } - - // Form the set of commands that should be in - RVCommandArray profileEngineCommands; - CleanupResetAndDestroyPushL( profileEngineCommands ); - for( TInt i = 0; i < iNameArray->MdcaCount(); i++ ) - { - TInt index = iNameArray->FindByName( iNameArray->MdcaPoint( i ) ); - TInt profileId = iNameArray->ProfileId( index ); - CVCommand* command = CreateProfileCommandL( iNameArray->MdcaPoint( i ), profileId ); - profileEngineCommands.AppendL( command ); - } - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - - const CVCommandArray& storedCommands = ListVCommandsL(); - CVCommandArray* deduction = storedCommands.ProduceUntrainSetByRunnablesLC( profileEngineCommands ); - CVCommandArray* addition = storedCommands.ProduceTrainSetByRunnablesLC( profileEngineCommands ); - - iService->RemoveCommandsL( deduction->PointerArray(), ETrue ); - iService->AddCommandsL( addition->PointerArray(), ETrue ); - CleanupStack::PopAndDestroy( addition ); - CleanupStack::PopAndDestroy( deduction ); - - CleanupStack::PopAndDestroy( &profileEngineCommands ); - - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::HandleProfileNameArrayModificationL -// ----------------------------------------------------------------------------- -// -// Assume that there will be only one change each time this function is called. -// -void CVCommandProfileObserver::HandleProfileNameArrayModificationL() - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::HandleProfileNameArrayModificationL()" ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - - // new array of profile names - MProEngProfileNameArray* nameArray = iProfileEngine->ProfileNameArrayLC(); - - // copy profile names to two descriptor arrays - // - CDesC16ArrayFlat* oldNames = new ( ELeave ) CDesCArrayFlat( iNameArray->MdcaCount() ); - CleanupStack::PushL( oldNames ); - - CDesC16ArrayFlat* newNames = new ( ELeave ) CDesCArrayFlat( nameArray->MdcaCount() ); - CleanupStack::PushL( newNames ); - - for( TInt i = 0; i < iNameArray->MdcaCount(); i++ ) - { - oldNames->AppendL( iNameArray->MdcaPoint( i ) ); - } - for( TInt j = 0; j < nameArray->MdcaCount(); j++ ) - { - newNames->AppendL( nameArray->MdcaPoint( j ) ); - } - - - // Find changes by deleting equivalent commands from both descriptor arrays. - // - for( TInt i = 0; i < newNames->MdcaCount(); i++ ) // go through the new names - { - TName searchStr = newNames->MdcaPoint( i ); - TInt index; - - oldNames->Find( searchStr, index, ECmpNormal ); - - if( index != oldNames->MdcaCount() ) // String was found - { - oldNames->Delete( index ); - newNames->Delete( i ); - i--; - } - } - - - // profile name has been edited - // - if( newNames->MdcaCount() == oldNames->MdcaCount() ) - { - - // now we should have a pair of original and changed name - // - if( newNames->MdcaCount() == 1 ) // let's edit the profile name (old name, new name) - { - TRAPD( error, EditProfileNameL( oldNames->MdcaPoint( 0 ), newNames->MdcaPoint( 0 ) ) ); - if ( error == KErrGeneral ) - { - CleanupStack::PopAndDestroy( newNames ); - CleanupStack::PopAndDestroy( oldNames ); - CleanupStack::Pop(); // nameArray ( M-class pointer ) - - delete iNameArray; - iNameArray = nameArray; - - User::Leave( error ); - } - } - } - // new profile(s) has been added - // - else if( newNames->MdcaCount() > oldNames->MdcaCount() ) - { - AddNewProfilesL( *newNames, *nameArray ); - } - // profile(s) has been deleted - // - else - { - RemoveProfilesL( *oldNames ); - } - - // update old profile names - // - CleanupStack::PopAndDestroy( newNames ); - CleanupStack::PopAndDestroy( oldNames ); - CleanupStack::Pop(); // nameArray ( M-class pointer ) - - delete iNameArray; - iNameArray = nameArray; - - if ( iProfileUpdateError ) - { - iProfileUpdateError = EFalse; - - HandleProfileNameArrayModificationL(); - } - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::HandleProfileNameArrayNotificationError -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::HandleProfileNameArrayNotificationError( TInt aError ) - { - RUBY_ERROR1( "HandleProfileNameArrayNotificationError: %d", aError ); - - if ( aError == KErrLocked ) - { - iProfileUpdateError = ETrue; - } - } - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::LoadProfileDataL -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::LoadProfileDataL() - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::LoadProfileDataL()" ); - - RFs fs; - CleanupClosePushL( fs ); - User::LeaveIfError( fs.Connect() ); - - RResourceFile resourceFile; - TResourceReader theReader; - - TFileName name; - name.Append( KResourceFile ); - - BaflUtils::NearestLanguageFile( fs, name ); - - if ( !BaflUtils::FileExists( fs, name ) ) - { - User::Leave( KErrNotFound ); - } - - resourceFile.OpenL( fs, name ); - CleanupClosePushL( resourceFile ); - - // Leaves 'res' to cleanupstack - HBufC8* res = resourceFile.AllocReadLC( VCPROFILEOBSERVERINFO ); - theReader.SetBuffer( res ); - - iProfileFolder = theReader.ReadHBufCL(); - iFolderTitle = theReader.ReadHBufCL(); - iProfileTooltip = theReader.ReadHBufCL(); - - // Cleanup res - CleanupStack::PopAndDestroy( res ); - CleanupStack::PopAndDestroy( &resourceFile ); - CleanupStack::PopAndDestroy( &fs ); - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::ListVCommandsL -// ----------------------------------------------------------------------------- -// -const CVCommandArray& CVCommandProfileObserver::ListVCommandsL() - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::ListVCommandsL()" ); - - if( !iCommands ) - { - iCommands = iService->ListCommandsL(); - } - - return *iCommands; - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::DeleteCache -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::DeleteCache() - { - RUBY_DEBUG0( "CVCommandProfileObserver::DeleteCache()" ); - - // delete cache and force iCommands to be reloaded - // - delete iCommands; - iCommands = NULL; - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::AddNewProfileL -// Adds new profile to VCommandhandler. -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::AddNewProfileL( const TDesC& aNewName, - TInt aProfileId, - TBool aCommit ) - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::AddNewProfileL()" ); - - // if profile name doesn't exists - // - if( FindProfileIndexL( aNewName ) == KErrNotFound ) - { - CVCommand* initialCommand = CreateProfileCommandL( aNewName, aProfileId ); - CleanupStack::PushL( initialCommand ); - - if ( aCommit ) - { - iService->AddCommandL( *initialCommand ); - CleanupStack::PopAndDestroy( initialCommand ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - } - else - { - iAddedCommands.AppendL( initialCommand ); - - CleanupStack::Pop( initialCommand ); - } - } - } - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::AddNewProfilesL -// Adds new profiles to VCommandhandler. -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::AddNewProfilesL( const CDesC16ArrayFlat& aNames, - const MProEngProfileNameArray& aProfileNames, - TBool aCommit ) - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::AddNewProfilesL()" ); - - RVCommandArray commands; - CleanupClosePushL( commands ); - CleanupResetAndDestroyPushL( commands ); - - for( TInt i = 0; i < aNames.MdcaCount(); i++ ) - { - TInt index = aProfileNames.FindByName( aNames.MdcaPoint(i) ); - TInt profileId = aProfileNames.ProfileId( index ); - - // if profile name doesn't exists - // - if( FindProfileIndexL( aNames.MdcaPoint(i) ) == KErrNotFound ) - { - CVCommand* initialCommand = CreateProfileCommandL( aNames.MdcaPoint(i), profileId ); - CleanupStack::PushL( initialCommand ); - - if ( aCommit ) - { - commands.Append( initialCommand ); - } - else - { - iAddedCommands.AppendL( initialCommand ); - } - - CleanupStack::Pop( initialCommand ); - } - } - - if ( aCommit ) - { - iService->AddCommandsL( commands ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - } - - CleanupStack::PopAndDestroy( &commands ); - CleanupStack::PopAndDestroy( &commands ); - } - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::CreateProfileCommandL -// Creates a VCommand for the given profile attributes -// ----------------------------------------------------------------------------- -CVCommand* CVCommandProfileObserver::CreateProfileCommandL( const TDesC& profileName, TInt aProfileId ) const - { - CVCFolderInfo* folderInfo = CVCFolderInfo::NewL( iFolderTitle->Des(), - iProfileFolder->Des(), 0, - KProfileFolderIconIndex, - KIconFile ); - CleanupStack::PushL( folderInfo ); - CVCCommandUi* commandUi = CVCCommandUi::NewL( profileName, - *folderInfo, ETrue, - iProfileTooltip->Des(), - KUidAppProfiles ); - CleanupStack::PopAndDestroy( folderInfo ); - CleanupStack::PushL( commandUi ); - - TBuf8<10> idDescriptor; - idDescriptor.Num( KProfileCommandArgumentBase + aProfileId ); - CVCRunnable* runnable = CVCRunnable::NewL( KProfileChangerUid, idDescriptor.Left( idDescriptor.Length() ) ); - CleanupStack::PushL( runnable ); - - CVCommand* command = CVCommand::NewL( profileName, - *runnable, - *commandUi ); - CleanupStack::PopAndDestroy( runnable ); - CleanupStack::PopAndDestroy( commandUi ); - return command; - } - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::RemoveProfileL -// Removes profile from VCommandhandler. -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::RemoveProfileL( const TDesC& aName ) - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::RemoveProfileL()" ); - - TInt idx = 0; - while( ( idx = FindProfileIndexL( aName ) ) != KErrNotFound ) - { - iService->RemoveCommandL( ListVCommandsL()[ idx ] ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - } - } - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::RemoveProfilesL -// Removes profiles from VCommandhandler. -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::RemoveProfilesL( const CDesC16ArrayFlat& aNames ) - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::RemoveProfilesL()" ); - - RVCommandArray commands; - CleanupClosePushL( commands ); - - for( TInt i = 0; i < aNames.MdcaCount(); i++ ) - { - TInt idx = 0; - while( ( idx = FindProfileIndexL( aNames.MdcaPoint(i) ) ) != KErrNotFound ) - { - commands.Append( &ListVCommandsL()[ idx ] ); - break; - } - } - - iService->RemoveCommandsL( commands ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - - CleanupStack::PopAndDestroy( &commands ); - } - - -// ----------------------------------------------------------------------------- -// CVCommandProfileObserver::EditProfileNameL -// Edits the profile name. -// ----------------------------------------------------------------------------- -// -void CVCommandProfileObserver::EditProfileNameL( const TDesC& aOldName, const TDesC& aNewName ) - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::EditProfileNameL()" ); - - // Get profile id - TInt idx = iNameArray->FindByName( aOldName ); - TInt profileId = iNameArray->ProfileId( idx ); - - idx = FindProfileIndexL( aOldName ); - - // this finds always user edited one, if one exists - // - if( idx == KErrNotFound ) - { - // for some reason profile doesn't exist in voice command list - // so let's add it - // - return AddNewProfileL( aNewName, profileId ); - } - - const CVCommand& oldCmd = ListVCommandsL()[ idx ]; - - CVCCommandUi* commandUi = CVCCommandUi::NewL( aNewName, - oldCmd.CommandUi().FolderInfo(), ETrue, - oldCmd.CommandUi().Tooltip(), - oldCmd.CommandUi().IconUid() ); - CleanupStack::PushL( commandUi ); - - TBuf8<10> idDescriptor; - idDescriptor.Num( profileId ); - CVCRunnable* runnable = CVCRunnable::NewL( oldCmd.Runnable() ); - CleanupStack::PushL( runnable ); - - CVCommand* command = CVCommand::NewL( aNewName, *runnable, *commandUi ); - CleanupStack::PopAndDestroy( runnable ); - CleanupStack::PopAndDestroy( commandUi ); - CleanupStack::PushL( command ); - - // Delete old command - iService->RemoveCommandL( oldCmd ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - - while( ( idx = FindProfileIndexL( aOldName ) ) != KErrNotFound ) - { - iService->RemoveCommandL( ListVCommandsL()[ idx ] ); - DeleteCache(); - } - - // Add new command - // - iService->AddCommandL( *command ); - CleanupStack::PopAndDestroy( command ); - - // delete cache and force iCommands to be reloaded - // - DeleteCache(); - } - - -// --------------------------------------------------------- -// CVCommandProfileObserver::FindProfileIndexL -// --------------------------------------------------------- -// -// Assumes that profiles are in a folder called GetProfileFolderName(). -// -// Finds always the user edited command if it exists. -// -TInt CVCommandProfileObserver::FindProfileIndexL( const TDesC& aName ) - { - RUBY_DEBUG_BLOCK( "CVCommandProfileObserver::FindProfileIndexL()" ); - - TInt retval = KErrNotFound; - - for( TInt i = 0; i < ListVCommandsL().Count(); i++ ) - { - if( ListVCommandsL()[ i ].CommandUi().FolderInfo().Title() == iFolderTitle->Des() && - aName == ListVCommandsL()[ i ].CommandUi().WrittenText() ) - { - retval = i; - - // user edited command - // - if( ListVCommandsL()[ i ].SpokenText() != - ListVCommandsL()[ i ].CommandUi().WrittenText() ) - { - break; - } - } - } - return retval; - } - - -// End of File -