diff -r 24062c24fe38 -r 2a26698d78ba phoneuis/easydialing/src/easydialingplugin.cpp --- a/phoneuis/easydialing/src/easydialingplugin.cpp Fri Mar 12 15:42:40 2010 +0200 +++ b/phoneuis/easydialing/src/easydialingplugin.cpp Mon Mar 15 12:40:24 2010 +0200 @@ -128,9 +128,11 @@ static TBool IsItuTCharacter( TChar aChar ); -// FORWARD DECLARATIONS +static TInt Find( const MVPbkContactLink* aLink, const RPointerArray& aArray ); -using namespace AknLayoutScalable_Avkon; +template +inline void CleanupResetAndDestroyPushL(T& aRef); + // ----------------------------------------------------------------------------- @@ -283,7 +285,7 @@ // ----------------------------------------------------------------------------- -// Initialize +// InitializeL // Initialises easy dialing. // ----------------------------------------------------------------------------- // @@ -410,7 +412,7 @@ } // ----------------------------------------------------------------------------- -// GetContactFields +// SetSortOrderL // ----------------------------------------------------------------------------- // void CEasyDialingPlugin::SetSortOrderL( CEasyDialingContactDataManager::TNameOrder aNameOrder ) @@ -432,7 +434,7 @@ fields.Append(R_VPBK_FIELD_TYPE_COMPANYNAME); } iPredictiveContactSearchHandler->ChangeSortOrderL( *iContactDataStores[0], fields ); - CleanupStack::PopAndDestroy(); //fields + CleanupStack::PopAndDestroy( &fields ); } // ----------------------------------------------------------------------------- @@ -712,6 +714,7 @@ { // We get here if user e.g. leaves dialer open and goes to Contacts // application and does some editing. + iContactDataManager->Reload(); // to update thumbnails AsyncActionLaunchL( ELaunchSearch ); } } @@ -847,7 +850,7 @@ { return; } - + iDiscardCompletingSearches = EFalse; iNewSearchNeeded = EFalse; @@ -893,7 +896,7 @@ // void CEasyDialingPlugin::HandlePsResultsUpdate( RPointerArray& aResults, RPointerArray& aSeqs ) { - if (iCenrepListener && iCenrepListener->Value() == 0) + if ( !IsEnabled() ) { // Easydialing is off. We should arrive here only if user turned it off while a search was happening. Reset(); @@ -901,7 +904,7 @@ } TRAPD( leaveError, HandlePsResultsUpdateL( aResults, aSeqs ) ); - if( leaveError ) + if ( leaveError ) { OstTrace1( TRACE_ERROR, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATE, "HandlePsResultsUpdate failed: %d", leaveError ); LOGSTRING1("EasyDialingPlugin: HandlePsResultsUpdate failed: %d", leaveError ); @@ -1007,61 +1010,92 @@ OstTrace1( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_MATCHES, "Matching results from PCS: %d", numberOfPCSMatches ); LOGSTRING1("EasyDialingPlugin: Matching results from PCS: %d", numberOfPCSMatches ); - if ( numberOfPCSMatches > 0 ) - { - // retrieve the name order before adding - CEasyDialingContactDataManager::TNameOrder nameOrder = iContactDataManager->NameOrder(); + // retrieve the name order before adding + CEasyDialingContactDataManager::TNameOrder nameOrder = iContactDataManager->NameOrder(); - // map results to old contact match data - for( TInt i = 0; i < numberOfPCSMatches; i++ ) - { - TInt indexFromEnd = numberOfPCSMatches - i - 1; + RPointerArray favsFoundByPcs; + CleanupResetAndDestroyPushL( favsFoundByPcs ); + + // Update the model + // ---------------- + for ( TInt i = 0; i < numberOfPCSMatches; i++ ) + { + TInt indexFromEnd = numberOfPCSMatches - i - 1; - MVPbkContactLink* link = iPredictiveContactSearchHandler->ConvertToVpbkLinkLC( - *(aResults[indexFromEnd]), *iContactManager ); - if ( !iContactDataManager->IsFavL( link ) ) - { - // handle favourites separately, in another loop - HBufC* contactString = CreateContactStringLC( aResults[ indexFromEnd ], nameOrder ); - CreateListBoxContactStringL( *contactString, link, matchThumbnails, EFalse ); - CleanupStack::PopAndDestroy( contactString ); - } + MVPbkContactLink* link = iPredictiveContactSearchHandler->ConvertToVpbkLinkLC( + *(aResults[indexFromEnd]), *iContactManager ); + if ( !iContactDataManager->IsFavL( link ) ) + { + // handle favourites separately, in another loop + HBufC* contactString = CreateContactStringLC( aResults[ indexFromEnd ], nameOrder ); + CreateListBoxContactStringL( *contactString, link, matchThumbnails, EFalse ); + CleanupStack::PopAndDestroy( contactString ); CleanupStack::PopAndDestroy( link ); - - OstTraceExt2( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_SHOW_MATCH, "Contact #%d: '%S'", i+1, iContactStringCreationBuffer ); - LOGSTRING2("EasyDialingPlugin: Contact #%d: '%S'", i+1, &iContactStringCreationBuffer ); } + else + { + // favourites are handled later + favsFoundByPcs.AppendL( link ); + CleanupStack::Pop( link ); + } + + OstTraceExt2( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_SHOW_MATCH, "Contact #%d: '%S'", i+1, iContactStringCreationBuffer ); + LOGSTRING2( "EasyDialingPlugin: Contact #%d: '%S'", i+1, &iContactStringCreationBuffer ); + } - TInt numberOfFavs( iContactDataManager->NumberOfFavsL() ); - TBuf results; - for ( TInt i = numberOfFavs - 1; i >= 0; i-- ) + // Search synchronously through all the favourite contacts to ensure + // that all favourite matches are added to bottom even when number of mathces + // exceeds the maximum number set to PCS + TInt numberOfFavs( iContactDataManager->NumberOfFavsL() ); + TBuf results; + for ( TInt i = numberOfFavs - 1; i >= 0; i-- ) + { + HBufC* favContactString = iContactDataManager->FavContactStringLC( i, nameOrder ); + MVPbkContactLink* link = iContactDataManager->FavLinkLC( i ); + + // Check if this fav contact was returned in aResults. + // It's at least theoretically possible that all matches in aResults + // are not matched when using LookupMatchL. PCS has completely separate logics + // for functions SearchL and LookupMatchL and especially with Chinese variant + // they may return different results. + TBool found = ( Find( link, favsFoundByPcs ) != KErrNotFound ); + + // If this fav contact was not in aResults, then use LookupMatchL + // to check if this contact is still a match and was excluded from aResults + // because maximum number of results was exceeded. + if ( !found ) { - // check if this fav matches the search - HBufC* favContactString = iContactDataManager->FavContactStringLC( i, nameOrder ); results = KNullDesC; iPredictiveContactSearchHandler->LookupMatchL( *iPredictiveSearchQuery, *favContactString, results ); - if ( results.Length() > 0 ) - { - // matches, add this fav to listbox. - MVPbkContactLink* link = iContactDataManager->FavLinkLC( i ); - CreateListBoxContactStringL( *favContactString, link, matchThumbnails, ETrue ); - CleanupStack::PopAndDestroy(); //link - } - CleanupStack::PopAndDestroy( favContactString ); + found = ( results.Length() > 0 ); + } + + if ( found ) + { + // matches, add this fav to listbox. + CreateListBoxContactStringL( *favContactString, link, matchThumbnails, ETrue ); } - - iNumberOfNames = iListBoxModel->Count(); + + CleanupStack::PopAndDestroy(); // link + CleanupStack::PopAndDestroy( favContactString ); + } + + CleanupStack::PopAndDestroy( &favsFoundByPcs ); // ResetAndDestroy + + // Update the view + // --------------- + iNumberOfNames = iListBoxModel->Count(); + if ( iNumberOfNames ) + { iContactListBox->SetRectToNumberOfItems( iNumberOfNames ); iContactListBox->HandleItemAdditionL(); // Scroll the list to bottom iContactListBox->ScrollToMakeItemVisible( iNumberOfNames-1 ); - iContactListBox->MakeVisible( ETrue ); } else { - iNumberOfNames = 0; iContactListBox->MakeVisible( EFalse ); } @@ -1333,7 +1367,7 @@ if ( iContactListBox->CurrentItemIndex() >= 0 ) { - TInt index = iContactListBox->CurrentContactDataIndex(); + TInt index = iContactListBox->CurrentContactDataIndex(); voiceCall = iContactDataManager->VoiceCallAvailable( index ); videoCall = iContactDataManager->VideoCallAvailable( index ); @@ -1413,7 +1447,7 @@ TBool ret(EFalse); - switch( aCommand ) + switch ( aCommand ) { case EEasyDialingOpenContact: @@ -1495,9 +1529,9 @@ // Check if Easy dialing is enabled in the settings // ----------------------------------------------------------------------------- // -TBool CEasyDialingPlugin::IsEnabled() +TBool CEasyDialingPlugin::IsEnabled() const { - return ( iCenrepListener->Value() != 0 ); + return ( iCenrepListener && iCenrepListener->Value() != 0 ); } // ----------------------------------------------------------------------------- @@ -1534,7 +1568,7 @@ // This means that iInputBlocker is deleted by CAknInputBlock when // it's cancelled ( we get a callback where iInputBlocker is set to NULL). - iInputBlocker->SetCancelDelete( iInputBlocker ); + iInputBlocker->SetCancelDelete( iInputBlocker ); } // ----------------------------------------------------------------------------- @@ -1600,7 +1634,7 @@ HBufC* fullName = AllocWithoutHighlightSeparatorsLC( fullNameSeparators ); VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector selector( - VPbkFieldTypeSelectorFactory::EEmptySelector ); + VPbkFieldTypeSelectorFactory::EEmptySelector ); switch ( iActionToBeLaunched ) { @@ -1626,7 +1660,7 @@ selector = VPbkFieldTypeSelectorFactory::EVoiceCallSelector; } - CleanupStack::PopAndDestroy( sPSettings ); + CleanupStack::PopAndDestroy( sPSettings ); } break; @@ -1693,6 +1727,18 @@ AsyncActionLaunchL( ELaunchCurrentContact ); break; + // Pause contact data manager when panning and flicking listbox. + // This ensures smooth and responsive listbox touch handling. + case EEventFlickStarted: + case EEventPanningStarted: + iContactDataManager->Pause( ETrue ); + break; + + case EEventFlickStopped: + case EEventPanningStopped: + iContactDataManager->Pause( EFalse ); + break; + // We are not interested about the other listbox events. default: break; @@ -1930,5 +1976,42 @@ aChar == TChar('+'); } +// ----------------------------------------------------------------------------- +// Find contact link pointing to the same contact as given link +// ----------------------------------------------------------------------------- +// +static TInt Find( const MVPbkContactLink* aLink, const RPointerArray& aArray ) + { + TInt idx = KErrNotFound; + for ( TInt i = 0 ; i < aArray.Count() ; ++i ) + { + if ( aArray[i]->IsSame( *aLink ) ) + { + idx = i; + i = aArray.Count(); + } + } + return idx; + } + +// ----------------------------------------------------------------------------- +// CleanupStack helpers for item owning RPointerArrays (etc) +// ----------------------------------------------------------------------------- +// +template +class CleanupResetAndDestroy + { +public: + inline static void PushL( T& aRef ) + { CleanupStack::PushL( TCleanupItem(&ResetAndDestroy,&aRef) ); } +private: + inline static void ResetAndDestroy( TAny *aPtr ) + { static_cast(aPtr)->ResetAndDestroy(); } + }; + +template +inline void CleanupResetAndDestroyPushL( T& aRef ) + { CleanupResetAndDestroy::PushL(aRef); } + // End of File