--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/srsf/vcommandhandler/src/tagnameset.cpp Wed Sep 01 12:29:17 2010 +0100
@@ -0,0 +1,353 @@
+/*
+* Copyright (c) 2006 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: Array of tags and corresponding spoken texts
+*
+*/
+
+
+#include "rubydebug.h"
+#include "tagnameset.h"
+#include <nssvasmspeechitem.h>
+#include <nssvasmtag.h>
+#include <nssvasmtagmgr.h>
+
+_LIT( KTagNameSetPanic, "TNS" );
+
+CTagNameSet* CTagNameSet::NewLC()
+ {
+ CTagNameSet* self = new (ELeave) CTagNameSet;
+ CleanupStack::PushL( self );
+ return self;
+ }
+
+CTagNameSet::~CTagNameSet()
+ {
+ iTags.ResetAndDestroy();
+ iTexts.ResetAndDestroy();
+ }
+
+
+/**
+* Adds a tag-text pair to be trained
+* @param aTag tag to be trained and saved. This objects takes ownership
+* on the aTag
+* @param aTrainingText text to be recognized. This object doesn't
+* take ownership on aTrainingText, but makes an own copy
+*/
+void CTagNameSet::AppendL( const MNssTag* aTag, const TDesC& aTrainingText )
+ {
+ HBufC* text = aTrainingText.AllocL();
+ iTexts.Append( text );
+ iTags.Append( aTag );
+ }
+
+/**
+* Train and save to VAS all the stored tags. It is not specified what happens
+* to VAS if this method leaves
+* @param aParams
+* @param aTagMgr
+* @param aIgnoreErrors If ETrue, doesn't fail the whole operation if some
+* individual trainings/savings failed. Trains and saves as much as
+* possible
+*/
+void CTagNameSet::TrainAndSaveL( const CNssTrainingParameters& aParams,
+ MNssTagMgr& aTagMgr, TBool aIgnoreErrors )
+ {
+ RUBY_DEBUG_BLOCK( "CTrainingPack::TrainAndSaveL" );
+ iIgnoreErrors = aIgnoreErrors;
+ RUBY_DEBUG1( "CTrainingPack::TrainAndSaveL Processing [%d] pairs", iTags.Count() );
+
+ TrainTagsL( aParams );
+ SaveTagsL( aTagMgr );
+ }
+
+/**
+* Remove all the stored tags from VAS. It is not specified what happens
+* to VAS if this method leaves
+* @param aTagMgr
+* @param aIgnoreErrors If ETrue, doesn't fail the whole operation if some
+* individual removals failed. Removes as many tags as
+* possible
+*/
+void CTagNameSet::UntrainL( MNssTagMgr& aTagMgr, TBool aIgnoreErrors )
+ {
+ RUBY_DEBUG_BLOCK("");
+ iIgnoreErrors = aIgnoreErrors;
+ RUBY_DEBUG1( "Removing [%d] tags from VAS", iTags.Count() );
+ SetCallbacksExpected( iTags.Count() );
+
+ if( iCallbacksExpected > 0 )
+ {
+ for( TInt i = 0; i < iTags.Count(); i++ )
+ {
+ DeleteTagL( aTagMgr, *iTags[i] );
+ } // for
+ WaitUntilOperationsAreCompletedL();
+ }
+ }
+
+/**
+* @return Number of tag-name pairs stored
+*/
+TInt CTagNameSet::Count() const
+ {
+ return iTags.Count();
+ }
+
+/**
+* @param aIndex must be >= 0 and < Count()
+* @return Voice tag at the given position
+* @panic KErrArgument if aIndex is out of bounds
+*/
+const MNssTag& CTagNameSet::TagAt( TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0 && aIndex < iTags.Count(),
+ User::Panic( KTagNameSetPanic, KErrArgument ));
+ return *iTags[aIndex];
+ }
+
+/**
+* @param aIndex must be >= 0 and < Count()
+* @return Recognition text at the given position
+* @panic KErrArgument if aIndex is out of bounds
+*/
+const TDesC& CTagNameSet::TextAt( TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0 && aIndex < iTexts.Count(),
+ User::Panic( KTagNameSetPanic, KErrArgument ));
+ return *iTexts[aIndex];
+ }
+
+/**
+* Train all the stored tag-name pairs. Synchronous
+*/
+void CTagNameSet::TrainTagsL( const CNssTrainingParameters& aParams )
+ {
+ __ASSERT_ALWAYS( iCallbacksExpected == 0, User::Leave( KErrInUse) );
+ SetCallbacksExpected( Count() );
+ if( iCallbacksExpected > 0 )
+ {
+ for( TInt i = 0; i < Count(); i++ )
+ {
+ TrainTagL( TagAt( i ), aParams, TextAt( i ) );
+ } // for
+ WaitUntilOperationsAreCompletedL();
+ } // if
+ }
+
+
+/**
+* Trains the voice tag. Asynchronous
+* @leave VAS error code
+* @todo Is it ok to mix system-wide codes with the TNssSpeechItemResult codes
+*/
+void CTagNameSet::TrainTagL( const MNssTag& aTag,
+ const CNssTrainingParameters& aParams, const TDesC& aSpokenText )
+ {
+ RUBY_DEBUG_BLOCKL( "CTagNameSet::TrainTagL" );
+ RUBY_DEBUG1( "Training for spoken text [%S]", &aSpokenText )
+
+ MNssSpeechItem* speechItem = const_cast<MNssTag&>(aTag).SpeechItem();
+ speechItem->SetTextL( aSpokenText );
+ MNssSpeechItem::TNssSpeechItemResult nssErr =
+ speechItem->TrainTextL( this, const_cast<CNssTrainingParameters*>( &aParams ) );
+
+ if ( nssErr != MNssSpeechItem::EVasErrorNone )
+ {
+ RUBY_ERROR1( "CTagNameSet::TrainTagL training start failed with the nss code [%d]",
+ nssErr );
+ if( iIgnoreErrors )
+ {
+ RUBY_DEBUG0( "CTagNameSet::TrainTagL ignoring error" );
+ DecreaseCallbacksExpected();
+ }
+ else
+ {
+ // Wait for started operations before leaving
+ DecreaseCallbacksExpected();
+ WaitUntilOperationsAreCompletedL();
+
+ switch( nssErr )
+ {
+ case MNssSpeechItem::EVasInvalidParameter:
+ User::Leave( KErrArgument );
+ case MNssSpeechItem::EVasTrainFailed:
+ User::Leave( KErrGeneral );
+ default:
+ User::Leave( nssErr );
+ }
+ }
+ }
+ RUBY_DEBUG0( "CTagNameSet::TrainTagL Tag training has been initiated" );
+ }
+
+
+/**
+* Train Complete Event - Voice tag training completed
+* @param aErrorCode KErrNone if training was successfull
+*/
+void CTagNameSet::HandleTrainComplete( TInt aErrorCode )
+ {
+ //RUBY_DEBUG0( "Start" );
+ ProcessCallback( aErrorCode );
+ //RUBY_DEBUG0( "End" );
+ }
+
+/**
+* Saves the trained voice tag to VAS. Synchronous
+*/
+void CTagNameSet::SaveTagsL( MNssTagMgr& aTagManager )
+ {
+ RUBY_DEBUG_BLOCK( "CTagSaver::SaveTagsL" );
+ __ASSERT_ALWAYS( iCallbacksExpected == 0, User::Leave( KErrInUse) );
+ SetCallbacksExpected( Count() );
+ if( iCallbacksExpected > 0 )
+ {
+ for( TInt i = 0; i < Count(); i++ )
+ {
+ SaveTagL( aTagManager, TagAt( i ) );
+ } // for
+
+ WaitUntilOperationsAreCompletedL();
+ } // if
+ }
+
+
+/**
+* Saves the trained voice tag to VAS.
+*/
+void CTagNameSet::SaveTagL( MNssTagMgr& aTagManager, const MNssTag& aTag )
+ {
+ RUBY_DEBUG_BLOCKL( "CTagNameSet::SaveTagL" );
+ TInt nssErr =
+ aTagManager.SaveTag( this, const_cast<MNssTag*>( &aTag ) );
+ if( nssErr != KErrNone )
+ {
+ RUBY_ERROR1( "CTagNameSet::SaveTagL Savetag start failed with the nss code [%d]", nssErr );
+ if( iIgnoreErrors )
+ {
+ RUBY_DEBUG0( "CTagNameSet::SaveTagL ignoring error" );
+ DecreaseCallbacksExpected();
+ }
+ else
+ {
+ // Wait for started operations before leaving
+ DecreaseCallbacksExpected();
+ WaitUntilOperationsAreCompletedL();
+
+ User::Leave( KErrGeneral );
+ }
+ }
+ RUBY_DEBUG0( "CTagNameSet::SaveTagL Savetag sequence started" );
+
+ }
+
+/**
+* Callback to indicate that SaveTag sequence has been completed
+* @param aErrorCode KErrNone if saving of tag was successfull
+*/
+void CTagNameSet::SaveTagCompleted( TInt aErrorCode )
+ {
+ RUBY_DEBUG0( "Start" );
+ ProcessCallback( aErrorCode );
+ RUBY_DEBUG0( "End" );
+ }
+
+/**
+* Deletes the voice tag from VAS. Asynchronous
+* @leave VAS error codes
+*/
+void CTagNameSet::DeleteTagL( MNssTagMgr& aTagManager, MNssTag& aTag )
+ {
+ User::LeaveIfError( aTagManager.DeleteTag( this, &aTag ) );
+ }
+
+/**
+* Callback to indicate a tag was deleted successfully.
+* @param aErrorCode KErrNone if deletion of tag was successfull
+*/
+void CTagNameSet::DeleteTagCompleted( TInt aErrorCode )
+ {
+ RUBY_DEBUG0( "Start" );
+ ProcessCallback( aErrorCode );
+ RUBY_DEBUG0( "End" );
+ }
+
+/**
+* Handles the common part of the callback processing
+* Decrements the number of still expected callbacks and
+* handles the errors according to aIgnoreErrors from the
+* public methods
+*/
+void CTagNameSet::ProcessCallback( TInt aErrorCode )
+ {
+ //RUBY_DEBUG0( "Start" );
+ if( iIgnoreErrors || aErrorCode == KErrNone )
+ {
+ if( DecreaseCallbacksExpected() == 0 )
+ {
+ StopAsyncWaitingOrPanic( KErrNone );
+ }
+ }
+ else
+ {
+ RUBY_ERROR1( "Callback reported error [%d] ", aErrorCode );
+ if( DecreaseCallbacksExpected() == 0 )
+ {
+ StopAsyncWaitingOrPanic( aErrorCode );
+ }
+ }
+ //RUBY_DEBUG0( "End" );
+ }
+
+/**
+* Sets the number of callbacks to expect
+*/
+void CTagNameSet::SetCallbacksExpected (TUint aCallbacksExpected )
+ {
+ RUBY_DEBUG2( "Changing from [%d] to [%d]", iCallbacksExpected, aCallbacksExpected );
+ iCallbacksExpected = aCallbacksExpected;
+ }
+
+/**
+* Decreases the number of callbacks to expect by one
+* @return Number of callbacks expected after decreasing
+*/
+TUint CTagNameSet::DecreaseCallbacksExpected()
+ {
+ __ASSERT_ALWAYS( iCallbacksExpected > 0, User::Panic( KTagNameSetPanic, KErrNotReady ) );
+ RUBY_DEBUG2( "Changing from [%d] to [%d]", iCallbacksExpected, iCallbacksExpected - 1 );
+ return --iCallbacksExpected;
+ }
+
+/**
+* Waits until all the expected callbacks are received
+* If no callbacks are expected returns immediately
+* @leave @see CAsyncWorker::WaitForAsyncCallbackL
+*/
+void CTagNameSet::WaitUntilOperationsAreCompletedL()
+ {
+ RUBY_DEBUG_BLOCK( "" );
+ if( iCallbacksExpected > 0 )
+ {
+ RUBY_DEBUG1( "[%d] callbacks expected. Waiting for them", iCallbacksExpected );
+ WaitForAsyncCallbackL();
+ }
+ else
+ {
+ RUBY_DEBUG0( "no callbacks expected. Returning immediately" );
+ }
+ }
+
+//End of file