phonebookui/Phonebook2/UIControls/src/CPbk2PredictiveSearchFilter.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2PredictiveSearchFilter.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,917 @@
+/*
+* Copyright (c) 2002-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: 
+*     Phonebook 2 search pane filter. This acts as a wrapper to the FindBox in
+*     NameslistView. Info needs to be passed to this filter before the FindBox
+*
+*/
+
+// INCLUDE FILES
+#include "CPbk2PredictiveSearchFilter.h"
+
+// Phonebook 2
+#include <Phonebook2PrivateCRKeys.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <MPbk2ContactNameFormatter2.h>
+#include <MVPbkViewContact.h>
+#include "MPbk2FilteredViewStack.h"
+#include "cpbk2predictiveviewstack.h"
+#include "TPbk2FindTextUtil.h"
+// Debugging headers
+#include <Pbk2Debug.h>
+
+//Avkon System includes
+#include <aknsfld.h>
+#include <txtetext.h>
+#include <eikenv.h>
+#include <eikappui.h>
+#include <EIKCOCTL.rsg>
+#include <eikedwin.h>
+#include <featmgr.h>
+#include <AknFepInternalCRKeys.h>
+#include <txtglobl.h>
+
+//PS
+#include <CPsRequestHandler.h>
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+_LIT(KQuestionMark, "?");
+_LIT(KspaceStr, " ");
+const TInt Kspace = ' ';
+const TInt Kquestion = '?';
+const TInt KDefaultListFormatting =
+        MPbk2ContactNameFormatter::EUseSeparator |
+        MPbk2ContactNameFormatter::EPreserveLeadingSpaces;
+
+} /// namespace
+
+NONSHARABLE_CLASS( CRunAsynch ): public CActive
+    {
+    public:
+        static CRunAsynch* NewL(CPbk2PredictiveSearchFilter* aParent);
+        void ReDraw();
+        
+        ~CRunAsynch();
+    private: 
+        CRunAsynch(CPbk2PredictiveSearchFilter* aParent);
+        
+        void RunL();
+        void DoCancel();
+        
+    private: //Data
+        CPbk2PredictiveSearchFilter* iParent;
+    };
+
+// --------------------------------------------------------------------------
+// CRunAsynch::CRunAsynch
+// --------------------------------------------------------------------------
+//
+CRunAsynch::CRunAsynch(CPbk2PredictiveSearchFilter* aParent) :
+    CActive(EPriorityIdle), 
+    iParent(aParent) 
+    {
+    CActiveScheduler::Add(this);
+    }
+
+// --------------------------------------------------------------------------
+// CRunAsynch::~CRunAsynch
+// --------------------------------------------------------------------------
+//
+inline CRunAsynch::~CRunAsynch()
+    {
+    Cancel();
+    }
+
+// --------------------------------------------------------------------------
+// CRunAsynch::NewL
+// --------------------------------------------------------------------------
+//
+CRunAsynch* CRunAsynch::NewL(CPbk2PredictiveSearchFilter* aParent)
+    {
+    CRunAsynch* self = new ( ELeave ) CRunAsynch(aParent);
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CRunAsynch::Redraw
+// --------------------------------------------------------------------------
+//
+void CRunAsynch::ReDraw()
+    {
+    if(!IsActive())
+        {
+        TRequestStatus* status=&iStatus;
+        User::RequestComplete(status, KErrNone);
+        SetActive();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CRunAsynch::DoCancel
+// --------------------------------------------------------------------------
+//
+void CRunAsynch::DoCancel()
+    {
+    
+    }
+
+// --------------------------------------------------------------------------
+// CRunAsynch::RunL
+// --------------------------------------------------------------------------
+//
+void CRunAsynch::RunL()
+    {
+    iParent->ReDrawL();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::CPbk2PredictiveSearchFilter
+// --------------------------------------------------------------------------
+//
+inline CPbk2PredictiveSearchFilter::CPbk2PredictiveSearchFilter() :
+    iFiltering(EFalse),
+    iAppUi( *(iEikonEnv->EikAppUi()) ),
+    iPredictiveSearchEnabled(EFalse)
+    {
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::~CPbk2PredictiveSearchFilter
+// --------------------------------------------------------------------------
+//
+CPbk2PredictiveSearchFilter::~CPbk2PredictiveSearchFilter()
+    {    
+    RemoveFromViewStack();    
+    iPredictiveTextEntered.Close();    
+    delete iSearchText;
+    delete iRunAsynch;
+    // UnInitialize feature manager
+    FeatureManager::UnInitializeLib();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2PredictiveSearchFilter* CPbk2PredictiveSearchFilter::NewL()
+    {
+    CPbk2PredictiveSearchFilter* self =
+        new ( ELeave ) CPbk2PredictiveSearchFilter();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::ConstructL()
+    {
+    // Initialize feature manager
+    FeatureManager::InitializeLibL();
+
+    if(FeatureManager::FeatureSupported(KFeatureIdFfContactsPredictiveSearch))
+        {
+        //The implementation algorithm suppose that only this class is
+        //responsible to change or return PCS input mode therefore we can use this value
+        CRepository* repository = CRepository::NewLC(TUid::Uid(KCRUidPhonebook));    
+        repository->Get( KPhonebookPredictiveSearchEnablerFlags, iPredictiveSearchEnabled );      
+        CleanupStack::PopAndDestroy(); //repository
+        
+        }
+ 
+    iRunAsynch = CRunAsynch::NewL(this);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::FilterL
+// --------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::FilterL( 
+        const TKeyEvent& aKeyEvent, 
+        TEventCode aType,
+        CAknSearchField* aSearchField )
+    {    
+    
+    if( aType == EEventKeyDown && aKeyEvent.iCode == EKeyNull )
+        {        
+        if( IsPredictiveActivated() && aSearchField )
+            {
+            iFiltering = ETrue;
+            
+            // Before single click it does nothing, but between multitap 
+            // clicks it breaks Fep transaction.
+            // It removes multitap. 
+            RBuf searchText;
+            searchText.CreateL( aSearchField->TextLength() );
+            CleanupClosePushL( searchText );
+            aSearchField->GetSearchText( searchText );       
+            aSearchField->SetSearchTextL( searchText );
+            aSearchField->SetFocus( ETrue, EDrawNow );
+            CleanupStack::PopAndDestroy( &searchText );
+            iFiltering = EFalse;  
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::IsFiltering
+// --------------------------------------------------------------------------
+//
+TBool CPbk2PredictiveSearchFilter::IsFiltering()
+    {
+    return iFiltering;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::StartFindPaneInlineEditL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2PredictiveSearchFilter::StartFindPaneInlineEditL( TDes& aFindPaneText )
+    {
+    //Level 1 : Check if virtual keyboard was used
+    if( !iVKbUsed && iSearchField && iSearchText->Length() < aFindPaneText.Length() &&
+         (iSearchField->Editor().AknEdwinFlags() & EAknEditorFlagTouchInputModeOpened) )
+        {
+        iVKbUsed = ETrue;
+        }
+    //Level 2 : Check if predictive serach is activated or not
+    //if predictive serach is not activated, avoid performing
+    //any operation on the same string in FindPane
+    if ( !IsPredictiveActivated() )
+        {
+        return ETrue;
+        }
+    TPtr searchPtr (iSearchText->Des()); //Text which holds the FindPane display text    
+    TInt findPaneTxtLen = aFindPaneText.Length(); 
+        
+    //Level 3: If search text filtering is ongoing, avoid performing
+    //any operation on the same string in FindPane 
+    if (iFiltering )
+        {
+        return EFalse;
+        }    
+    
+    //Level 4: HandleControlEventL wil be called more than once, avoid performing
+    //any operation on the same string in FindPane 
+    if (aFindPaneText.Compare(searchPtr) == 0)//HandleControlEventL wil be called more than once, avoid performing
+                                          //any operation on the same string in FindPane
+        {            
+        return EFalse;
+        }
+    
+    //Level 5: If editor is locked, avoid performing
+    //any operation on the same string in FindPane 
+    if ( iLocked ) 
+        { 
+        if( aFindPaneText.Length() > 1 && aFindPaneText[aFindPaneText.Length() - 2] == Kquestion )
+            {
+            TBuf <KSearchFieldLength> findPaneTxtCopy;
+            findPaneTxtCopy.SetLength(0);            
+            findPaneTxtCopy.Copy(aFindPaneText);
+            findPaneTxtCopy.Replace(aFindPaneText.Length() - 1, 1, KspaceStr);            
+            SetSearchBoxTextL(findPaneTxtCopy, findPaneTxtCopy.Length() - 1);
+            iRemoveSpace = ETrue;
+            }
+        return EFalse;
+        }
+    
+    TBool isCharRemoved (EFalse); //To know whether its a backspace char or not. If backspace nothing needs to be done
+    if ( findPaneTxtLen )
+        {    
+        TInt len = iPredictiveTextEntered.Length();
+        //Append the newly entered char into our predictive search query string
+        if ( findPaneTxtLen >= len )
+            {
+            if ( iLongKeyPress )
+                {
+                //If it was a long key press
+                //Normally during Long Key Press, there are 2 actions that happen
+                //first the char is displayed and then followed by that the number
+                //eg. the numeric key pad "2" denotes "abc2...", when u long press 2, 
+                //first the char 'a' is shown
+                //and then followed by that it shows '2'. 
+                //We get 2 events one wih 'a' and next with '2'
+                //So, we need to send first 'a' to the predictive search
+                //and then followed by this '2'.
+                //So During this case, the Fep transaction is broken because of us
+                //and thus the FEP will send the event with any of the strings
+                //' 2' or '*2'(* - denotes the matched char for the 1stquery a)
+                //If Long Key Press, we remove the previous char and use the new one
+                //for our search, otherwise we might end up sending a search req for 
+                //as 'a2' if that would have been a long key press on mumeric keypad 2.
+                iPredictiveTextEntered.Delete( len - 1, 1 );
+                iLongKeyPress = EFalse;
+                }
+            if ( findPaneTxtLen == len )
+                {
+                len = len - 1;
+                isCharRemoved = ETrue;
+                }
+            //Append the newly entered char to our predictive search query. 
+            iPredictiveTextEntered.Append( aFindPaneText.Right(findPaneTxtLen - len) );
+            }
+        else
+            {
+            //Some chars have been removed so delete the app char from our predictive search query            
+            iPredictiveTextEntered.Delete( findPaneTxtLen, iPredictiveTextEntered.Length() - findPaneTxtLen );
+            isCharRemoved = ETrue;
+            }
+        
+        TBuf <KSearchFieldLength> findPaneTxtCopy;
+        findPaneTxtCopy.SetLength(0);            
+        findPaneTxtCopy.Copy(aFindPaneText);
+                    
+        //Check whether a new text was entered    
+        //Ignore if " " has been entered
+        if ( !isCharRemoved )
+            {
+            //New text was entered
+            //Now we cannot render this text untill we find the match char from the Predictive search engine
+            //Hence remove the newly entered char and diplay the findpane
+            //once we get the callback from predictive search with the matched char
+            //then we can render that char as the newly entered char
+            findPaneTxtCopy.Replace(aFindPaneText.Length()-1, 1, KspaceStr);            
+            SetSearchBoxTextL(findPaneTxtCopy, findPaneTxtCopy.Length());
+            iLongKeyPress = ETrue;
+            }
+        
+        searchPtr.Copy( findPaneTxtCopy );
+        aFindPaneText.Copy( iPredictiveTextEntered );
+        }
+    else
+        {
+        ResetL();
+        }
+       
+    return ETrue;
+    }   
+       
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::IsPredictiveActivated
+// ---------------------------------------------------------------------------
+//
+TBool CPbk2PredictiveSearchFilter::IsPredictiveActivated() const
+    {    
+    return iPredictiveSearchEnabled && !iVKbUsed;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::HandlePSResults
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::HandlePSNoMatchL( const TDesC& /*aQueryString*/, const TDesC& aMatchSeq )
+    {
+    //we have received our Predictive Search Result
+    //aMatchSeq contains the string that needs to be displayed on the FindPane
+    //now we can render the string on the findPane
+    if ( !IsPredictiveActivated() )
+        {
+        return;
+        }
+    
+    CommitFindPaneTextL( aMatchSeq );
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::LookupL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::LookupL( 
+        const MVPbkViewContact& aContact, CPbk2PredictiveViewStack& aView, 
+        MPbk2ContactNameFormatter& aNameFormatter, TDes& aMatchSeqChr )
+    {
+    HBufC* name(NULL);
+    if( FeatureManager::FeatureSupported(KFeatureIdFfContactsCompanyNames) )
+    {
+        MPbk2ContactNameFormatter2* nameformatterExtension =
+            reinterpret_cast<MPbk2ContactNameFormatter2*>(aNameFormatter.
+                    ContactNameFormatterExtension( MPbk2ContactNameFormatterExtension2Uid ) );
+        name = nameformatterExtension->GetContactTitleWithCompanyNameL(aContact.Fields(),
+                KDefaultListFormatting);
+         }
+     else
+         {
+         // Append name
+         name =
+         aNameFormatter.GetContactTitleL(aContact.Fields(),
+             KDefaultListFormatting);
+         }
+    CleanupStack::PushL( name );         
+              
+    TPtr namePtr = name->Des();
+    TRAP_IGNORE (
+        if ( IsMirroredInputLang() )
+            {
+            // temporary solution
+            // PCS LookupLmethod doesn't work correctly for
+            // bidirectional languages
+            RArray<TPsMatchLocation> searchMatches; 
+            
+            aView.GetMatchingPartsL(*name, searchMatches);
+            
+            TInt matchCount = searchMatches.Count();
+            if( matchCount )
+                {
+                for (TInt index1=0; index1<matchCount; index1++)
+                    {
+                    TPsMatchLocation& location = searchMatches[index1];                    
+                    aMatchSeqChr.Append(namePtr.Mid(location.index, location.length));
+                    aMatchSeqChr.Append(Kspace);
+                    }
+                aMatchSeqChr.LowerCase();
+                aMatchSeqChr.Trim();
+                }
+            searchMatches.Close();
+            }
+        else
+            {
+            CPsQuery* lastQuery = const_cast<CPsQuery*> (aView.LastPCSQuery());
+            CPSRequestHandler* psHandler = aView.PSHandler();
+            if ( psHandler && lastQuery )
+                {
+                psHandler->LookupMatchL( *lastQuery, *name, aMatchSeqChr );
+                }
+            }
+       );
+        
+    CleanupStack::PopAndDestroy( name );
+    }
+            
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::CommitFindPaneTextL
+// ---------------------------------------------------------------------------
+//
+TInt CPbk2PredictiveSearchFilter::CommitFindPaneTextL( MPbk2FilteredViewStack& aViewStack,
+                                MPbk2ContactNameFormatter& aNameFormatter )
+    {    
+    //aViewStack contains list of the items that is currently shown in
+    //the nameslist. 
+    //The first item's matched characters must be shown in the Findpane    
+    if ( !IsPredictiveActivated() )
+        {
+        return KErrNotFound;
+        }    
+    
+    RBuf copyPredictiveTextEntered;
+    CleanupClosePushL(copyPredictiveTextEntered);
+    copyPredictiveTextEntered.CreateL(iPredictiveTextEntered);
+    copyPredictiveTextEntered.Trim();
+    TBool allCharsAreSpaces = (copyPredictiveTextEntered.Length() == 0) ? ETrue : EFalse;
+    CleanupStack::PopAndDestroy(&copyPredictiveTextEntered);
+    if( allCharsAreSpaces )
+        {
+        ReDrawL();
+        return KErrNotFound;
+        }
+    
+    TBuf<KSearchFieldLength> matchSeqChr; 
+    CPbk2PredictiveViewStack& view = static_cast
+                    <CPbk2PredictiveViewStack&>( aViewStack );
+    TInt contactCount = aViewStack.ContactCountL();
+    TInt matchedItemIndex = KErrNotFound;
+    if ( &view && contactCount )
+        {
+   
+        //Proceed, only if there are any contacts visible in the view
+        TBool found = EFalse;
+        CPsQuery* lastQuery = const_cast<CPsQuery*> (view.LastPCSQuery()); 
+        for ( TInt index = 0; index<contactCount && lastQuery && !found; index++ )
+            {
+            //Iterate untill we find a match to our predictive search query      
+            if ( view.IsNonMatchingMarkedContact( index ) )
+                {
+                //Avoid any mess with the marked contacts that are not part of our
+                //search result
+                continue;
+                }
+            
+            //Get the item from the view stack
+            const MVPbkViewContact& contact = aViewStack.ContactAtL( index );
+            LookupL( contact, view, aNameFormatter, matchSeqChr );
+            found = matchSeqChr.Length();
+            if ( found )
+                {
+                matchedItemIndex = index;
+                }
+            }
+        }
+    
+    CommitFindPaneTextL( matchSeqChr );
+    return matchedItemIndex;
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::CommitFindPaneTextL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::CommitFindPaneTextL( MPbk2FilteredViewStack& aViewStack,
+                                MPbk2ContactNameFormatter& aNameFormatter, const TInt aIndex )
+    {
+    CPbk2PredictiveViewStack& view = static_cast
+                     <CPbk2PredictiveViewStack&>( aViewStack );
+    const MVPbkViewContact& contact = aViewStack.ContactAtL( aIndex );
+    TBuf<KSearchFieldLength> matchSeqChr; 
+    LookupL( contact, view, aNameFormatter, matchSeqChr );
+    CommitFindPaneTextL( matchSeqChr );
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::CommitFindPaneTextL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::CommitFindPaneTextL( const TDesC& aMatchSeq )
+    {
+    if ( !iSearchText )
+        {
+        return;
+        }
+    
+    TPtr searchPtr (iSearchText->Des()); //Text with which previous search was initiated    
+    TInt len = iPredictiveTextEntered.Length();
+    TInt matchSeqLen = aMatchSeq.Length();
+    TBuf <KSearchFieldLength> searchTextBuffer;    
+    searchTextBuffer.Copy( searchPtr.Left( len ) );
+    
+    //if the last character was not a space  
+    if ( len )            
+        {
+        if (matchSeqLen)
+            {
+            TInt matchSeqIndex( 0 );
+            for ( TInt index = 0; index < len; index++ )
+                {
+                if ( (matchSeqIndex < matchSeqLen) && (aMatchSeq[matchSeqIndex] == Kspace) )
+                    {
+                    ++matchSeqIndex;
+                    }
+                if ( ( iPredictiveTextEntered[index] != Kspace ) 
+                                && ( matchSeqIndex < matchSeqLen ) )
+                    {
+                    searchTextBuffer[index] = aMatchSeq[matchSeqIndex++];
+                    }
+                }
+            
+            iLocked = EFalse;          
+            }
+        else
+            {                     
+            for (TInt index=0; index<len; index++)
+                {
+                if ( searchTextBuffer[index] == Kspace )
+                    {
+                    searchTextBuffer[index] = iPredictiveTextEntered[index];
+                    }
+                }
+            //there is no item to match this predictive serach query
+            //hence replace the new character with ? and
+            //lock the Findpane filter
+            searchTextBuffer.Replace(
+                    searchTextBuffer.Length()-1, 
+                    KQuestionMark().Length(), 
+                    KQuestionMark);
+            iLocked = ETrue;    
+            }
+
+        SetSearchBoxTextL(searchTextBuffer, searchTextBuffer.Length());
+        
+        if (iLocked)
+            {
+            //Push the filter to the Top of the View Stack
+            //AddToViewStackL will be run in OfferKeyEventL because it breaks FEP transaction
+            iAddToViewStack = ETrue;
+            }
+        else
+            {
+            //Remove the filter from the Top of the View Stack
+            RemoveFromViewStack();
+            }
+        iFiltering = EFalse;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::IsLocked
+// ---------------------------------------------------------------------------
+//
+TBool CPbk2PredictiveSearchFilter::IsLocked() const
+    {
+    TBool locked (EFalse);
+    if ( IsPredictiveActivated() )
+        {
+        locked = iLocked;
+        }
+    return locked;
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::OfferKeyEventL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CPbk2PredictiveSearchFilter::OfferKeyEventL
+        ( const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    TKeyResponse keyConsume( EKeyWasNotConsumed ); 
+    iEditorMode = ENone;
+    
+    if (IsPredictiveActivated())
+        {
+        if( iAddToViewStack )
+            {
+			//Push the filter to the Top of the View Stack
+ 		    //run delayed AddToViewStackL
+            AddToViewStackL();
+            iAddToViewStack = EFalse;
+            }
+        TChar ch(aKeyEvent.iScanCode);
+        //If the FindPane filter is locked, discard all
+        //other keys here. Since the filter is of high priority
+        //than the FEP, FEP will not get the keyevent if consumed
+        //by the findpane filter
+        if (iLocked && ch.IsAlphaDigit())
+            {
+            keyConsume = EKeyWasConsumed;
+            }
+        else
+            {
+            if ( aType == EEventKeyDown )
+                {
+                iLongKeyPress = EFalse;
+                }
+            TInt code=aKeyEvent.iCode;
+            const TInt modifiers=aKeyEvent.iModifiers;            
+            TBool magnify=modifiers&EModifierCtrl;            
+            
+            if ( code == EKeyBackspace)
+                {
+                //Release the findPane lock
+                iLocked = EFalse;
+                if( iSearchText && iRemoveSpace )
+                    {
+                    SetSearchBoxTextL(*iSearchText, iSearchText->Length());
+                    iRemoveSpace = EFalse;
+                    }
+                }
+            
+            //This Checks whether a Paste Operation was performed
+            //on the findpane or not
+            if (magnify && ( code<100 && code!=' ' ) ) ////!!! magic number
+                {        
+                TBuf<KSearchFieldLength> buf;        
+                iCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_CTRL_HOTKEYS);
+                TInt ret=buf.Locate(TChar(code+'a'-1));        
+                if ( ret == CEikEdwin::EHotKeyPaste )
+                    {
+                    iEditorMode = EPaste;
+                    }
+                }
+            }
+        }        
+    return keyConsume;
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::ResetL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::ResetL()
+    {
+    iVKbUsed = EFalse;
+    RemoveFromViewStack();    
+    
+    delete iSearchText;
+    iSearchText = NULL;    
+            
+    iSearchText = HBufC::NewL( KSearchFieldLength );
+    iFiltering = EFalse;
+    iLocked = EFalse;
+    iLongKeyPress = EFalse;
+    iPredictiveTextEntered.Close();
+    iPredictiveTextEntered.CreateL( KSearchFieldLength );
+    }
+    
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::FindPaneResetL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::FindPaneResetL()
+    {
+    if ( iSearchField )
+        {
+        iSearchField->ResetL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::GetSearchTextL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::GetSearchTextL( RBuf& aSearchText )
+    {
+    //Reset
+    aSearchText.Close();
+    
+    if (IsPredictiveActivated())
+        {
+        aSearchText.CreateL( iPredictiveTextEntered.Length() );
+        aSearchText.Copy( iPredictiveTextEntered );        
+        }
+    else
+        {
+        aSearchText.CreateL ( iSearchField->TextLength() );
+        iSearchField->GetSearchText( aSearchText );        
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::SetAknSearchFieldL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::SetAknSearchFieldL( CAknSearchField* aSearchField )
+    {
+    iSearchField = aSearchField;
+    iPredictiveTextEntered.CreateL( KSearchFieldLength );
+    iSearchText = HBufC::NewL( KSearchFieldLength );
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::IsPasteMode
+// ---------------------------------------------------------------------------
+//
+TBool CPbk2PredictiveSearchFilter::IsPasteMode()
+    {
+    return (iEditorMode == EPaste) ? ETrue : EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::AddToViewStackL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::AddToViewStackL()
+    {
+    if ( !iViewStack )
+        {
+        iViewStack = ETrue;
+        iAppUi.AddToStackL(this, ECoeStackPriorityEnvironmentFilter, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::RemoveFromViewStack
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::RemoveFromViewStack()
+    {
+    if ( iViewStack )
+        {
+        iViewStack = EFalse;
+        iAppUi.RemoveFromStack(this);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::HandleForegroundEventL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::HandleForegroundEventL(TBool aForeground)
+    {
+    if ( aForeground && iLocked )
+        {
+        AddToViewStackL();
+        }
+    else
+        {
+        RemoveFromViewStack();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::FindPaneTextL
+// ---------------------------------------------------------------------------
+//
+HBufC* CPbk2PredictiveSearchFilter::FindPaneTextL()
+    {
+    HBufC* findTextBuf( NULL );
+    if ( iSearchField )
+        {
+        TPbk2FindTextUtil::EnsureFindTextBufSizeL( 
+                *iSearchField,
+                &findTextBuf );
+        TPtr bufPtr = findTextBuf->Des();
+        iSearchField->GetSearchText(bufPtr);
+        if ( iLocked )
+            {
+            TInt index = bufPtr.LocateReverse( Kquestion );
+            if ( ( KErrNotFound != index )  && ( index == bufPtr.Length() - 1 ) )
+                {
+                bufPtr.Delete( index, 1 );
+                }
+            }        
+        }
+
+    return findTextBuf;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::IsMirroredInputLang
+// ---------------------------------------------------------------------------
+//
+TBool CPbk2PredictiveSearchFilter::IsMirroredInputLang()
+    {
+    // Check if we have mirrored input
+    // It is possible to have mixed input in search string. Always ask repository file to get
+    // correct input language
+    
+    TBool mirroredInput( EFalse );
+    TInt inputLang( 0 );
+    CRepository* centRep( NULL );
+    TRAPD(leavecode, centRep = CRepository::NewL( KCRUidAknFep ) );
+    if( KErrNone == leavecode )
+        {
+        centRep->Get( KAknFepInputTxtLang, inputLang );
+        }
+    delete centRep;
+    
+    mirroredInput = ( inputLang == ELangArabic ||
+                      inputLang == ELangHebrew ||
+                      inputLang == ELangFarsi);            
+            
+    return mirroredInput;
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::SetSearchBoxTextL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::ReDrawL(TBool aAsynchronous)
+    {
+    if( aAsynchronous )
+        {
+        iRunAsynch->ReDraw();
+        return;
+        }
+    
+    if( iSearchField )
+        {
+        RBuf searchText;
+        searchText.CreateL ( iSearchField->TextLength() );
+        CleanupClosePushL( searchText );
+        iSearchField->GetSearchText( searchText );
+        SetSearchBoxTextL( searchText, iSearchField->TextLength() );
+        CleanupStack::PopAndDestroy(&searchText);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2PredictiveSearchFilter::SetSearchBoxTextL
+// ---------------------------------------------------------------------------
+//
+void CPbk2PredictiveSearchFilter::SetSearchBoxTextL( const TDesC& aText, TInt aCursorPos, TBool aDrawNow )
+    {
+    if( iSearchField )
+        {
+        iFiltering = ETrue;
+        CEikEdwin& editor(iSearchField->Editor());
+        if( IsPredictiveActivated() && aText.Length() )
+            {
+            CGlobalText* globalText = static_cast<CGlobalText*>(editor.Text());
+            TCharFormat format;
+            TCharFormatMask mask;
+            TInt pos = 0;
+            TInt length = aText.Length();
+            globalText->GetCharFormat(format, mask, pos, length);
+            format.iFontPresentation.iUnderline = EUnderlineOn;
+            mask.SetAttrib(EAttFontUnderline);
+            globalText->ApplyCharFormatL(format, mask, pos, length);
+            editor.SetDocumentContentL(*globalText);
+            }
+        editor.SetTextL(&aText);
+        editor.SetCursorPosL(aCursorPos, EFalse);
+        if( aDrawNow )
+            {
+            editor.DrawNow();
+            }
+        iFiltering = EFalse;
+        }
+    }
+
+ //End of File