branch | RCL_3 |
changeset 5 | 2a26698d78ba |
parent 4 | 24062c24fe38 |
child 6 | 38529f706030 |
4:24062c24fe38 | 5:2a26698d78ba |
---|---|
126 |
126 |
127 static HBufC* AllocWithoutHighlightSeparatorsLC( TDesC& aDesc ); |
127 static HBufC* AllocWithoutHighlightSeparatorsLC( TDesC& aDesc ); |
128 |
128 |
129 static TBool IsItuTCharacter( TChar aChar ); |
129 static TBool IsItuTCharacter( TChar aChar ); |
130 |
130 |
131 // FORWARD DECLARATIONS |
131 static TInt Find( const MVPbkContactLink* aLink, const RPointerArray<MVPbkContactLink>& aArray ); |
132 |
132 |
133 using namespace AknLayoutScalable_Avkon; |
133 template <class T> |
134 inline void CleanupResetAndDestroyPushL(T& aRef); |
|
135 |
|
134 |
136 |
135 |
137 |
136 // ----------------------------------------------------------------------------- |
138 // ----------------------------------------------------------------------------- |
137 // CEasyDialingPlugin |
139 // CEasyDialingPlugin |
138 // The default c++ constructor |
140 // The default c++ constructor |
281 LOGSTRING("EasyDialingPlugin: Plugin unloaded"); |
283 LOGSTRING("EasyDialingPlugin: Plugin unloaded"); |
282 } |
284 } |
283 |
285 |
284 |
286 |
285 // ----------------------------------------------------------------------------- |
287 // ----------------------------------------------------------------------------- |
286 // Initialize |
288 // InitializeL |
287 // Initialises easy dialing. |
289 // Initialises easy dialing. |
288 // ----------------------------------------------------------------------------- |
290 // ----------------------------------------------------------------------------- |
289 // |
291 // |
290 void CEasyDialingPlugin::InitializeL( CCoeControl& aParent ) |
292 void CEasyDialingPlugin::InitializeL( CCoeControl& aParent ) |
291 { |
293 { |
408 |
410 |
409 iPredictiveSearchQuery = CPsQuery::NewL(); |
411 iPredictiveSearchQuery = CPsQuery::NewL(); |
410 } |
412 } |
411 |
413 |
412 // ----------------------------------------------------------------------------- |
414 // ----------------------------------------------------------------------------- |
413 // GetContactFields |
415 // SetSortOrderL |
414 // ----------------------------------------------------------------------------- |
416 // ----------------------------------------------------------------------------- |
415 // |
417 // |
416 void CEasyDialingPlugin::SetSortOrderL( CEasyDialingContactDataManager::TNameOrder aNameOrder ) |
418 void CEasyDialingPlugin::SetSortOrderL( CEasyDialingContactDataManager::TNameOrder aNameOrder ) |
417 { |
419 { |
418 RArray<TInt> fields; |
420 RArray<TInt> fields; |
430 if ( iCompanyNamePCSIndex != KErrNotFound ) |
432 if ( iCompanyNamePCSIndex != KErrNotFound ) |
431 { |
433 { |
432 fields.Append(R_VPBK_FIELD_TYPE_COMPANYNAME); |
434 fields.Append(R_VPBK_FIELD_TYPE_COMPANYNAME); |
433 } |
435 } |
434 iPredictiveContactSearchHandler->ChangeSortOrderL( *iContactDataStores[0], fields ); |
436 iPredictiveContactSearchHandler->ChangeSortOrderL( *iContactDataStores[0], fields ); |
435 CleanupStack::PopAndDestroy(); //fields |
437 CleanupStack::PopAndDestroy( &fields ); |
436 } |
438 } |
437 |
439 |
438 // ----------------------------------------------------------------------------- |
440 // ----------------------------------------------------------------------------- |
439 // OfferKeyEventL |
441 // OfferKeyEventL |
440 // Check the received keypad event and performs user |
442 // Check the received keypad event and performs user |
710 } |
712 } |
711 else |
713 else |
712 { |
714 { |
713 // We get here if user e.g. leaves dialer open and goes to Contacts |
715 // We get here if user e.g. leaves dialer open and goes to Contacts |
714 // application and does some editing. |
716 // application and does some editing. |
717 iContactDataManager->Reload(); // to update thumbnails |
|
715 AsyncActionLaunchL( ELaunchSearch ); |
718 AsyncActionLaunchL( ELaunchSearch ); |
716 } |
719 } |
717 } |
720 } |
718 } |
721 } |
719 |
722 |
845 { |
848 { |
846 if ( iSearchString.Length() == 0 ) |
849 if ( iSearchString.Length() == 0 ) |
847 { |
850 { |
848 return; |
851 return; |
849 } |
852 } |
850 |
853 |
851 iDiscardCompletingSearches = EFalse; |
854 iDiscardCompletingSearches = EFalse; |
852 iNewSearchNeeded = EFalse; |
855 iNewSearchNeeded = EFalse; |
853 |
856 |
854 iPredictiveSearchQuery->Reset(); |
857 iPredictiveSearchQuery->Reset(); |
855 |
858 |
891 // Called after predictive search has been completed. |
894 // Called after predictive search has been completed. |
892 // ----------------------------------------------------------------------------- |
895 // ----------------------------------------------------------------------------- |
893 // |
896 // |
894 void CEasyDialingPlugin::HandlePsResultsUpdate( RPointerArray<CPsClientData>& aResults, RPointerArray<CPsPattern>& aSeqs ) |
897 void CEasyDialingPlugin::HandlePsResultsUpdate( RPointerArray<CPsClientData>& aResults, RPointerArray<CPsPattern>& aSeqs ) |
895 { |
898 { |
896 if (iCenrepListener && iCenrepListener->Value() == 0) |
899 if ( !IsEnabled() ) |
897 { |
900 { |
898 // Easydialing is off. We should arrive here only if user turned it off while a search was happening. |
901 // Easydialing is off. We should arrive here only if user turned it off while a search was happening. |
899 Reset(); |
902 Reset(); |
900 return; |
903 return; |
901 } |
904 } |
902 TRAPD( leaveError, HandlePsResultsUpdateL( aResults, aSeqs ) ); |
905 TRAPD( leaveError, HandlePsResultsUpdateL( aResults, aSeqs ) ); |
903 |
906 |
904 if( leaveError ) |
907 if ( leaveError ) |
905 { |
908 { |
906 OstTrace1( TRACE_ERROR, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATE, "HandlePsResultsUpdate failed: %d", leaveError ); |
909 OstTrace1( TRACE_ERROR, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATE, "HandlePsResultsUpdate failed: %d", leaveError ); |
907 LOGSTRING1("EasyDialingPlugin: HandlePsResultsUpdate failed: %d", leaveError ); |
910 LOGSTRING1("EasyDialingPlugin: HandlePsResultsUpdate failed: %d", leaveError ); |
908 } |
911 } |
909 } |
912 } |
1005 } |
1008 } |
1006 |
1009 |
1007 OstTrace1( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_MATCHES, "Matching results from PCS: %d", numberOfPCSMatches ); |
1010 OstTrace1( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_MATCHES, "Matching results from PCS: %d", numberOfPCSMatches ); |
1008 LOGSTRING1("EasyDialingPlugin: Matching results from PCS: %d", numberOfPCSMatches ); |
1011 LOGSTRING1("EasyDialingPlugin: Matching results from PCS: %d", numberOfPCSMatches ); |
1009 |
1012 |
1010 if ( numberOfPCSMatches > 0 ) |
1013 // retrieve the name order before adding |
1011 { |
1014 CEasyDialingContactDataManager::TNameOrder nameOrder = iContactDataManager->NameOrder(); |
1012 // retrieve the name order before adding |
1015 |
1013 CEasyDialingContactDataManager::TNameOrder nameOrder = iContactDataManager->NameOrder(); |
1016 RPointerArray<MVPbkContactLink> favsFoundByPcs; |
1014 |
1017 CleanupResetAndDestroyPushL( favsFoundByPcs ); |
1015 // map results to old contact match data |
1018 |
1016 for( TInt i = 0; i < numberOfPCSMatches; i++ ) |
1019 // Update the model |
1017 { |
1020 // ---------------- |
1018 TInt indexFromEnd = numberOfPCSMatches - i - 1; |
1021 for ( TInt i = 0; i < numberOfPCSMatches; i++ ) |
1019 |
1022 { |
1020 MVPbkContactLink* link = iPredictiveContactSearchHandler->ConvertToVpbkLinkLC( |
1023 TInt indexFromEnd = numberOfPCSMatches - i - 1; |
1021 *(aResults[indexFromEnd]), *iContactManager ); |
1024 |
1022 if ( !iContactDataManager->IsFavL( link ) ) |
1025 MVPbkContactLink* link = iPredictiveContactSearchHandler->ConvertToVpbkLinkLC( |
1023 { |
1026 *(aResults[indexFromEnd]), *iContactManager ); |
1024 // handle favourites separately, in another loop |
1027 if ( !iContactDataManager->IsFavL( link ) ) |
1025 HBufC* contactString = CreateContactStringLC( aResults[ indexFromEnd ], nameOrder ); |
1028 { |
1026 CreateListBoxContactStringL( *contactString, link, matchThumbnails, EFalse ); |
1029 // handle favourites separately, in another loop |
1027 CleanupStack::PopAndDestroy( contactString ); |
1030 HBufC* contactString = CreateContactStringLC( aResults[ indexFromEnd ], nameOrder ); |
1028 } |
1031 CreateListBoxContactStringL( *contactString, link, matchThumbnails, EFalse ); |
1032 CleanupStack::PopAndDestroy( contactString ); |
|
1029 CleanupStack::PopAndDestroy( link ); |
1033 CleanupStack::PopAndDestroy( link ); |
1030 |
1034 } |
1031 OstTraceExt2( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_SHOW_MATCH, "Contact #%d: '%S'", i+1, iContactStringCreationBuffer ); |
1035 else |
1032 LOGSTRING2("EasyDialingPlugin: Contact #%d: '%S'", i+1, &iContactStringCreationBuffer ); |
1036 { |
1033 } |
1037 // favourites are handled later |
1034 |
1038 favsFoundByPcs.AppendL( link ); |
1035 TInt numberOfFavs( iContactDataManager->NumberOfFavsL() ); |
1039 CleanupStack::Pop( link ); |
1036 TBuf<KBufferMaxLen> results; |
1040 } |
1037 for ( TInt i = numberOfFavs - 1; i >= 0; i-- ) |
1041 |
1038 { |
1042 OstTraceExt2( TRACE_NORMAL, CEASYDIALINGPLUGIN_HANDLEPSRESULTSUPDATEL_SHOW_MATCH, "Contact #%d: '%S'", i+1, iContactStringCreationBuffer ); |
1039 // check if this fav matches the search |
1043 LOGSTRING2( "EasyDialingPlugin: Contact #%d: '%S'", i+1, &iContactStringCreationBuffer ); |
1040 HBufC* favContactString = iContactDataManager->FavContactStringLC( i, nameOrder ); |
1044 } |
1045 |
|
1046 // Search synchronously through all the favourite contacts to ensure |
|
1047 // that all favourite matches are added to bottom even when number of mathces |
|
1048 // exceeds the maximum number set to PCS |
|
1049 TInt numberOfFavs( iContactDataManager->NumberOfFavsL() ); |
|
1050 TBuf<KBufferMaxLen> results; |
|
1051 for ( TInt i = numberOfFavs - 1; i >= 0; i-- ) |
|
1052 { |
|
1053 HBufC* favContactString = iContactDataManager->FavContactStringLC( i, nameOrder ); |
|
1054 MVPbkContactLink* link = iContactDataManager->FavLinkLC( i ); |
|
1055 |
|
1056 // Check if this fav contact was returned in aResults. |
|
1057 // It's at least theoretically possible that all matches in aResults |
|
1058 // are not matched when using LookupMatchL. PCS has completely separate logics |
|
1059 // for functions SearchL and LookupMatchL and especially with Chinese variant |
|
1060 // they may return different results. |
|
1061 TBool found = ( Find( link, favsFoundByPcs ) != KErrNotFound ); |
|
1062 |
|
1063 // If this fav contact was not in aResults, then use LookupMatchL |
|
1064 // to check if this contact is still a match and was excluded from aResults |
|
1065 // because maximum number of results was exceeded. |
|
1066 if ( !found ) |
|
1067 { |
|
1041 results = KNullDesC; |
1068 results = KNullDesC; |
1042 iPredictiveContactSearchHandler->LookupMatchL( |
1069 iPredictiveContactSearchHandler->LookupMatchL( |
1043 *iPredictiveSearchQuery, *favContactString, results ); |
1070 *iPredictiveSearchQuery, *favContactString, results ); |
1044 if ( results.Length() > 0 ) |
1071 found = ( results.Length() > 0 ); |
1045 { |
1072 } |
1046 // matches, add this fav to listbox. |
1073 |
1047 MVPbkContactLink* link = iContactDataManager->FavLinkLC( i ); |
1074 if ( found ) |
1048 CreateListBoxContactStringL( *favContactString, link, matchThumbnails, ETrue ); |
1075 { |
1049 CleanupStack::PopAndDestroy(); //link |
1076 // matches, add this fav to listbox. |
1050 } |
1077 CreateListBoxContactStringL( *favContactString, link, matchThumbnails, ETrue ); |
1051 CleanupStack::PopAndDestroy( favContactString ); |
1078 } |
1052 } |
1079 |
1053 |
1080 CleanupStack::PopAndDestroy(); // link |
1054 iNumberOfNames = iListBoxModel->Count(); |
1081 CleanupStack::PopAndDestroy( favContactString ); |
1082 } |
|
1083 |
|
1084 CleanupStack::PopAndDestroy( &favsFoundByPcs ); // ResetAndDestroy |
|
1085 |
|
1086 // Update the view |
|
1087 // --------------- |
|
1088 iNumberOfNames = iListBoxModel->Count(); |
|
1089 if ( iNumberOfNames ) |
|
1090 { |
|
1055 iContactListBox->SetRectToNumberOfItems( iNumberOfNames ); |
1091 iContactListBox->SetRectToNumberOfItems( iNumberOfNames ); |
1056 iContactListBox->HandleItemAdditionL(); |
1092 iContactListBox->HandleItemAdditionL(); |
1057 // Scroll the list to bottom |
1093 // Scroll the list to bottom |
1058 iContactListBox->ScrollToMakeItemVisible( iNumberOfNames-1 ); |
1094 iContactListBox->ScrollToMakeItemVisible( iNumberOfNames-1 ); |
1059 |
|
1060 iContactListBox->MakeVisible( ETrue ); |
1095 iContactListBox->MakeVisible( ETrue ); |
1061 } |
1096 } |
1062 else |
1097 else |
1063 { |
1098 { |
1064 iNumberOfNames = 0; |
|
1065 iContactListBox->MakeVisible( EFalse ); |
1099 iContactListBox->MakeVisible( EFalse ); |
1066 } |
1100 } |
1067 |
1101 |
1068 if ( IsFocused() ) |
1102 if ( IsFocused() ) |
1069 { |
1103 { |
1331 TBool videoCall = EFalse; |
1365 TBool videoCall = EFalse; |
1332 TBool message = EFalse; |
1366 TBool message = EFalse; |
1333 |
1367 |
1334 if ( iContactListBox->CurrentItemIndex() >= 0 ) |
1368 if ( iContactListBox->CurrentItemIndex() >= 0 ) |
1335 { |
1369 { |
1336 TInt index = iContactListBox->CurrentContactDataIndex(); |
1370 TInt index = iContactListBox->CurrentContactDataIndex(); |
1337 |
1371 |
1338 voiceCall = iContactDataManager->VoiceCallAvailable( index ); |
1372 voiceCall = iContactDataManager->VoiceCallAvailable( index ); |
1339 videoCall = iContactDataManager->VideoCallAvailable( index ); |
1373 videoCall = iContactDataManager->VideoCallAvailable( index ); |
1340 message = iContactDataManager->UniEditorAvailable( index ); |
1374 message = iContactDataManager->UniEditorAvailable( index ); |
1341 } |
1375 } |
1411 } |
1445 } |
1412 |
1446 |
1413 |
1447 |
1414 TBool ret(EFalse); |
1448 TBool ret(EFalse); |
1415 |
1449 |
1416 switch( aCommand ) |
1450 switch ( aCommand ) |
1417 { |
1451 { |
1418 case EEasyDialingOpenContact: |
1452 case EEasyDialingOpenContact: |
1419 |
1453 |
1420 iRememberFocus = ETrue; |
1454 iRememberFocus = ETrue; |
1421 AsyncActionLaunchL( ELaunchCurrentContact ); |
1455 AsyncActionLaunchL( ELaunchCurrentContact ); |
1493 // ----------------------------------------------------------------------------- |
1527 // ----------------------------------------------------------------------------- |
1494 // IsEnabled |
1528 // IsEnabled |
1495 // Check if Easy dialing is enabled in the settings |
1529 // Check if Easy dialing is enabled in the settings |
1496 // ----------------------------------------------------------------------------- |
1530 // ----------------------------------------------------------------------------- |
1497 // |
1531 // |
1498 TBool CEasyDialingPlugin::IsEnabled() |
1532 TBool CEasyDialingPlugin::IsEnabled() const |
1499 { |
1533 { |
1500 return ( iCenrepListener->Value() != 0 ); |
1534 return ( iCenrepListener && iCenrepListener->Value() != 0 ); |
1501 } |
1535 } |
1502 |
1536 |
1503 // ----------------------------------------------------------------------------- |
1537 // ----------------------------------------------------------------------------- |
1504 // AsyncActionLaunchL |
1538 // AsyncActionLaunchL |
1505 // Use asynchronous callback to launch action. While action is being launched, |
1539 // Use asynchronous callback to launch action. While action is being launched, |
1532 iInputBlocker = CAknInputBlock::NewCancelHandlerLC( this ); |
1566 iInputBlocker = CAknInputBlock::NewCancelHandlerLC( this ); |
1533 CleanupStack::Pop( iInputBlocker ); |
1567 CleanupStack::Pop( iInputBlocker ); |
1534 |
1568 |
1535 // This means that iInputBlocker is deleted by CAknInputBlock when |
1569 // This means that iInputBlocker is deleted by CAknInputBlock when |
1536 // it's cancelled ( we get a callback where iInputBlocker is set to NULL). |
1570 // it's cancelled ( we get a callback where iInputBlocker is set to NULL). |
1537 iInputBlocker->SetCancelDelete( iInputBlocker ); |
1571 iInputBlocker->SetCancelDelete( iInputBlocker ); |
1538 } |
1572 } |
1539 |
1573 |
1540 // ----------------------------------------------------------------------------- |
1574 // ----------------------------------------------------------------------------- |
1541 // AsyncCallBackToLaunchAction |
1575 // AsyncCallBackToLaunchAction |
1542 // Callback function for CAsyncCallBack class. |
1576 // Callback function for CAsyncCallBack class. |
1598 |
1632 |
1599 // Remove highlight separators. It is possible that some contactor API has problem with them. |
1633 // Remove highlight separators. It is possible that some contactor API has problem with them. |
1600 HBufC* fullName = AllocWithoutHighlightSeparatorsLC( fullNameSeparators ); |
1634 HBufC* fullName = AllocWithoutHighlightSeparatorsLC( fullNameSeparators ); |
1601 |
1635 |
1602 VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector selector( |
1636 VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector selector( |
1603 VPbkFieldTypeSelectorFactory::EEmptySelector ); |
1637 VPbkFieldTypeSelectorFactory::EEmptySelector ); |
1604 |
1638 |
1605 switch ( iActionToBeLaunched ) |
1639 switch ( iActionToBeLaunched ) |
1606 { |
1640 { |
1607 case ECallCurrentContact: |
1641 case ECallCurrentContact: |
1608 { |
1642 { |
1624 else |
1658 else |
1625 { |
1659 { |
1626 selector = VPbkFieldTypeSelectorFactory::EVoiceCallSelector; |
1660 selector = VPbkFieldTypeSelectorFactory::EVoiceCallSelector; |
1627 } |
1661 } |
1628 |
1662 |
1629 CleanupStack::PopAndDestroy( sPSettings ); |
1663 CleanupStack::PopAndDestroy( sPSettings ); |
1630 } |
1664 } |
1631 break; |
1665 break; |
1632 |
1666 |
1633 case EVideoCallCurrentContact: |
1667 case EVideoCallCurrentContact: |
1634 |
1668 |
1689 AsyncActionLaunchL( ECallCurrentContact ); |
1723 AsyncActionLaunchL( ECallCurrentContact ); |
1690 break; |
1724 break; |
1691 |
1725 |
1692 case KEasyDialingContactLongTapped: |
1726 case KEasyDialingContactLongTapped: |
1693 AsyncActionLaunchL( ELaunchCurrentContact ); |
1727 AsyncActionLaunchL( ELaunchCurrentContact ); |
1728 break; |
|
1729 |
|
1730 // Pause contact data manager when panning and flicking listbox. |
|
1731 // This ensures smooth and responsive listbox touch handling. |
|
1732 case EEventFlickStarted: |
|
1733 case EEventPanningStarted: |
|
1734 iContactDataManager->Pause( ETrue ); |
|
1735 break; |
|
1736 |
|
1737 case EEventFlickStopped: |
|
1738 case EEventPanningStopped: |
|
1739 iContactDataManager->Pause( EFalse ); |
|
1694 break; |
1740 break; |
1695 |
1741 |
1696 // We are not interested about the other listbox events. |
1742 // We are not interested about the other listbox events. |
1697 default: |
1743 default: |
1698 break; |
1744 break; |
1928 aChar == TChar('#') || |
1974 aChar == TChar('#') || |
1929 aChar == TChar('*') || |
1975 aChar == TChar('*') || |
1930 aChar == TChar('+'); |
1976 aChar == TChar('+'); |
1931 } |
1977 } |
1932 |
1978 |
1979 // ----------------------------------------------------------------------------- |
|
1980 // Find contact link pointing to the same contact as given link |
|
1981 // ----------------------------------------------------------------------------- |
|
1982 // |
|
1983 static TInt Find( const MVPbkContactLink* aLink, const RPointerArray<MVPbkContactLink>& aArray ) |
|
1984 { |
|
1985 TInt idx = KErrNotFound; |
|
1986 for ( TInt i = 0 ; i < aArray.Count() ; ++i ) |
|
1987 { |
|
1988 if ( aArray[i]->IsSame( *aLink ) ) |
|
1989 { |
|
1990 idx = i; |
|
1991 i = aArray.Count(); |
|
1992 } |
|
1993 } |
|
1994 return idx; |
|
1995 } |
|
1996 |
|
1997 // ----------------------------------------------------------------------------- |
|
1998 // CleanupStack helpers for item owning RPointerArrays (etc) |
|
1999 // ----------------------------------------------------------------------------- |
|
2000 // |
|
2001 template <class T> |
|
2002 class CleanupResetAndDestroy |
|
2003 { |
|
2004 public: |
|
2005 inline static void PushL( T& aRef ) |
|
2006 { CleanupStack::PushL( TCleanupItem(&ResetAndDestroy,&aRef) ); } |
|
2007 private: |
|
2008 inline static void ResetAndDestroy( TAny *aPtr ) |
|
2009 { static_cast<T*>(aPtr)->ResetAndDestroy(); } |
|
2010 }; |
|
2011 |
|
2012 template <class T> |
|
2013 inline void CleanupResetAndDestroyPushL( T& aRef ) |
|
2014 { CleanupResetAndDestroy<T>::PushL(aRef); } |
|
2015 |
|
1933 // End of File |
2016 // End of File |
1934 |
2017 |