uifw/AvKon/src/AknAdaptiveSearch.cpp
changeset 0 2f259fa3e83a
child 6 9f56a4e1b8ab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknAdaptiveSearch.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,554 @@
+/*
+* Copyright (c) 2006 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:  
+*
+*/
+
+
+// INCLUDE FILES
+#include "AknAdaptiveSearch.h"
+#include <aknsfld.h>
+#include <centralrepository.h>      // CenRep for AS
+#include <AvkonInternalCRKeys.h>    // CenRep for AS
+#include <akntrace.h>               //for trace
+
+
+// CONSTANTS
+const TInt KAknStringBufferSize = 256;
+const TInt KLitHyphen('-');
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CAknAdaptiveSearch* CAknAdaptiveSearch::NewL( const TInt aTextLimit, TInt aFieldStyle )
+    {
+    CAknAdaptiveSearch* self = CAknAdaptiveSearch::NewLC( aTextLimit, aFieldStyle);
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CAknAdaptiveSearch* CAknAdaptiveSearch::NewLC( const TInt aTextLimit, TInt aFieldStyle )
+    {
+    CAknAdaptiveSearch* self = new ( ELeave ) CAknAdaptiveSearch ();
+    CleanupStack::PushL( self );
+    self->ConstructL( aTextLimit, aFieldStyle );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::CAknAdaptiveSearch
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CAknAdaptiveSearch::CAknAdaptiveSearch()     
+    : iBlockFlag( EFalse )      
+    {    
+    }     
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::~CAknAdaptiveSearch
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CAknAdaptiveSearch::~CAknAdaptiveSearch()
+    {  
+    _AKNTRACE_FUNC_ENTER;
+    if ( iAdaptiveSearchGrid )
+	    {
+	    delete iAdaptiveSearchGrid;	
+	    }
+	if( iGridChars )
+		{
+		delete iGridChars;
+		iGridChars = NULL;
+		}
+	iAdaptiveSearchTextObserver = NULL;	
+	// Stop listening CenRep.
+    if ( iCenRepNotifyHandlerChinese )
+    	{
+    	iCenRepNotifyHandlerChinese->StopListening();
+    	}
+    delete iCenRepNotifyHandlerChinese;
+    if ( iCenRepNotifyHandlerPRC )
+    	{
+    	iCenRepNotifyHandlerPRC->StopListening();
+    	}
+    delete iCenRepNotifyHandlerPRC;
+    if ( iCenRepNotifyHandlerTW )
+    	{
+    	iCenRepNotifyHandlerTW->StopListening();
+    	}
+    delete iCenRepNotifyHandlerTW;
+    if ( iCenRepNotifyHandlerHongkong )
+    	{
+    	iCenRepNotifyHandlerHongkong->StopListening();
+    	}
+    delete iCenRepNotifyHandlerHongkong;
+    delete iCenRep;    
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::ConstructL
+// Symbian 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::ConstructL( const TInt aTextLimit, TInt aSearchField )
+    {
+    _AKNTRACE_FUNC_ENTER;
+    iAdaptiveSearchGrid = CAknAdaptiveSearchGrid::NewL( aTextLimit, aSearchField );  
+    iAdaptiveSearchGrid->SetAdaptiveSearchGridObserver( this );
+    iGridChars = NULL;
+    iTextLimit = aTextLimit;
+    iAdaptiveSearchTextObserver = NULL;  
+    
+    // Start listening a CenRep key indicating input language 
+    TRAPD( err, iCenRep = CRepository::NewL( KCRUidAvkon ) );
+    if ( err == KErrNone )
+        {
+        iCenRepNotifyHandlerChinese = CCenRepNotifyHandler::NewL( *this, *iCenRep,
+                                      CCenRepNotifyHandler::EIntKey,
+                                      KAknAdaptiveSearchLastChinese );
+        iCenRepNotifyHandlerChinese->StartListeningL(); 
+        
+        iCenRepNotifyHandlerPRC = CCenRepNotifyHandler::NewL( *this, *iCenRep,
+                                  CCenRepNotifyHandler::EIntKey,
+                                  KAknAdaptiveSearchChinesePRC );
+        iCenRepNotifyHandlerPRC->StartListeningL(); 
+        
+        iCenRepNotifyHandlerTW = CCenRepNotifyHandler::NewL( *this, *iCenRep,
+                                 CCenRepNotifyHandler::EIntKey,
+                                 KAknAdaptiveSearchChineseTW);
+        iCenRepNotifyHandlerTW->StartListeningL();
+        
+        iCenRepNotifyHandlerHongkong = CCenRepNotifyHandler::NewL( *this, *iCenRep,
+                                       CCenRepNotifyHandler::EIntKey,
+                                       KAknAdaptiveSearchChineseHongkong );
+        iCenRepNotifyHandlerHongkong->StartListeningL(); 
+        }  
+    _AKNTRACE_FUNC_EXIT;
+    }
+           
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::HandleControlEventL
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::HandleControlEventL( CCoeControl */*aControl*/, 
+                                              TCoeEvent /*aEventType*/ )
+	{	
+	}
+	
+// -----------------------------------------------------------------------------
+// For Devanagari AS
+// Checks if the last character entered is a Indic halant character.
+// @param aCh - character to be checked  
+// @return ETrue if this is a halant character EFalse otherwise.                        
+// -----------------------------------------------------------------------------
+inline TBool IsIndicHalantChar( const TChar aCh )
+    {
+    //Devanagari halant character check:
+    return ( aCh == 0x094D );
+    }	
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::SetButtonCharsL
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::SetButtonCharsL( const TDesC& aGridChars )
+    {  
+    _AKNTRACE_FUNC_ENTER;
+    _AKNDEBUG(
+            _LIT( KClassName, "CAknAdaptiveSearch" );
+            _LIT( KFunctionName, "SetButtonCharsL" );
+            _LIT( KFormat, "[%S][%S] The text is: %S");
+            _AKNTRACE( KFormat, 
+            &KClassName, &KFunctionName, &aGridChars );
+            );
+	if( iGridChars )
+		{
+		delete iGridChars;
+		iGridChars = NULL;
+		}   
+
+    TBuf<KAknStringBufferSize> criteria;
+    iSearchField->GetSearchText( criteria );
+    TInt length = criteria.Length();   
+	if( !iTextLimit || length < iTextLimit )
+	    {
+	    iGridChars = HBufC::NewL( aGridChars.Length() );
+	    iGridChars->Des().Copy( aGridChars );	
+	    iAdaptiveSearchGrid->SetButtonGridChars( aGridChars );	
+					
+        // To do lower case for search pane
+        iGridChars->Des().LowerCase();          
+        iBlockFlag = EFalse;   	
+	    }
+	else
+	    {	    
+	    TPtrC nullText( KNullDesC );
+	    iAdaptiveSearchGrid->SetButtonGridChars( nullText );
+	    iBlockFlag = EFalse;   		
+	    }
+	_AKNTRACE_FUNC_EXIT;
+   	}
+	    	    	
+// -----------------------------------------------------------------------------
+// For Devanagari AS
+// Checks if the last character entered is a Indic independent character.
+// @param aCh      - character to be checked  
+// @return ETrue if this is an independent character EFalse otherwise                        
+// -----------------------------------------------------------------------------
+inline TBool IsIndicIndependentChar( const TChar aCh )
+	{
+	if (( aCh >= 0x0905 && aCh <= 0x0939 ) || ( aCh >= 0x0958 && aCh <= 0x0961 ))
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+	}
+
+
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::ProcessCommandL
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::ProcessCommandL( TInt aCommand )
+	{
+	_AKNTRACE_FUNC_ENTER;
+	 _AKNTRACE( "[%s][%s] Command ID: %d", "CAknAdaptiveSearch",
+	         __FUNCTION__, aCommand);
+	if( aCommand == CAknAdaptiveSearchGrid::ECloseGridPressed )
+		{
+		//hide grid
+        HideAdaptiveSearchGridL();
+		iSearchField->MakeVisible( ETrue );	
+		iSearchField->SetFocus( ETrue );	
+	
+		}
+    else if( aCommand == CAknAdaptiveSearchGrid::EDeleteLastCharPressed )
+		{
+		//do search text update
+		if( iSearchField )
+			{
+			TBuf<KAknStringBufferSize> criteria;
+            if ( iSearchField->Editor().SelectionLength() > 0 )
+                {
+                iAdaptiveSearchGrid->SetSearchTextToFindPane( criteria );
+                iSearchField->SetSearchTextL( criteria );
+                iSearchField->HandleControlEventL( iSearchField, EEventStateChanged );
+                }
+            else
+                {
+                iSearchField->GetSearchText( criteria );
+                }
+			TInt length = criteria.Length();
+			if( length > 0 )
+				{
+				// If Devanagari
+				if ( (criteria[length-1] == KLitHyphen) && length>1 && IsIndicIndependentChar(criteria[length-2]) )
+					{						
+					// First check if this is one of the four special ligatures, in which
+					// case, there will be a halant prior to 'criteria[length-2]'			
+					if ( (length > 3) && IsIndicHalantChar(criteria[length-3]) )
+					    {
+					    // hyphen should be removed along with the preceding 3 characters 
+					    criteria = criteria.Mid( 0, (length-4) ); 
+					    }
+					else
+					    {
+					    // normal Indic character - remove the preceding character.
+					    criteria = criteria.Mid( 0, (length-2) );
+					    }
+					}
+				else
+					{
+					criteria = criteria.Mid( 0, (length-1) );		
+					}					
+				// Update the AS search field first to be ready for redraw
+				iAdaptiveSearchGrid->SetSearchTextToFindPane( criteria );				
+                iSearchField->SetSearchTextL( criteria );   
+                iSearchField->HandleControlEventL( iSearchField, EEventStateChanged );      
+				iSearchField->SetFocus( EFalse );		        			
+				iSearchField->MakeVisible ( EFalse );
+				iAdaptiveSearchGrid->SetSearchTextToFindPane( criteria );	
+				iSearchField->DrawNow();
+				if( iAdaptiveSearchTextObserver )
+					{
+					iSearchField->SetLanguageChangedFlag( EFalse );
+					iAdaptiveSearchTextObserver->AdaptiveSearchTextChanged( iSearchField );		
+					}						
+				}
+			}
+		}
+	else if ( iBlockFlag == EFalse )
+	    {
+	    iBlockFlag = ETrue; 	       
+        TBuf<KAknStringBufferSize> criteria;
+        if ( iSearchField->Editor().SelectionLength() == 0 )
+            {
+            iSearchField->GetSearchText( criteria );            
+            }
+        // Check if Devanagari 
+        TInt indicHalantPos( KErrNotFound );
+        TInt gridCharsLength = iGridChars->Length();
+        // Search for the first appearing halant character. 
+        for ( TInt index = 1; index < gridCharsLength ; ++index )
+            {
+            if ( IsIndicHalantChar((*iGridChars)[index]) )
+                {
+                indicHalantPos = index;
+                break;
+                }
+            }
+        if ( indicHalantPos < 0 || aCommand < (indicHalantPos-1) )
+            {
+            // Western search
+            criteria.Append( iGridChars->Mid(aCommand,1) );
+            }
+        else
+            {
+            // Devanagari search
+            for ( TInt index = (indicHalantPos-1); index < gridCharsLength ; ++index )
+                {
+                if ( aCommand == index )
+                    {
+                    // check if this is an Indic special ligature
+                    if ( index+1 < gridCharsLength && IsIndicHalantChar((*iGridChars)[index+1]) )
+                        {
+                        // append the next 2 characters as well to the search criteria
+                        criteria.Append( iGridChars->Mid(index,3) );
+                        }
+                    else
+                        {
+                        // send just the one character
+                        criteria.Append( iGridChars->Mid(index,1) );
+                        }
+                    break;
+                    }
+                } // for
+             }            
+        TInt length = criteria.Length();  
+        // If Devanagri Append the placeholder for dependent vowels 
+    	if ( IsIndicIndependentChar( criteria[length-1] ) )
+        	criteria.Append( KLitHyphen );
+        	
+      	// Update the AS search field first to be ready for redraw
+        iAdaptiveSearchGrid->SetSearchTextToFindPane( criteria );       
+        iSearchField->SetSearchTextL( criteria );   
+        iSearchField->HandleControlEventL( iSearchField, EEventStateChanged );      
+    	iSearchField->SetFocus( EFalse );    	
+    	iSearchField->MakeVisible ( EFalse );
+        iSearchField->DrawNow();
+        if( iAdaptiveSearchTextObserver )
+        	{
+        	iSearchField->SetLanguageChangedFlag( EFalse );
+        	iAdaptiveSearchTextObserver->AdaptiveSearchTextChanged( iSearchField );	
+	        }
+	    }
+	_AKNTRACE_FUNC_EXIT;
+	}
+	
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::SetSearchField
+// -----------------------------------------------------------------------------
+//	
+void CAknAdaptiveSearch::SetSearchField( CAknSearchField* aSearchField )
+	{
+	iSearchField = aSearchField; 
+    iAdaptiveSearchGrid->SetMopParent( aSearchField );
+	}
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::ShowAdaptiveSearchGridL
+// Shows adaptive search grid.
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::ShowAdaptiveSearchGridL()
+	{
+	if( !iAdaptiveSearchGrid->IsShown() )
+        {
+        iAdaptiveSearchGrid->ShowL();
+        }
+	}
+
+// ----------------------------------------------------------------------------- 
+// CAknAdaptiveSearch::HandleNotifyInt
+// Check adaptive search availability from cenrep
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::HandleNotifyInt( TUint32 aId, TInt /*aNewValue*/ )
+    {
+    _AKNTRACE( "[%s][%s] The input method for adaptive search: %d", 
+                               "CAknAdaptiveSearch", __FUNCTION__, aId );
+    if ( aId == KAknAdaptiveSearchLastChinese )
+        {
+        TRAP_IGNORE( iSearchField->HandleControlEventL(iSearchField, EEventStateChanged) );          	
+        }
+    if ( aId == KAknAdaptiveSearchChinesePRC )
+        {
+        TRAP_IGNORE( iSearchField->HandleControlEventL(iSearchField, EEventStateChanged) );  
+        }   
+    if ( aId == KAknAdaptiveSearchChineseTW )
+        {
+        TRAP_IGNORE( iSearchField->HandleControlEventL(iSearchField, EEventStateChanged) );  	
+        }
+    if ( aId == KAknAdaptiveSearchChineseHongkong )
+       {
+       TRAP_IGNORE( iSearchField->HandleControlEventL(iSearchField, EEventStateChanged) );  	
+       }       
+    if( iAdaptiveSearchTextObserver )
+       {
+       iSearchField->SetLanguageChangedFlag( ETrue ); 
+       iAdaptiveSearchTextObserver->AdaptiveSearchTextChanged( iSearchField );
+       }    
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::HideAdaptiveSearchGrid
+// Hides adaptive search grid.
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::HideAdaptiveSearchGridL()
+	{
+	_AKNTRACE_FUNC_ENTER;
+	if( iAdaptiveSearchGrid->IsShown() )
+	    {
+        iAdaptiveSearchGrid->HideL();      
+	    }	
+	 _AKNTRACE_FUNC_EXIT;
+	}
+	
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::InvertAdaptiveSearchGridVisibility
+// Hides adaptive search grid if it shown, and shows if it is hide.
+// -----------------------------------------------------------------------------
+//	
+void CAknAdaptiveSearch::InvertAdaptiveSearchGridVisibilityL( TBool aSelectAll )
+	{
+	 _AKNTRACE_FUNC_ENTER;
+	// update the search text here if showing
+	TInt textLength = 0;
+	if( !iAdaptiveSearchGrid->IsShown() && &(iSearchField->Editor()) )
+	    {
+	    textLength = iSearchField->Editor().TextLength();
+	    HBufC* searchText = NULL;
+	    TPtrC finalText( KNullDesC );
+	    if( textLength > 0 )
+	        {
+	        TRAP_IGNORE( searchText = iSearchField->Editor().GetTextInHBufL() );
+    	    if( searchText )
+    	        {
+    	        finalText.Set( *searchText ); // set the value
+    	           _AKNDEBUG(
+    	                    _LIT( KClassName, "CAknAdaptiveSearch" );
+    	                    _LIT( KFunctionName, "InvertAdaptiveSearchGridVisibilityL" );
+    	                    _LIT( KFormat, "[%S][%S] Final text is: %S");
+    	                    _AKNTRACE( KFormat, 
+    	                    &KClassName, &KFunctionName, &finalText );
+    	                    );
+    	        }
+	        }	    
+    	iAdaptiveSearchGrid->SetSearchTextToFindPane( finalText );    
+    	if( searchText )
+    	    {
+    	    delete searchText;
+    	    searchText = NULL;
+    	    }
+	    }
+	TBool shown( !(iAdaptiveSearchGrid->IsShown()) );
+	if ( shown )
+	    {
+	    iSearchField->SetFocus( EFalse );	 
+	    iSearchField->MakeVisible( EFalse );   
+	    }
+	else
+	    {
+	    iSearchField->Editor().RemoveFlagFromUserFlags( CEikEdwin::EAvkonDisableVKB );
+	    iSearchField->MakeVisible( ETrue );      
+	    iSearchField->SetFocus( ETrue );	         
+	    }
+    iAdaptiveSearchGrid->SetVisibilityL( shown, aSelectAll );
+    _AKNTRACE_FUNC_EXIT;
+	}
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::AddAdaptiveSearchTextObserverL
+// Adds an adaptive search text observer.
+// -----------------------------------------------------------------------------
+// 
+void CAknAdaptiveSearch::AddAdaptiveSearchTextObserverL( MAdaptiveSearchTextObserver* aObserver )
+	{
+	iAdaptiveSearchTextObserver = aObserver;  	
+	}
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::RemoveAdaptiveSearchTextObserver
+// Removes an adaptive search text observer. 
+// -----------------------------------------------------------------------------
+//
+TBool CAknAdaptiveSearch::RemoveAdaptiveSearchTextObserver( MAdaptiveSearchTextObserver* aObserver )
+	{
+	if( iAdaptiveSearchTextObserver == aObserver )
+		{
+		iAdaptiveSearchTextObserver = NULL;
+		return ETrue;
+		}
+	else
+		{
+		return EFalse;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CAknAdaptiveSearch::UpdateGridSkinL()
+// Update adaptive search grid skin, since it can't recieve any messages
+// if it is hidden.
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::UpdateGridSkinL()
+	{
+	// only update its skin when it is hidden.
+	if (iAdaptiveSearchGrid && !iAdaptiveSearchGrid->IsShown())
+		{
+		iAdaptiveSearchGrid->HandleResourceChange(KAknsMessageSkinChange);
+		}
+	}
+
+
+// -----------------------------------------------------------------------------
+// CCAknAdaptiveSearch::SaveFindPaneRect()
+// When the rect of find pane is set, this functions will be notified
+// to record the size of it.
+// -----------------------------------------------------------------------------
+//
+void CAknAdaptiveSearch::SaveFindPaneRect( const TRect &aRect )
+    {
+    iAdaptiveSearchGrid->SaveFindPaneRect( aRect );
+    }
+
+// End of File
+