phonebookui/Phonebook2/remotecontactlookup/engine/src/cpbkxrclserviceuicontextimpl.cpp
Add missing IMPORT_C to two functions, to match the EXPORT_C in the corresponding cpp files
/*
* Copyright (c) 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: Implementation of the class CPbkxRclServiceUiContextImpl.
*
*/
#include "emailtrace.h"
#include <pbk2rclengine.rsg>
#include <cntfldst.h>
#include <StringLoader.h>
#include <CPbkContactEngine.h>
#include <bautils.h>
#include <textresolver.h>
#include "fsccontactactionservicedefines.h"
#include <data_caging_path_literals.hrh>
#include <AknsUtils.h>
#include <hlplch.h>
#include "cpbkxrclserviceuicontextimpl.h"
#include "pbkxremotecontactlookuppanic.h"
#include <cpbkxremotecontactlookupprotocolsession.h>
#include <cpbkxremotecontactlookupprotocoladapter.h>
#include <cpbkxremotecontactlookupprotocolaccount.h>
#include "cpbkxrclprotocolenvimpl.h"
#include "cpbkxrclsearchresultdlg.h"
#include "cpbkxrclresultinfodlg.h"
#include "cpbkxrclqueryeditor.h"
#include "cpbkxrclactionservicewrapper.h"
#include "pbkxrclutils.h"
#include "pbkxrclengineconstants.h"
#include "engine.hrh"
#include <aknnotewrappers.h>
/// Unnamed namespace for local definitions
namespace {
const TInt KTwoMinutesTimerInterval(120000000);
} /// namespace
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::NewL
// ---------------------------------------------------------------------------
//
CPbkxRclServiceUiContextImpl* CPbkxRclServiceUiContextImpl::NewL(
TPbkxRemoteContactLookupProtocolAccountId aId,
TMode aMode )
{
FUNC_LOG;
CPbkxRclServiceUiContextImpl* context =
CPbkxRclServiceUiContextImpl::NewLC( aId, aMode );
CleanupStack::Pop( context );
return context;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::NewLC
// ---------------------------------------------------------------------------
//
CPbkxRclServiceUiContextImpl* CPbkxRclServiceUiContextImpl::NewLC(
TPbkxRemoteContactLookupProtocolAccountId aId,
TMode aMode )
{
FUNC_LOG;
CPbkxRclServiceUiContextImpl* context =
new ( ELeave ) CPbkxRclServiceUiContextImpl( aId, aMode );
CleanupStack::PushL( context );
context->ConstructL();
return context;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::CPbkxRclServiceUiContextImpl
// ---------------------------------------------------------------------------
//
CPbkxRclServiceUiContextImpl::CPbkxRclServiceUiContextImpl(
TPbkxRemoteContactLookupProtocolAccountId aId,
TMode aMode ) :
iAccountId( aId ), iMode( aMode ), iSelectedIndex( KErrNotFound )
{
FUNC_LOG;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::~CPbkxRclServiceUiContextImpl
// ---------------------------------------------------------------------------
//
CPbkxRclServiceUiContextImpl::~CPbkxRclServiceUiContextImpl()
{
FUNC_LOG;
if( iTimer )
{
iTimer->Cancel();
}
delete iTimer;
iQueryText.Close();
iQueryCriteria.Close();
CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset );
iContactCards.Reset();
iSearchResults.ResetAndDestroy();
iWaitObjects.ResetAndDestroy();
delete iContactEngine;
delete iActionServiceWrapper;
delete iAccount;
delete iSession;
delete iAdapter;
delete iEnvImpl;
delete iEventScheduler;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ConstructL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::ConstructL()
{
FUNC_LOG;
CCoeEnv* coeEnv = CCoeEnv::Static();
TFileName dllFileName;
Dll::FileName( dllFileName );
TParse parse;
parse.Set( KResourceFile, &KDC_APP_RESOURCE_DIR, &dllFileName );
TFileName resourceFile = parse.FullName();
BaflUtils::NearestLanguageFile( coeEnv->FsSession(), resourceFile );
TRAPD( status,
iResourceFileOffset = coeEnv->AddResourceFileL( resourceFile ) );
if( status != KErrNone )
{
PbkxRclPanic( EPbkxRclPanicGeneral );
}
else
{
}
// create default contact engine to use to create CPbkContactItems
iContactEngine = CPbkContactEngine::NewL();
// create actions service wrapper used by UI views
iActionServiceWrapper = CPbkxRclActionServiceWrapper::NewL( *iContactEngine );
iActionServiceWrapper->SetContactSelectorMode(
iMode == EModeContactSelector );
// Create objects needed for executing the search
iEnvImpl = CPbkxRclProtocolEnvImpl::NewL();
iAdapter = CPbkxRemoteContactLookupProtocolAdapter::NewL(
iAccountId.iProtocolUid,
*iEnvImpl );
iAccount = iAdapter->NewProtocolAccountL( iAccountId );
if ( iAccount == NULL )
{
User::Leave( KErrNotFound );
}
iSession = iAdapter->NewSessionL();
iSession->InitializeL( *this, iAccountId );
iEventScheduler = CPbkxRclEventScheduler::NewL( *this );
iTimer = CPeriodic::NewL( CActive::EPriorityIdle );
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::GetSelectedContactL
// ---------------------------------------------------------------------------
//
CContactItem* CPbkxRclServiceUiContextImpl::GetSelectedContactL()
{
FUNC_LOG;
__ASSERT_ALWAYS( iSelectedIndex >= 0 && iSelectedIndex < iContactCards.Count(),
PbkxRclPanic( EPbkxRclPanicGeneral ) );
CContactCard* selected = iContactCards[iSelectedIndex];
CContactCard* copy = CContactCard::NewL( selected );
return copy;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::GetResultByIndex
// ---------------------------------------------------------------------------
//
CPbkxRemoteContactLookupProtocolResult*
CPbkxRclServiceUiContextImpl::GetResultByIndex( TInt aIndex )
{
__ASSERT_ALWAYS( aIndex >= 0 && aIndex < iContactCards.Count(),
PbkxRclPanic( EPbkxRclPanicGeneral ) );
CContactCard* card = iContactCards[aIndex];
CPbkxRemoteContactLookupProtocolResult* result = NULL;
for ( TInt i = 0; i < iSearchResults.Count(); i++ )
{
if ( card == &( iSearchResults[i]->ContactItem() ) )
{
result = iSearchResults[i];
break;
}
}
__ASSERT_ALWAYS( result != NULL, PbkxRclPanic( EPbkxRclPanicGeneral ) );
return result;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ExecuteL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::ExecuteL( const TDesC& aQueryText, TResult& aResult )
{
FUNC_LOG;
// set state as initial
ResetState();
SetState( EInitial );
iExitCode = KErrNone;
iSearchResults.ResetAndDestroy();
iQueryCriteria.Close();
iQueryCriteria.CreateL( KRclQueryTextMaxLength );
iQueryCriteria = aQueryText.Left( KRclQueryTextMaxLength );
iResult = &aResult;
TOperation op = ( iMode != EModeExistingCriteria ) ?
EOpenSearchQueryDefault : EExecuteSearchWithNoQuery;
AddOperation( op );
StartActiveWaitL( EMainWait );
HandleContextExitL();
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::LooseSearchCompleted
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::LooseSearchCompleted(
TInt aStatus,
RPointerArray<CPbkxRemoteContactLookupProtocolResult>& aResults )
{
FUNC_LOG;
TRAPD( err, DoLooseSearchCompletedL( aStatus, aResults ) );
if ( err != KErrNone )
{
HandleError( err );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ContactFieldsRetrievalCompleted
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::ContactFieldsRetrievalCompleted( TInt aStatus )
{
FUNC_LOG;
TRAPD( err, DoContactFieldsRetrievalCompletedL( aStatus ) );
if ( err != KErrNone )
{
HandleError( err );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::RetrieveDetailsL
// ---------------------------------------------------------------------------
//
CContactCard* CPbkxRclServiceUiContextImpl::RetrieveDetailsL(
TInt aContactIndex,
const TDesC& aWaitNoteText )
{
FUNC_LOG;
CPbkxRemoteContactLookupProtocolResult* result = GetResultByIndex( aContactIndex );
CContactCard* card = static_cast<CContactCard*>( &result->ContactItem() );
if ( !result->IsComplete() )
{
RPointerArray<CPbkxRemoteContactLookupProtocolResult> array;
CleanupClosePushL( array );
array.AppendL( result );
iSession->RetrieveContactFieldsL( array );
// Start time for time out event
iTimer->Start(
KTwoMinutesTimerInterval, KTwoMinutesTimerInterval,
TCallBack(TimerCallBack, this));
DisplayWaitDialogL( R_RCL_SEARCH_WAIT_DIALOG_CANCEL, aWaitNoteText );
// Start active wait. When contact retrieval is completed,
// ContactFieldsRetrievalCompleted is called. If user cancels
// retrieval, DialogDismissedL is called. TimeOut is called when time is out.
StartActiveWaitL( EContactRetrievalWait );
CleanupStack::PopAndDestroy( &array );
// if contact retrieval was canceledor retrieval failed,
// result is not yet complete
if ( !result->IsComplete() )
{
card = NULL;
}
}
return card;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ContactCount
// ---------------------------------------------------------------------------
//
TInt CPbkxRclServiceUiContextImpl::ContactCount() const
{
FUNC_LOG;
return iContactCards.Count();
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::SetSelectedContact
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::SetSelectedContactL( TInt aIndex )
{
FUNC_LOG;
iSearchResultDialog->SetCurrentItemIndexL( aIndex );
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::EventTriggered
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::EventTriggered()
{
FUNC_LOG;
TRAPD( err, DoHandleOperationL() );
if ( err != KErrNone )
{
HandleError( err );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ProcessCommandL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::ProcessCommandL( TInt aCommandId )
{
FUNC_LOG;
// some commands are handled the same way no matter which dialog is on top
TBool handled = ETrue;
switch ( aCommandId )
{
case ERclCmdVoiceCall:
iActionServiceWrapper->ExecuteActionL(
KFscAtComCallGSM );
break;
case ERclCmdVideoCall:
iActionServiceWrapper->ExecuteActionL(
KFscAtComCallVideo );
break;
case ERclCmdVoip:
iActionServiceWrapper->ExecuteActionL(
KFscAtComCallVoip );
break;
case ERclCmdSendMsg:
iActionServiceWrapper->ExecuteActionL(
KFscAtComSendMsg );
break;
case ERclCmdSendEmail:
iActionServiceWrapper->ExecuteActionL(
KFscAtComSendEmail );
break;
case ERclCmdSendMeetingReq:
iActionServiceWrapper->ExecuteActionL(
KFscAtComSendCalReq );
break;
case ERclCmdSendAudioMsg:
iActionServiceWrapper->ExecuteActionL(
KFscAtComSendAudio );
break;
case ERclCmdToContact:
iActionServiceWrapper->ExecuteActionL(
KFscAtComCallPoc );
break;
case ERclCmdSendBusinessCard:
iActionServiceWrapper->ExecuteActionL(
KFscAtSendBusinessCard );
break;
case ERclCmdHelp:
{
CCoeAppUi* appUi = CCoeEnv::Static()->AppUi();
CArrayFix<TCoeHelpContext>* contexts = appUi->AppHelpContextL();
HlpLauncher::LaunchHelpApplicationL(
CCoeEnv::Static()->WsSession(),
contexts );
}
break;
default:
handled = EFalse;
break;
}
if ( !handled )
{
if ( IsStateSet( EResultDlgOnTop ) )
{
switch ( aCommandId )
{
case ERclCmdAddAsRecipient:
// close the dialog, selected contact is stored in iSelectedContact
AddOperation( ECloseSearchResultDlg );
SetState( EReturnToCaller );
SetState( EResultSelected );
break;
case ERclCmdViewDetails:
AddOperation( EOpenResultInfoDlg );
break;
case ERclCmdNewSearch:
// open empty search query
AddOperation( EOpenSearchQueryEmpty );
break;
case ERclCmdNewSearchPrefilled:
// open empty search query
AddOperation( EOpenSearchQueryDefault );
break;
case ERclCmdSaveToContacts:
{
// first retrieve all the details
HBufC* waitNoteText = StringLoader::LoadLC(
R_QTN_RCL_SAVING_WAIT_NOTE );
if ( RetrieveDetailsL(
iSearchResultDialog->CurrentItemIndex(),
*waitNoteText ) != NULL )
{
iActionServiceWrapper->ExecuteActionL(
KFscAtManSaveAs );
// in contact selector mode, return to the calling
// application
if ( iMode == EModeContactSelector )
{
AddOperation( ECloseSearchResultDlg );
SetState( EReturnToCaller );
SetState( EResultSelected );
}
}
CleanupStack::PopAndDestroy( waitNoteText );
}
break;
case EAknCmdExit:
iResult->iExitReason = TResult::EExitApplication;
AddOperation( ECloseSearchResultDlg );
SetState( EReturnToCaller );
break;
default:
break;
}
}
else if ( IsStateSet( EInfoDlgOnTop ) )
{
switch ( aCommandId )
{
case ERclCmdAddAsRecipient:
// close both dialogs, selected contact is in iSelectedContact
AddOperation( ECloseResultInfoDlg );
AddOperation( ECloseSearchResultDlg );
SetState( EResultSelected );
SetState( EReturnToCaller );
break;
case ERclCmdSendCallbackReq:
iResultInfoDialog->SendCallbackRequestL();
break;
case ERclCmdAddToContacts:
iActionServiceWrapper->ExecuteActionL(
KFscAtManSaveAs );
// in contact selector mode, return to the calling
// application
if ( iMode == EModeContactSelector )
{
AddOperation( ECloseResultInfoDlg );
AddOperation( ECloseSearchResultDlg );
SetState( EReturnToCaller );
SetState( EResultSelected );
}
break;
case ERclCmdSendBusinessCard:
iActionServiceWrapper->ExecuteActionL(
KFscAtSendBusinessCard );
break;
case EAknCmdExit:
// again close both dialogs
AddOperation( ECloseResultInfoDlg );
AddOperation( ECloseSearchResultDlg );
SetState( EReturnToCaller );
iResult->iExitReason = TResult::EExitApplication;
break;
case ERclCmdCopyDetail:
iResultInfoDialog->CopyDetailToClipboardL(
iActionServiceWrapper->ContactManager() );
break;
default:
break;
}
}
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DialogDismissedL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DialogDismissedL( TInt aButtonId )
{
FUNC_LOG;
if ( aButtonId == EAknSoftkeyCancel )
{
// Action was canceled. Don't need to inform about errors
iExitCode = KErrNone;
// cancel search or detail retrieval
if (iSession)
{
iSession->Cancel();
}
// cancel time out timer
if (iTimer)
{
iTimer->Cancel();
}
// do actions based on state
if ( IsStateSet( EInitial ) )
{
if ( iMode != EModeExistingCriteria )
{
// show new search query dialog
AddOperation( EOpenSearchQueryDefault );
}
else
{
// with existing criteria, exit
AddOperation( EExit );
}
}
else if ( IsStateSet( EResultDlgOnTop ) || IsStateSet( EInfoDlgOnTop ) )
{
StopActiveWait( EContactRetrievalWait );
}
}
else
{
// wait dialog closed by itself. exit now if exiting
if ( IsStateSet( EReturnToCaller ) &&
( IsStateSet( EResultSelected ) || IsStateSet( EInitial ) ) )
{
AddOperation( EExit );
}
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ExecuteSearchL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::ExecuteSearchL(
TBool aShowQueryDialog,
const TDesC& aQueryText )
{
FUNC_LOG;
iQueryText.Close();
iQueryText.CreateMaxL( KRclQueryTextMaxLength );
iQueryText = aQueryText;
TBool result = EFalse;
if ( aShowQueryDialog )
{
CPbkxRclQueryEditor* queryEditor = CPbkxRclQueryEditor::NewL(
iAccount->Name(),
iQueryText );
result = queryEditor->ExecuteDialogLD();
// save initial query text given by user
iQueryCriteria = iQueryText;
}
else
{
result = ETrue;
}
if ( result )
{
// Start time for time out event
iTimer->Start(
KTwoMinutesTimerInterval, KTwoMinutesTimerInterval,
TCallBack(TimerCallBack, this));
// execute search based on query text
// use KMaxMatches + 1 to be able to catch "too many results error"
iSession->LooseSearchL( iQueryText, KMaxMatches + 1 );
HBufC* text = StringLoader::LoadLC( R_QTN_RCL_SEARCH_WAIT_NOTE, iQueryText );
DisplayWaitDialogL( R_RCL_SEARCH_WAIT_DIALOG_CANCEL, *text );
CleanupStack::PopAndDestroy( text );
}
else
{
if ( !IsStateSet( EResultDlgOnTop ) )
{
AddOperation( EExit );
} // otherwise just return to search result dlg
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DisplayWaitDialogL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DisplayWaitDialogL(
TInt aDialogResourceId,
const TDesC& aText )
{
FUNC_LOG;
iWaitDialog = new ( ELeave ) CAknWaitDialog( NULL, ETrue );
iWaitDialog->SetTextL( aText );
iWaitDialog->SetCallback( this );
iWaitDialog->ExecuteLD( aDialogResourceId );
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DisplayNoteDialogL
// ---------------------------------------------------------------------------
//
TBool CPbkxRclServiceUiContextImpl::DisplayNoteDialogL(
TInt aDialogResourceId,
const TDesC& aText,
TBool aTimeout )
{
FUNC_LOG;
CAknNoteDialog* dialog = NULL;
if ( aTimeout )
{
dialog = new ( ELeave ) CAknNoteDialog(
CAknNoteDialog::ENoTone,
CAknNoteDialog::ELongTimeout );
}
else
{
dialog = new ( ELeave ) CAknNoteDialog();
}
dialog->PrepareLC( aDialogResourceId );
dialog->SetTextL( aText );
TBool ret = ( TBool )dialog->RunLD();
return ret;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DisplayQueryDialogL
// ---------------------------------------------------------------------------
//
//Fix for: EASV-7KFGG3
TBool CPbkxRclServiceUiContextImpl::DisplayQueryDialogL(
TInt aDialogResourceId,
const TDesC& aText )
{
FUNC_LOG;
CAknQueryDialog* dialog = NULL;
dialog = new ( ELeave ) CAknQueryDialog();
dialog->PrepareLC( aDialogResourceId );
dialog->SetPromptL( aText );
TBool ret = ( TBool )dialog->RunLD();
return ret;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::CloseWaitDialogL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::CloseWaitDialogL()
{
FUNC_LOG;
if (iWaitDialog)
{
iWaitDialog->ProcessFinishedL();
iWaitDialog = NULL;
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DisplaySearchResultDialogL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DisplaySearchResultDialogL(TBool aShowTooManyResultsNote)
{
FUNC_LOG;
if ( iSearchResultDialog == NULL )
{
// no search result dialog on screen, show new one
// result array holds list box items and it is filled inside search
// result dialog
CDesCArrayFlat* resultArray =
new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
CleanupStack::PushL( resultArray );
TBool contactSelectorEnabled = iMode == EModeContactSelector;
iSearchResultDialog = CPbkxRclSearchResultDlg::NewL(
iSelectedIndex,
resultArray,
this,
iContactCards,
*iContactEngine,
*iActionServiceWrapper,
contactSelectorEnabled,
aShowTooManyResultsNote);
UnsetState( EInitial );
SetState( EResultDlgOnTop );
// set action service mode
iActionServiceWrapper->SetActionMenuMode( ETrue );
iSearchResultDialog->ExecuteLD();
iActionServiceWrapper->SetActionMenuMode( EFalse );
iSearchResultDialog = NULL;
CleanupStack::PopAndDestroy( resultArray );
HandleSearchResultDialogExitL();
UnsetState( EResultDlgOnTop );
SetState( EInitial );
}
else
{ // iSearchResultDialog != NULL
iSearchResultDialog->UpdateDialogL();
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DisplayResultInfoDialogL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DisplayResultInfoDialogL()
{
FUNC_LOG;
// items array holds the list box items in result info dialog and it is filled
// result info dialog
CDesCArrayFlat* items = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
CleanupStack::PushL( items );
TInt index = 0;
TBool contactSelectorEnabled = iMode == EModeContactSelector;
TInt itemIndex = iSearchResultDialog->CurrentItemIndex();
// creation fails if item details cannot be retrieved or user cancels
// retrieval
iResultInfoDialog = CPbkxRclResultInfoDlg::NewL(
index,
items,
this,
this,
*iContactEngine,
*iActionServiceWrapper,
contactSelectorEnabled,
itemIndex );
UnsetState( EResultDlgOnTop );
SetState( EInfoDlgOnTop );
// set action service mode
iActionServiceWrapper->SetActionMenuMode( EFalse );
//Fix for: PKAO-7NNCJ2
if ( iSearchResultDialog )
{
iSearchResultDialog->InfoDlgVisible( ETrue );
}
iResultInfoDialog->ExecuteLD();
// update action service since now search result dialog is on top
iActionServiceWrapper->SetActionMenuMode( ETrue );
if ( !IsStateSet( EReturnToCaller ) && iResult->iExitReason != TResult::EExitApplication )
{
iSearchResultDialog->SetCurrentContactToActionServiceL();
}
//Fix for: PKAO-7NNCJ2
if ( iSearchResultDialog )
{
iSearchResultDialog->InfoDlgVisible( EFalse );
}
iResultInfoDialog = NULL;
UnsetState( EInfoDlgOnTop );
SetState( EResultDlgOnTop );
CleanupStack::PopAndDestroy( items );
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::CreateContactCardArray
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::CreateContactCardArray()
{
FUNC_LOG;
// remove possible old contact cards
iContactCards.Reset();
for ( TInt i = 0; i < iSearchResults.Count(); i++ )
{
CContactItem& item = iSearchResults[i]->ContactItem();
CContactCard* card = dynamic_cast<CContactCard*>( &item );
if ( card != NULL )
{
iContactCards.Append( card );
}
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DoLooseSearchCompletedL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DoLooseSearchCompletedL(
TInt aStatus,
RPointerArray<CPbkxRemoteContactLookupProtocolResult>& aResults )
{
FUNC_LOG;
// cancel time out timer
if (iTimer)
{
iTimer->Cancel();
}
CloseWaitDialogL();
if ( aStatus == KErrNone )
{
TInt origCount = aResults.Count();
// delete old results
iSearchResults.ResetAndDestroy();
TInt count = aResults.Count() <= KMaxMatches ? aResults.Count() : KMaxMatches;
for ( TInt i = 0; i < count; i++ )
{
iSearchResults.AppendL( aResults[i] );
}
// delete the extra results
for ( TInt j = aResults.Count() - 1; j >= KMaxMatches; j-- )
{
delete aResults[j];
aResults.Remove( j );
}
CreateContactCardArray();
TLinearOrder<CContactCard> sort( CPbkxRclServiceUiContextImpl::Sort );
iContactCards.Sort( sort );
if ( origCount > KMaxMatches )
{
AddOperation( EOpenSearchResultDlgTooManyResults );
}
else
{
AddOperation( EOpenSearchResultDlg );
}
}
else
{
// reset the array just in case
aResults.ResetAndDestroy();
// remote contact lookup failed, exit
HandleError( aStatus );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DoContactFieldsRetrievalCompletedL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DoContactFieldsRetrievalCompletedL( TInt aStatus )
{
FUNC_LOG;
// cancel time out timer
if (iTimer)
{
iTimer->Cancel();
}
StopActiveWait( EContactRetrievalWait );
CloseWaitDialogL();
if ( aStatus != KErrNone )
{
// error occurred, so contact is not complete. this is checked
// in RetrieveContactDetailsL method and it returns NULL
// to the caller
// exit application
HandleError( aStatus );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::DoHandleOperationL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::DoHandleOperationL()
{
FUNC_LOG;
if ( iOperations.Count() > 0 )
{
TOperation operation = iOperations.Pop();
switch ( operation )
{
case EOpenSearchResultDlgTooManyResults:
DisplaySearchResultDialogL( ETrue );
break;
case EOpenSearchResultDlg:
DisplaySearchResultDialogL( EFalse );
break;
case EOpenResultInfoDlg:
DisplayResultInfoDialogL();
break;
case ECloseSearchResultDlg:
if ( iSearchResultDialog != NULL )
{
iSearchResultDialog->Close();
}
break;
case ECloseResultInfoDlg:
if ( iResultInfoDialog != NULL )
{
iResultInfoDialog->Close();
}
break;
case EOpenSearchQueryDefault:
ExecuteSearchL( ETrue, iQueryCriteria );
break;
case EOpenSearchQueryEmpty:
ExecuteSearchL( ETrue, KNullDesC );
break;
case EExecuteSearchWithNoQuery:
ExecuteSearchL( EFalse, iQueryCriteria );
break;
case EExit:
StopActiveWait( EMainWait );
break;
default:
PbkxRclPanic( EPbkxRclPanicGeneral );
break;
}
if ( iOperations.Count() > 0 )
{
iEventScheduler->TriggerEvent();
}
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::HandleSearchResultDialogExitL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::HandleSearchResultDialogExitL()
{
FUNC_LOG;
// this flag is set if wait dialog on the screen and we cannot exit before
// wait dialog is closed itself
TBool waitDlgOnScreen = EFalse;
if ( IsStateSet( EResultSelected ) )
{
// if contact details are not retrieved, we must do that before exiting
CPbkxRemoteContactLookupProtocolResult* result = GetResultByIndex( iSelectedIndex );
if ( !result->IsComplete() )
{
HBufC* text = StringLoader::LoadLC( R_QTN_RCL_RETRIEVAL_WAIT_NOTE );
RetrieveDetailsL( iSelectedIndex, *text );
CleanupStack::PopAndDestroy( text );
// if wait dialog is NULL, it is closed by CloseWaitDialogL method
// and not by user. so it is still on the screen
waitDlgOnScreen = iWaitDialog == NULL;
// make sure we succeeded in detail retrieving. if not, return nothing.
if ( result->IsComplete() )
{
iResult->iSelectedContactItem = GetSelectedContactL();
}
}
else
{
iResult->iSelectedContactItem = GetSelectedContactL();
}
}
if ( !waitDlgOnScreen )
{
// exit
AddOperation( EExit );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::HandleContextExitL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::HandleContextExitL()
{
FUNC_LOG;
// set exit reason
if ( iResult->iExitReason == TResult::EExitUndefined )
{
if ( iExitCode != KErrNone )
{
iResult->iExitReason = TResult::EExitError;
}
else if ( iResult->iSelectedContactItem != NULL )
{
iResult->iExitReason = TResult::EExitContactSelected;
}
else
{
iResult->iExitReason = TResult::EExitUserClosed;
}
}
if ( iExitCode != KErrNone )
{
// show error note
CTextResolver* resolver = CTextResolver::NewLC( *( CCoeEnv::Static() ) );
// on return, contains information about the loaded error text
TUint textFlags;
TInt textId;
const TDesC& errorText = resolver->ResolveErrorString(
iExitCode,
textId,
textFlags,
CTextResolver::ECtxNoCtxNoSeparator );
if ( textFlags & EErrorResBlankErrorFlag ||
textFlags & ETextResolverUnknownErrorFlag )
{
// show general error message, because there was no good error
// message available
HBufC* text = StringLoader::LoadLC( R_QTN_RCL_ERROR_NOTE );
DisplayNoteDialogL( R_RCL_WARNING_NOTE, *text, ETrue );
CleanupStack::PopAndDestroy( text );
}
else
{
DisplayNoteDialogL( R_RCL_WARNING_NOTE, errorText, ETrue );
}
CleanupStack::PopAndDestroy( resolver );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::StartActiveWaitL
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::StartActiveWaitL( TWaitObjectIndex aIndex )
{
FUNC_LOG;
if ( aIndex != iWaitObjects.Count() )
{
// wait object index invalid, panic
PbkxRclPanic( EPbkxRclPanicGeneral );
}
// starts new active wait and appends it in the list of wait objects
CActiveSchedulerWait* wait = new ( ELeave ) CActiveSchedulerWait();
CleanupStack::PushL( wait );
iWaitObjects.AppendL( wait );
CleanupStack::Pop( wait );
wait->Start();
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::StopActiveWait
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::StopActiveWait( TWaitObjectIndex aIndex )
{
FUNC_LOG;
if ( (aIndex + 1) == iWaitObjects.Count() )
{
// stops active wait of the most recently started wait
CActiveSchedulerWait* wait = iWaitObjects[aIndex];
iWaitObjects.Remove( aIndex );
wait->AsyncStop();
delete wait;
}
else if ( (aIndex + 1) < iWaitObjects.Count() )
{
// Panic = always the of the most recently started wait
// needs to be stopped first
PbkxRclPanic( EPbkxRclPanicGeneral );
}
else
{
// aIndex + 1 > iWaitObjects.Count() --> wait object already cancelled.
// Don't do anything. No reason to panic here.
}
// ----
// Old implementation below expected that it is illegal to stop a wait object that is
// already stopped. Example: calling from DialogDismissedL and DoContactFieldsRetrievalCompletedL
// concurrently caused panic. To fix that and other possible similar cases - changed
// so that it is always safe to try stop the most recently started wait wait object
// ---
// if ( iWaitObjects.Count() != aIndex + 1 )
// {
// // invalid wait object count, panic
// PbkxRclPanic( EPbkxRclPanicGeneral );
// }
//
// // stops active wait of the most recently started wait
// CActiveSchedulerWait* wait = iWaitObjects[aIndex];
// iWaitObjects.Remove( aIndex );
// wait->AsyncStop();
// delete wait;
//
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::SetState
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::SetState( TState aState )
{
FUNC_LOG;
iState |= aState;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::UnsetState
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::UnsetState( TState aState )
{
FUNC_LOG;
iState &= ~aState;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::IsStateSet
// ---------------------------------------------------------------------------
//
TBool CPbkxRclServiceUiContextImpl::IsStateSet( TState aState )
{
FUNC_LOG;
return ( iState & aState ) != 0;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::ResetState
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::ResetState()
{
FUNC_LOG;
iState = 0;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::AddOperation
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::AddOperation( TOperation aOperation )
{
FUNC_LOG;
if ( EExit == aOperation )
{
iExitTriggerred = ETrue;
}
iOperations.Add( aOperation );
iEventScheduler->TriggerEvent();
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::HandleError
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::HandleError( TInt aError )
{
FUNC_LOG;
iExitCode = aError;
SetState( EReturnToCaller );
if ( IsStateSet( EInfoDlgOnTop ) )
{
AddOperation( ECloseResultInfoDlg );
AddOperation( ECloseSearchResultDlg );
}
else if ( IsStateSet( EResultDlgOnTop ) )
{
AddOperation( ECloseSearchResultDlg );
}
// If dialog is NULL and state is EInitial & EReturnToCaller
// EExit operation is added in DialogDismissedL callback
if ( !iWaitDialog && IsStateSet( EInitial ) && IsStateSet( EReturnToCaller ) )
{
//for some erros DialogDismissedL() doesnt trigger Exit Event
//So Check if the exit was Triggerred or Not, if not then trigger the Exit Event.
if ( !iExitTriggerred )
{
AddOperation( EExit );
}
return;
}
else
{
AddOperation( EExit );
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::Sort
// ---------------------------------------------------------------------------
//
TInt CPbkxRclServiceUiContextImpl::Sort(
const CContactCard& aFirst,
const CContactCard& aSecond )
{
FUNC_LOG;
TPtrC lastName1 = PbkxRclUtils::FieldText( &aFirst, KUidContactFieldFamilyName );
TPtrC lastName2 = PbkxRclUtils::FieldText( &aSecond, KUidContactFieldFamilyName );
TInt ret = 0;
if ( lastName1 < lastName2 )
{
ret = -1;
}
else if ( lastName1 > lastName2 )
{
ret = 1;
}
return ret;
}
// ----------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::TimerCallBack
// ----------------------------------------------------------------------------
//
TInt CPbkxRclServiceUiContextImpl::TimerCallBack(TAny* aAny)
{
FUNC_LOG;
CPbkxRclServiceUiContextImpl* self = static_cast<CPbkxRclServiceUiContextImpl*>( aAny );
self->TimeOut();
return KErrNone;
}
// ----------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::TimeOut
// ----------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::TimeOut()
{
FUNC_LOG;
iTimer->Cancel();
if (iSession)
{
iSession->Cancel();
}
if (IsStateSet( EInfoDlgOnTop ) || IsStateSet( EResultDlgOnTop ))
{
StopActiveWait( EContactRetrievalWait );
}
TRAP_IGNORE( CloseWaitDialogL() );
HandleError( KErrTimedOut );
}
//////////////////////////////////////////////////////////////////////////////
// TOperationQueue class definition
//////////////////////////////////////////////////////////////////////////////
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::TOperationQueue::TOperationQueue
// ---------------------------------------------------------------------------
//
CPbkxRclServiceUiContextImpl::TOperationQueue::TOperationQueue() :
iCurrent( 0 ), iCount( 0 )
{
FUNC_LOG;
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::TOperationQueue::Add
// ---------------------------------------------------------------------------
//
void CPbkxRclServiceUiContextImpl::TOperationQueue::Add( TOperation aOperation )
{
FUNC_LOG;
if ( iCount == KMaxOperations )
{
PbkxRclPanic( EPbkxRclPanicGeneral );
}
TBool exists = EFalse;
for ( TInt i = iCurrent, count = 0;
count < iCount;
( ++i ) % KMaxOperations, count++ )
{
if ( iOperations[i] == aOperation )
{
exists = ETrue;
break;
}
}
if ( !exists )
{
TInt newIndex = ( iCurrent + iCount ) % KMaxOperations;
iOperations[newIndex] = aOperation;
iCount++;
}
}
// ---------------------------------------------------------------------------
// CPbkxRclServiceUiContextImpl::TOperationQueue::Pop
// ---------------------------------------------------------------------------
//
CPbkxRclServiceUiContextImpl::TOperation
CPbkxRclServiceUiContextImpl::TOperationQueue::Pop()
{
if ( iCount > 0 )
{
TOperation op = iOperations[iCurrent];
iOperations[iCurrent] = ENoOperation;
iCount--;
if ( iCount > 0 )
{
iCurrent = ( ++iCurrent ) % KMaxOperations;
}
else
{
iCurrent = 0;
}
return op;
}
else
{
return ENoOperation;
}
}
TInt CPbkxRclServiceUiContextImpl::TOperationQueue::Count() const
{
FUNC_LOG;
return iCount;
}