phonebookui/Phonebook2/UIControls/src/CPbk2PredictiveSearchFilter.cpp
changeset 0 e686773b3f54
child 3 04ab22b956c2
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *     Phonebook 2 search pane filter. This acts as a wrapper to the FindBox in
       
    16 *     NameslistView. Info needs to be passed to this filter before the FindBox
       
    17 *
       
    18 */
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CPbk2PredictiveSearchFilter.h"
       
    22 
       
    23 // Phonebook 2
       
    24 #include <Phonebook2PrivateCRKeys.h>
       
    25 #include <MPbk2ContactNameFormatter.h>
       
    26 #include <MPbk2ContactNameFormatter2.h>
       
    27 #include <MVPbkViewContact.h>
       
    28 #include "MPbk2FilteredViewStack.h"
       
    29 #include "cpbk2predictiveviewstack.h"
       
    30 #include "TPbk2FindTextUtil.h"
       
    31 // Debugging headers
       
    32 #include <Pbk2Debug.h>
       
    33 
       
    34 //Avkon System includes
       
    35 #include <aknsfld.h>
       
    36 #include <txtetext.h>
       
    37 #include <eikenv.h>
       
    38 #include <eikappui.h>
       
    39 #include <eikcoctl.rsg>
       
    40 #include <eikedwin.h>
       
    41 #include <featmgr.h>
       
    42 #include <AknFepInternalCRKeys.h>
       
    43 #include <txtglobl.h>
       
    44 
       
    45 //PS
       
    46 #include <CPsRequestHandler.h>
       
    47 
       
    48 
       
    49 /// Unnamed namespace for local definitions
       
    50 namespace {
       
    51 
       
    52 _LIT(KQuestionMark, "?");
       
    53 _LIT(KspaceStr, " ");
       
    54 const TInt Kspace = ' ';
       
    55 const TInt Kquestion = '?';
       
    56 const TInt KDefaultListFormatting =
       
    57         MPbk2ContactNameFormatter::EUseSeparator |
       
    58         MPbk2ContactNameFormatter::EPreserveLeadingSpaces;
       
    59 
       
    60 } /// namespace
       
    61 
       
    62 NONSHARABLE_CLASS( CRunAsynch ): public CActive
       
    63     {
       
    64     public:
       
    65         static CRunAsynch* NewL(CPbk2PredictiveSearchFilter* aParent);
       
    66         void ReDraw();
       
    67         
       
    68         ~CRunAsynch();
       
    69     private: 
       
    70         CRunAsynch(CPbk2PredictiveSearchFilter* aParent);
       
    71         
       
    72         void RunL();
       
    73         void DoCancel();
       
    74         
       
    75     private: //Data
       
    76         CPbk2PredictiveSearchFilter* iParent;
       
    77     };
       
    78 
       
    79 // --------------------------------------------------------------------------
       
    80 // CRunAsynch::CRunAsynch
       
    81 // --------------------------------------------------------------------------
       
    82 //
       
    83 CRunAsynch::CRunAsynch(CPbk2PredictiveSearchFilter* aParent) :
       
    84     CActive(EPriorityIdle), 
       
    85     iParent(aParent) 
       
    86     {
       
    87     CActiveScheduler::Add(this);
       
    88     }
       
    89 
       
    90 // --------------------------------------------------------------------------
       
    91 // CRunAsynch::~CRunAsynch
       
    92 // --------------------------------------------------------------------------
       
    93 //
       
    94 inline CRunAsynch::~CRunAsynch()
       
    95     {
       
    96     Cancel();
       
    97     }
       
    98 
       
    99 // --------------------------------------------------------------------------
       
   100 // CRunAsynch::NewL
       
   101 // --------------------------------------------------------------------------
       
   102 //
       
   103 CRunAsynch* CRunAsynch::NewL(CPbk2PredictiveSearchFilter* aParent)
       
   104     {
       
   105     CRunAsynch* self = new ( ELeave ) CRunAsynch(aParent);
       
   106     return self;
       
   107     }
       
   108 
       
   109 // --------------------------------------------------------------------------
       
   110 // CRunAsynch::Redraw
       
   111 // --------------------------------------------------------------------------
       
   112 //
       
   113 void CRunAsynch::ReDraw()
       
   114     {
       
   115     if(!IsActive())
       
   116         {
       
   117         TRequestStatus* status=&iStatus;
       
   118         User::RequestComplete(status, KErrNone);
       
   119         SetActive();
       
   120         }
       
   121     }
       
   122 
       
   123 // --------------------------------------------------------------------------
       
   124 // CRunAsynch::DoCancel
       
   125 // --------------------------------------------------------------------------
       
   126 //
       
   127 void CRunAsynch::DoCancel()
       
   128     {
       
   129     
       
   130     }
       
   131 
       
   132 // --------------------------------------------------------------------------
       
   133 // CRunAsynch::RunL
       
   134 // --------------------------------------------------------------------------
       
   135 //
       
   136 void CRunAsynch::RunL()
       
   137     {
       
   138     iParent->ReDrawL();
       
   139     }
       
   140 
       
   141 // --------------------------------------------------------------------------
       
   142 // CPbk2PredictiveSearchFilter::CPbk2PredictiveSearchFilter
       
   143 // --------------------------------------------------------------------------
       
   144 //
       
   145 inline CPbk2PredictiveSearchFilter::CPbk2PredictiveSearchFilter() :
       
   146     iFiltering(EFalse),
       
   147     iAppUi( *(iEikonEnv->EikAppUi()) ),
       
   148     iPredictiveSearchEnabled(EFalse)
       
   149     {
       
   150     }
       
   151 
       
   152 // --------------------------------------------------------------------------
       
   153 // CPbk2PredictiveSearchFilter::~CPbk2PredictiveSearchFilter
       
   154 // --------------------------------------------------------------------------
       
   155 //
       
   156 CPbk2PredictiveSearchFilter::~CPbk2PredictiveSearchFilter()
       
   157     {    
       
   158     RemoveFromViewStack();    
       
   159     iPredictiveTextEntered.Close();    
       
   160     delete iSearchText;
       
   161     delete iRunAsynch;
       
   162     // UnInitialize feature manager
       
   163     FeatureManager::UnInitializeLib();
       
   164     }
       
   165 
       
   166 // --------------------------------------------------------------------------
       
   167 // CPbk2PredictiveSearchFilter::NewL
       
   168 // --------------------------------------------------------------------------
       
   169 //
       
   170 CPbk2PredictiveSearchFilter* CPbk2PredictiveSearchFilter::NewL()
       
   171     {
       
   172     CPbk2PredictiveSearchFilter* self =
       
   173         new ( ELeave ) CPbk2PredictiveSearchFilter();
       
   174     CleanupStack::PushL(self);
       
   175     self->ConstructL();
       
   176     CleanupStack::Pop(self);
       
   177     return self;
       
   178     }
       
   179 
       
   180 // --------------------------------------------------------------------------
       
   181 // CPbk2PredictiveSearchFilter::ConstructL
       
   182 // --------------------------------------------------------------------------
       
   183 //
       
   184 void CPbk2PredictiveSearchFilter::ConstructL()
       
   185     {
       
   186     // Initialize feature manager
       
   187     FeatureManager::InitializeLibL();
       
   188 
       
   189     if(FeatureManager::FeatureSupported(KFeatureIdFfContactsPredictiveSearch))
       
   190         {
       
   191         //The implementation algorithm suppose that only this class is
       
   192         //responsible to change or return PCS input mode therefore we can use this value
       
   193         CRepository* repository = CRepository::NewLC(TUid::Uid(KCRUidPhonebook));    
       
   194         repository->Get( KPhonebookPredictiveSearchEnablerFlags, iPredictiveSearchEnabled );      
       
   195         CleanupStack::PopAndDestroy(); //repository
       
   196         
       
   197         }
       
   198  
       
   199     iRunAsynch = CRunAsynch::NewL(this);
       
   200     }
       
   201 
       
   202 // --------------------------------------------------------------------------
       
   203 // CPbk2PredictiveSearchFilter::FilterL
       
   204 // --------------------------------------------------------------------------
       
   205 //
       
   206 void CPbk2PredictiveSearchFilter::FilterL( 
       
   207         const TKeyEvent& aKeyEvent, 
       
   208         TEventCode aType,
       
   209         CAknSearchField* aSearchField )
       
   210     {    
       
   211     
       
   212     if( aType == EEventKeyDown && aKeyEvent.iCode == EKeyNull )
       
   213         {        
       
   214         if( IsPredictiveActivated() && aSearchField )
       
   215             {
       
   216             iFiltering = ETrue;
       
   217             
       
   218             // Before single click it does nothing, but between multitap 
       
   219             // clicks it breaks Fep transaction.
       
   220             // It removes multitap. 
       
   221             RBuf searchText;
       
   222             searchText.CreateL( aSearchField->TextLength() );
       
   223             CleanupClosePushL( searchText );
       
   224             aSearchField->GetSearchText( searchText );       
       
   225             aSearchField->SetSearchTextL( searchText );
       
   226             aSearchField->SetFocus( ETrue, EDrawNow );
       
   227             CleanupStack::PopAndDestroy( &searchText );
       
   228             iFiltering = EFalse;  
       
   229             }
       
   230         }
       
   231     }
       
   232 
       
   233 // --------------------------------------------------------------------------
       
   234 // CPbk2PredictiveSearchFilter::IsFiltering
       
   235 // --------------------------------------------------------------------------
       
   236 //
       
   237 TBool CPbk2PredictiveSearchFilter::IsFiltering()
       
   238     {
       
   239     return iFiltering;
       
   240     }
       
   241 
       
   242 // --------------------------------------------------------------------------
       
   243 // CPbk2PredictiveSearchFilter::StartFindPaneInlineEditL
       
   244 // --------------------------------------------------------------------------
       
   245 //
       
   246 TBool CPbk2PredictiveSearchFilter::StartFindPaneInlineEditL( TDes& aFindPaneText )
       
   247     {
       
   248     //Level 1 : Check if virtual keyboard was used
       
   249     if( !iVKbUsed && iSearchField && iSearchText->Length() < aFindPaneText.Length() &&
       
   250          (iSearchField->Editor().AknEdwinFlags() & EAknEditorFlagTouchInputModeOpened) )
       
   251         {
       
   252         iVKbUsed = ETrue;
       
   253         }
       
   254     //Level 2 : Check if predictive serach is activated or not
       
   255     //if predictive serach is not activated, avoid performing
       
   256     //any operation on the same string in FindPane
       
   257     if ( !IsPredictiveActivated() )
       
   258         {
       
   259         return ETrue;
       
   260         }
       
   261     TPtr searchPtr (iSearchText->Des()); //Text which holds the FindPane display text    
       
   262     TInt findPaneTxtLen = aFindPaneText.Length(); 
       
   263         
       
   264     //Level 3: If search text filtering is ongoing, avoid performing
       
   265     //any operation on the same string in FindPane 
       
   266     if (iFiltering )
       
   267         {
       
   268         return EFalse;
       
   269         }    
       
   270     
       
   271     //Level 4: HandleControlEventL wil be called more than once, avoid performing
       
   272     //any operation on the same string in FindPane 
       
   273     if (aFindPaneText.Compare(searchPtr) == 0)//HandleControlEventL wil be called more than once, avoid performing
       
   274                                           //any operation on the same string in FindPane
       
   275         {            
       
   276         return EFalse;
       
   277         }
       
   278     
       
   279     //Level 5: If editor is locked, avoid performing
       
   280     //any operation on the same string in FindPane 
       
   281     if ( iLocked ) 
       
   282         { 
       
   283         if( aFindPaneText.Length() > 1 && aFindPaneText[aFindPaneText.Length() - 2] == Kquestion )
       
   284             {
       
   285             TBuf <KSearchFieldLength> findPaneTxtCopy;
       
   286             findPaneTxtCopy.SetLength(0);            
       
   287             findPaneTxtCopy.Copy(aFindPaneText);
       
   288             findPaneTxtCopy.Replace(aFindPaneText.Length() - 1, 1, KspaceStr);            
       
   289             SetSearchBoxTextL(findPaneTxtCopy, findPaneTxtCopy.Length() - 1);
       
   290             iRemoveSpace = ETrue;
       
   291             }
       
   292         return EFalse;
       
   293         }
       
   294     
       
   295     TBool isCharRemoved (EFalse); //To know whether its a backspace char or not. If backspace nothing needs to be done
       
   296     if ( findPaneTxtLen )
       
   297         {    
       
   298         TInt len = iPredictiveTextEntered.Length();
       
   299         //Append the newly entered char into our predictive search query string
       
   300         if ( findPaneTxtLen >= len )
       
   301             {
       
   302             if ( iLongKeyPress )
       
   303                 {
       
   304                 //If it was a long key press
       
   305                 //Normally during Long Key Press, there are 2 actions that happen
       
   306                 //first the char is displayed and then followed by that the number
       
   307                 //eg. the numeric key pad "2" denotes "abc2...", when u long press 2, 
       
   308                 //first the char 'a' is shown
       
   309                 //and then followed by that it shows '2'. 
       
   310                 //We get 2 events one wih 'a' and next with '2'
       
   311                 //So, we need to send first 'a' to the predictive search
       
   312                 //and then followed by this '2'.
       
   313                 //So During this case, the Fep transaction is broken because of us
       
   314                 //and thus the FEP will send the event with any of the strings
       
   315                 //' 2' or '*2'(* - denotes the matched char for the 1stquery a)
       
   316                 //If Long Key Press, we remove the previous char and use the new one
       
   317                 //for our search, otherwise we might end up sending a search req for 
       
   318                 //as 'a2' if that would have been a long key press on mumeric keypad 2.
       
   319                 iPredictiveTextEntered.Delete( len - 1, 1 );
       
   320                 iLongKeyPress = EFalse;
       
   321                 }
       
   322             if ( findPaneTxtLen == len )
       
   323                 {
       
   324                 len = len - 1;
       
   325                 isCharRemoved = ETrue;
       
   326                 }
       
   327             //Append the newly entered char to our predictive search query. 
       
   328             iPredictiveTextEntered.Append( aFindPaneText.Right(findPaneTxtLen - len) );
       
   329             }
       
   330         else
       
   331             {
       
   332             //Some chars have been removed so delete the app char from our predictive search query            
       
   333             iPredictiveTextEntered.Delete( findPaneTxtLen, iPredictiveTextEntered.Length() - findPaneTxtLen );
       
   334             isCharRemoved = ETrue;
       
   335             }
       
   336         
       
   337         TBuf <KSearchFieldLength> findPaneTxtCopy;
       
   338         findPaneTxtCopy.SetLength(0);            
       
   339         findPaneTxtCopy.Copy(aFindPaneText);
       
   340                     
       
   341         //Check whether a new text was entered    
       
   342         //Ignore if " " has been entered
       
   343         if ( !isCharRemoved )
       
   344             {
       
   345             //New text was entered
       
   346             //Now we cannot render this text untill we find the match char from the Predictive search engine
       
   347             //Hence remove the newly entered char and diplay the findpane
       
   348             //once we get the callback from predictive search with the matched char
       
   349             //then we can render that char as the newly entered char
       
   350             findPaneTxtCopy.Replace(aFindPaneText.Length()-1, 1, KspaceStr);            
       
   351             SetSearchBoxTextL(findPaneTxtCopy, findPaneTxtCopy.Length());
       
   352             iLongKeyPress = ETrue;
       
   353             }
       
   354         
       
   355         searchPtr.Copy( findPaneTxtCopy );
       
   356         aFindPaneText.Copy( iPredictiveTextEntered );
       
   357         }
       
   358     else
       
   359         {
       
   360         ResetL();
       
   361         }
       
   362        
       
   363     return ETrue;
       
   364     }   
       
   365        
       
   366 // ---------------------------------------------------------------------------
       
   367 // CPbk2PredictiveSearchFilter::IsPredictiveActivated
       
   368 // ---------------------------------------------------------------------------
       
   369 //
       
   370 TBool CPbk2PredictiveSearchFilter::IsPredictiveActivated() const
       
   371     {    
       
   372     return iPredictiveSearchEnabled && !iVKbUsed;
       
   373     }
       
   374 
       
   375 
       
   376 // ---------------------------------------------------------------------------
       
   377 // CPbk2PredictiveSearchFilter::HandlePSResults
       
   378 // ---------------------------------------------------------------------------
       
   379 //
       
   380 void CPbk2PredictiveSearchFilter::HandlePSNoMatchL( const TDesC& /*aQueryString*/, const TDesC& aMatchSeq )
       
   381     {
       
   382     //we have received our Predictive Search Result
       
   383     //aMatchSeq contains the string that needs to be displayed on the FindPane
       
   384     //now we can render the string on the findPane
       
   385     if ( !IsPredictiveActivated() )
       
   386         {
       
   387         return;
       
   388         }
       
   389     
       
   390     CommitFindPaneTextL( aMatchSeq );
       
   391     }
       
   392 
       
   393 // ---------------------------------------------------------------------------
       
   394 // CPbk2PredictiveSearchFilter::LookupL
       
   395 // ---------------------------------------------------------------------------
       
   396 //
       
   397 void CPbk2PredictiveSearchFilter::LookupL( 
       
   398         const MVPbkViewContact& aContact, CPbk2PredictiveViewStack& aView, 
       
   399         MPbk2ContactNameFormatter& aNameFormatter, TDes& aMatchSeqChr )
       
   400     {
       
   401     HBufC* name(NULL);
       
   402     if( FeatureManager::FeatureSupported(KFeatureIdFfContactsCompanyNames) )
       
   403     {
       
   404         MPbk2ContactNameFormatter2* nameformatterExtension =
       
   405             reinterpret_cast<MPbk2ContactNameFormatter2*>(aNameFormatter.
       
   406                     ContactNameFormatterExtension( MPbk2ContactNameFormatterExtension2Uid ) );
       
   407         name = nameformatterExtension->GetContactTitleWithCompanyNameL(aContact.Fields(),
       
   408                 KDefaultListFormatting);
       
   409          }
       
   410      else
       
   411          {
       
   412          // Append name
       
   413          name =
       
   414          aNameFormatter.GetContactTitleL(aContact.Fields(),
       
   415              KDefaultListFormatting);
       
   416          }
       
   417     CleanupStack::PushL( name );         
       
   418               
       
   419     TPtr namePtr = name->Des();
       
   420     TRAP_IGNORE (
       
   421         if ( IsMirroredInputLang() )
       
   422             {
       
   423             // temporary solution
       
   424             // PCS LookupLmethod doesn't work correctly for
       
   425             // bidirectional languages
       
   426             RArray<TPsMatchLocation> searchMatches; 
       
   427             
       
   428             aView.GetMatchingPartsL(*name, searchMatches);
       
   429             
       
   430             TInt matchCount = searchMatches.Count();
       
   431             if( matchCount )
       
   432                 {
       
   433                 for (TInt index1=0; index1<matchCount; index1++)
       
   434                     {
       
   435                     TPsMatchLocation& location = searchMatches[index1];                    
       
   436                     aMatchSeqChr.Append(namePtr.Mid(location.index, location.length));
       
   437                     aMatchSeqChr.Append(Kspace);
       
   438                     }
       
   439                 aMatchSeqChr.LowerCase();
       
   440                 aMatchSeqChr.Trim();
       
   441                 }
       
   442             searchMatches.Close();
       
   443             }
       
   444         else
       
   445             {
       
   446             CPsQuery* lastQuery = const_cast<CPsQuery*> (aView.LastPCSQuery());
       
   447             CPSRequestHandler* psHandler = aView.PSHandler();
       
   448             if ( psHandler && lastQuery )
       
   449                 {
       
   450                 psHandler->LookupMatchL( *lastQuery, *name, aMatchSeqChr );
       
   451                 }
       
   452             }
       
   453        );
       
   454         
       
   455     CleanupStack::PopAndDestroy( name );
       
   456     }
       
   457             
       
   458 // ---------------------------------------------------------------------------
       
   459 // CPbk2PredictiveSearchFilter::CommitFindPaneTextL
       
   460 // ---------------------------------------------------------------------------
       
   461 //
       
   462 TInt CPbk2PredictiveSearchFilter::CommitFindPaneTextL( MPbk2FilteredViewStack& aViewStack,
       
   463                                 MPbk2ContactNameFormatter& aNameFormatter )
       
   464     {    
       
   465     //aViewStack contains list of the items that is currently shown in
       
   466     //the nameslist. 
       
   467     //The first item's matched characters must be shown in the Findpane    
       
   468     if ( !IsPredictiveActivated() )
       
   469         {
       
   470         return KErrNotFound;
       
   471         }    
       
   472     
       
   473     RBuf copyPredictiveTextEntered;
       
   474     CleanupClosePushL(copyPredictiveTextEntered);
       
   475     copyPredictiveTextEntered.CreateL(iPredictiveTextEntered);
       
   476     copyPredictiveTextEntered.Trim();
       
   477     TBool allCharsAreSpaces = (copyPredictiveTextEntered.Length() == 0) ? ETrue : EFalse;
       
   478     CleanupStack::PopAndDestroy(&copyPredictiveTextEntered);
       
   479     if( allCharsAreSpaces )
       
   480         {
       
   481         ReDrawL();
       
   482         return KErrNotFound;
       
   483         }
       
   484     
       
   485     TBuf<KSearchFieldLength> matchSeqChr; 
       
   486     CPbk2PredictiveViewStack& view = static_cast
       
   487                     <CPbk2PredictiveViewStack&>( aViewStack );
       
   488     TInt contactCount = aViewStack.ContactCountL();
       
   489     TInt matchedItemIndex = KErrNotFound;
       
   490     if ( &view && contactCount )
       
   491         {
       
   492    
       
   493         //Proceed, only if there are any contacts visible in the view
       
   494         TBool found = EFalse;
       
   495         CPsQuery* lastQuery = const_cast<CPsQuery*> (view.LastPCSQuery()); 
       
   496         for ( TInt index = 0; index<contactCount && lastQuery && !found; index++ )
       
   497             {
       
   498             //Iterate untill we find a match to our predictive search query      
       
   499             if ( view.IsNonMatchingMarkedContact( index ) )
       
   500                 {
       
   501                 //Avoid any mess with the marked contacts that are not part of our
       
   502                 //search result
       
   503                 continue;
       
   504                 }
       
   505             
       
   506             //Get the item from the view stack
       
   507             const MVPbkViewContact& contact = aViewStack.ContactAtL( index );
       
   508             LookupL( contact, view, aNameFormatter, matchSeqChr );
       
   509             found = matchSeqChr.Length();
       
   510             if ( found )
       
   511                 {
       
   512                 matchedItemIndex = index;
       
   513                 }
       
   514             }
       
   515         }
       
   516     
       
   517     CommitFindPaneTextL( matchSeqChr );
       
   518     return matchedItemIndex;
       
   519     }
       
   520 
       
   521 // ---------------------------------------------------------------------------
       
   522 // CPbk2PredictiveSearchFilter::CommitFindPaneTextL
       
   523 // ---------------------------------------------------------------------------
       
   524 //
       
   525 void CPbk2PredictiveSearchFilter::CommitFindPaneTextL( MPbk2FilteredViewStack& aViewStack,
       
   526                                 MPbk2ContactNameFormatter& aNameFormatter, const TInt aIndex )
       
   527     {
       
   528     CPbk2PredictiveViewStack& view = static_cast
       
   529                      <CPbk2PredictiveViewStack&>( aViewStack );
       
   530     const MVPbkViewContact& contact = aViewStack.ContactAtL( aIndex );
       
   531     TBuf<KSearchFieldLength> matchSeqChr; 
       
   532     LookupL( contact, view, aNameFormatter, matchSeqChr );
       
   533     CommitFindPaneTextL( matchSeqChr );
       
   534     }
       
   535 
       
   536 // ---------------------------------------------------------------------------
       
   537 // CPbk2PredictiveSearchFilter::CommitFindPaneTextL
       
   538 // ---------------------------------------------------------------------------
       
   539 //
       
   540 void CPbk2PredictiveSearchFilter::CommitFindPaneTextL( const TDesC& aMatchSeq )
       
   541     {
       
   542     if ( !iSearchText )
       
   543         {
       
   544         return;
       
   545         }
       
   546     
       
   547     TPtr searchPtr (iSearchText->Des()); //Text with which previous search was initiated    
       
   548     TInt len = iPredictiveTextEntered.Length();
       
   549     TInt matchSeqLen = aMatchSeq.Length();
       
   550     TBuf <KSearchFieldLength> searchTextBuffer;    
       
   551     searchTextBuffer.Copy( searchPtr.Left( len ) );
       
   552     
       
   553     //if the last character was not a space  
       
   554     if ( len )            
       
   555         {
       
   556         if (matchSeqLen)
       
   557             {
       
   558             TInt matchSeqIndex( 0 );
       
   559             for ( TInt index = 0; index < len; index++ )
       
   560                 {
       
   561                 if ( (matchSeqIndex < matchSeqLen) && (aMatchSeq[matchSeqIndex] == Kspace) )
       
   562                     {
       
   563                     ++matchSeqIndex;
       
   564                     }
       
   565                 if ( ( iPredictiveTextEntered[index] != Kspace ) 
       
   566                                 && ( matchSeqIndex < matchSeqLen ) )
       
   567                     {
       
   568                     searchTextBuffer[index] = aMatchSeq[matchSeqIndex++];
       
   569                     }
       
   570                 }
       
   571             
       
   572             iLocked = EFalse;          
       
   573             }
       
   574         else
       
   575             {                     
       
   576             for (TInt index=0; index<len; index++)
       
   577                 {
       
   578                 if ( searchTextBuffer[index] == Kspace )
       
   579                     {
       
   580                     searchTextBuffer[index] = iPredictiveTextEntered[index];
       
   581                     }
       
   582                 }
       
   583             //there is no item to match this predictive serach query
       
   584             //hence replace the new character with ? and
       
   585             //lock the Findpane filter
       
   586             searchTextBuffer.Replace(
       
   587                     searchTextBuffer.Length()-1, 
       
   588                     KQuestionMark().Length(), 
       
   589                     KQuestionMark);
       
   590             iLocked = ETrue;    
       
   591             }
       
   592 
       
   593         SetSearchBoxTextL(searchTextBuffer, searchTextBuffer.Length());
       
   594         
       
   595         if (iLocked)
       
   596             {
       
   597             //Push the filter to the Top of the View Stack
       
   598             //AddToViewStackL will be run in OfferKeyEventL because it breaks FEP transaction
       
   599             iAddToViewStack = ETrue;
       
   600             }
       
   601         else
       
   602             {
       
   603             //Remove the filter from the Top of the View Stack
       
   604             RemoveFromViewStack();
       
   605             }
       
   606         iFiltering = EFalse;
       
   607         }
       
   608     }
       
   609 
       
   610 // ---------------------------------------------------------------------------
       
   611 // CPbk2PredictiveSearchFilter::IsLocked
       
   612 // ---------------------------------------------------------------------------
       
   613 //
       
   614 TBool CPbk2PredictiveSearchFilter::IsLocked() const
       
   615     {
       
   616     TBool locked (EFalse);
       
   617     if ( IsPredictiveActivated() )
       
   618         {
       
   619         locked = iLocked;
       
   620         }
       
   621     return locked;
       
   622     }
       
   623 
       
   624 // ---------------------------------------------------------------------------
       
   625 // CPbk2PredictiveSearchFilter::OfferKeyEventL
       
   626 // ---------------------------------------------------------------------------
       
   627 //
       
   628 TKeyResponse CPbk2PredictiveSearchFilter::OfferKeyEventL
       
   629         ( const TKeyEvent& aKeyEvent, TEventCode aType )
       
   630     {
       
   631     TKeyResponse keyConsume( EKeyWasNotConsumed ); 
       
   632     iEditorMode = ENone;
       
   633     
       
   634     if (IsPredictiveActivated())
       
   635         {
       
   636         if( iAddToViewStack )
       
   637             {
       
   638 			//Push the filter to the Top of the View Stack
       
   639  		    //run delayed AddToViewStackL
       
   640             AddToViewStackL();
       
   641             iAddToViewStack = EFalse;
       
   642             }
       
   643         TChar ch(aKeyEvent.iScanCode);
       
   644         //If the FindPane filter is locked, discard all
       
   645         //other keys here. Since the filter is of high priority
       
   646         //than the FEP, FEP will not get the keyevent if consumed
       
   647         //by the findpane filter
       
   648         if (iLocked && ch.IsAlphaDigit())
       
   649             {
       
   650             keyConsume = EKeyWasConsumed;
       
   651             }
       
   652         else
       
   653             {
       
   654             if ( aType == EEventKeyDown )
       
   655                 {
       
   656                 iLongKeyPress = EFalse;
       
   657                 }
       
   658             TInt code=aKeyEvent.iCode;
       
   659             const TInt modifiers=aKeyEvent.iModifiers;            
       
   660             TBool magnify=modifiers&EModifierCtrl;            
       
   661             
       
   662             if ( code == EKeyBackspace)
       
   663                 {
       
   664                 //Release the findPane lock
       
   665                 iLocked = EFalse;
       
   666                 if( iSearchText && iRemoveSpace )
       
   667                     {
       
   668                     SetSearchBoxTextL(*iSearchText, iSearchText->Length());
       
   669                     iRemoveSpace = EFalse;
       
   670                     }
       
   671                 }
       
   672             
       
   673             //This Checks whether a Paste Operation was performed
       
   674             //on the findpane or not
       
   675             if (magnify && ( code<100 && code!=' ' ) ) ////!!! magic number
       
   676                 {        
       
   677                 TBuf<KSearchFieldLength> buf;        
       
   678                 iCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_CTRL_HOTKEYS);
       
   679                 TInt ret=buf.Locate(TChar(code+'a'-1));        
       
   680                 if ( ret == CEikEdwin::EHotKeyPaste )
       
   681                     {
       
   682                     iEditorMode = EPaste;
       
   683                     }
       
   684                 }
       
   685             }
       
   686         }        
       
   687     return keyConsume;
       
   688     }
       
   689 
       
   690 // ---------------------------------------------------------------------------
       
   691 // CPbk2PredictiveSearchFilter::ResetL
       
   692 // ---------------------------------------------------------------------------
       
   693 //
       
   694 void CPbk2PredictiveSearchFilter::ResetL()
       
   695     {
       
   696     iVKbUsed = EFalse;
       
   697     RemoveFromViewStack();    
       
   698     
       
   699     delete iSearchText;
       
   700     iSearchText = NULL;    
       
   701             
       
   702     iSearchText = HBufC::NewL( KSearchFieldLength );
       
   703     iFiltering = EFalse;
       
   704     iLocked = EFalse;
       
   705     iLongKeyPress = EFalse;
       
   706     iPredictiveTextEntered.Close();
       
   707     iPredictiveTextEntered.CreateL( KSearchFieldLength );
       
   708     }
       
   709     
       
   710 // ---------------------------------------------------------------------------
       
   711 // CPbk2PredictiveSearchFilter::FindPaneResetL
       
   712 // ---------------------------------------------------------------------------
       
   713 //
       
   714 void CPbk2PredictiveSearchFilter::FindPaneResetL()
       
   715     {
       
   716     if ( iSearchField )
       
   717         {
       
   718         iSearchField->ResetL();
       
   719         }
       
   720     }
       
   721 
       
   722 // ---------------------------------------------------------------------------
       
   723 // CPbk2PredictiveSearchFilter::GetSearchTextL
       
   724 // ---------------------------------------------------------------------------
       
   725 //
       
   726 void CPbk2PredictiveSearchFilter::GetSearchTextL( RBuf& aSearchText )
       
   727     {
       
   728     //Reset
       
   729     aSearchText.Close();
       
   730     
       
   731     if (IsPredictiveActivated())
       
   732         {
       
   733         aSearchText.CreateL( iPredictiveTextEntered.Length() );
       
   734         aSearchText.Copy( iPredictiveTextEntered );        
       
   735         }
       
   736     else
       
   737         {
       
   738         aSearchText.CreateL ( iSearchField->TextLength() );
       
   739         iSearchField->GetSearchText( aSearchText );        
       
   740         }    
       
   741     }
       
   742 
       
   743 // ---------------------------------------------------------------------------
       
   744 // CPbk2PredictiveSearchFilter::SetAknSearchFieldL
       
   745 // ---------------------------------------------------------------------------
       
   746 //
       
   747 void CPbk2PredictiveSearchFilter::SetAknSearchFieldL( CAknSearchField* aSearchField )
       
   748     {
       
   749     iSearchField = aSearchField;
       
   750     iPredictiveTextEntered.CreateL( KSearchFieldLength );
       
   751     iSearchText = HBufC::NewL( KSearchFieldLength );
       
   752     }
       
   753 
       
   754 // ---------------------------------------------------------------------------
       
   755 // CPbk2PredictiveSearchFilter::IsPasteMode
       
   756 // ---------------------------------------------------------------------------
       
   757 //
       
   758 TBool CPbk2PredictiveSearchFilter::IsPasteMode()
       
   759     {
       
   760     return (iEditorMode == EPaste) ? ETrue : EFalse;
       
   761     }
       
   762 
       
   763 // ---------------------------------------------------------------------------
       
   764 // CPbk2PredictiveSearchFilter::AddToViewStackL
       
   765 // ---------------------------------------------------------------------------
       
   766 //
       
   767 void CPbk2PredictiveSearchFilter::AddToViewStackL()
       
   768     {
       
   769     if ( !iViewStack )
       
   770         {
       
   771         iViewStack = ETrue;
       
   772         iAppUi.AddToStackL(this, ECoeStackPriorityEnvironmentFilter, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
       
   773         }
       
   774     }
       
   775 
       
   776 
       
   777 // ---------------------------------------------------------------------------
       
   778 // CPbk2PredictiveSearchFilter::RemoveFromViewStack
       
   779 // ---------------------------------------------------------------------------
       
   780 //
       
   781 void CPbk2PredictiveSearchFilter::RemoveFromViewStack()
       
   782     {
       
   783     if ( iViewStack )
       
   784         {
       
   785         iViewStack = EFalse;
       
   786         iAppUi.RemoveFromStack(this);
       
   787         }
       
   788     }
       
   789 
       
   790 // ---------------------------------------------------------------------------
       
   791 // CPbk2PredictiveSearchFilter::HandleForegroundEventL
       
   792 // ---------------------------------------------------------------------------
       
   793 //
       
   794 void CPbk2PredictiveSearchFilter::HandleForegroundEventL(TBool aForeground)
       
   795     {
       
   796     if ( aForeground && iLocked )
       
   797         {
       
   798         AddToViewStackL();
       
   799         }
       
   800     else
       
   801         {
       
   802         RemoveFromViewStack();
       
   803         }
       
   804     }
       
   805 
       
   806 // ---------------------------------------------------------------------------
       
   807 // CPbk2PredictiveSearchFilter::FindPaneTextL
       
   808 // ---------------------------------------------------------------------------
       
   809 //
       
   810 HBufC* CPbk2PredictiveSearchFilter::FindPaneTextL()
       
   811     {
       
   812     HBufC* findTextBuf( NULL );
       
   813     if ( iSearchField )
       
   814         {
       
   815         TPbk2FindTextUtil::EnsureFindTextBufSizeL( 
       
   816                 *iSearchField,
       
   817                 &findTextBuf );
       
   818         TPtr bufPtr = findTextBuf->Des();
       
   819         iSearchField->GetSearchText(bufPtr);
       
   820         if ( iLocked )
       
   821             {
       
   822             TInt index = bufPtr.LocateReverse( Kquestion );
       
   823             if ( ( KErrNotFound != index )  && ( index == bufPtr.Length() - 1 ) )
       
   824                 {
       
   825                 bufPtr.Delete( index, 1 );
       
   826                 }
       
   827             }        
       
   828         }
       
   829 
       
   830     return findTextBuf;
       
   831     }
       
   832 
       
   833 
       
   834 // ---------------------------------------------------------------------------
       
   835 // CPbk2PredictiveSearchFilter::IsMirroredInputLang
       
   836 // ---------------------------------------------------------------------------
       
   837 //
       
   838 TBool CPbk2PredictiveSearchFilter::IsMirroredInputLang()
       
   839     {
       
   840     // Check if we have mirrored input
       
   841     // It is possible to have mixed input in search string. Always ask repository file to get
       
   842     // correct input language
       
   843     
       
   844     TBool mirroredInput( EFalse );
       
   845     TInt inputLang( 0 );
       
   846     CRepository* centRep( NULL );
       
   847     TRAPD(leavecode, centRep = CRepository::NewL( KCRUidAknFep ) );
       
   848     if( KErrNone == leavecode )
       
   849         {
       
   850         centRep->Get( KAknFepInputTxtLang, inputLang );
       
   851         }
       
   852     delete centRep;
       
   853     
       
   854     mirroredInput = ( inputLang == ELangArabic ||
       
   855                       inputLang == ELangHebrew ||
       
   856                       inputLang == ELangFarsi);            
       
   857             
       
   858     return mirroredInput;
       
   859     }
       
   860 
       
   861 // ---------------------------------------------------------------------------
       
   862 // CPbk2PredictiveSearchFilter::SetSearchBoxTextL
       
   863 // ---------------------------------------------------------------------------
       
   864 //
       
   865 void CPbk2PredictiveSearchFilter::ReDrawL(TBool aAsynchronous)
       
   866     {
       
   867     if( aAsynchronous )
       
   868         {
       
   869         iRunAsynch->ReDraw();
       
   870         return;
       
   871         }
       
   872     
       
   873     if( iSearchField )
       
   874         {
       
   875         RBuf searchText;
       
   876         searchText.CreateL ( iSearchField->TextLength() );
       
   877         CleanupClosePushL( searchText );
       
   878         iSearchField->GetSearchText( searchText );
       
   879         SetSearchBoxTextL( searchText, iSearchField->TextLength() );
       
   880         CleanupStack::PopAndDestroy(&searchText);
       
   881         }
       
   882     }
       
   883 
       
   884 // ---------------------------------------------------------------------------
       
   885 // CPbk2PredictiveSearchFilter::SetSearchBoxTextL
       
   886 // ---------------------------------------------------------------------------
       
   887 //
       
   888 void CPbk2PredictiveSearchFilter::SetSearchBoxTextL( const TDesC& aText, TInt aCursorPos, TBool aDrawNow )
       
   889     {
       
   890     if( iSearchField )
       
   891         {
       
   892         iFiltering = ETrue;
       
   893         CEikEdwin& editor(iSearchField->Editor());
       
   894         if( IsPredictiveActivated() && aText.Length() )
       
   895             {
       
   896             CGlobalText* globalText = static_cast<CGlobalText*>(editor.Text());
       
   897             TCharFormat format;
       
   898             TCharFormatMask mask;
       
   899             TInt pos = 0;
       
   900             TInt length = aText.Length();
       
   901             globalText->GetCharFormat(format, mask, pos, length);
       
   902             format.iFontPresentation.iUnderline = EUnderlineOn;
       
   903             mask.SetAttrib(EAttFontUnderline);
       
   904             globalText->ApplyCharFormatL(format, mask, pos, length);
       
   905             editor.SetDocumentContentL(*globalText);
       
   906             }
       
   907         editor.SetTextL(&aText);
       
   908         editor.SetCursorPosL(aCursorPos, EFalse);
       
   909         if( aDrawNow )
       
   910             {
       
   911             editor.DrawNow();
       
   912             }
       
   913         iFiltering = EFalse;
       
   914         }
       
   915     }
       
   916 
       
   917  //End of File