landmarksui/engine/src/CLmkSearchedLmListProvider.cpp
changeset 0 522cd55cc3d7
child 3 3c271c9e6618
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarksui/engine/src/CLmkSearchedLmListProvider.cpp	Tue Feb 02 00:16:03 2010 +0200
@@ -0,0 +1,619 @@
+/*
+* Copyright (c) 2002-2009 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:    Filtered landmarks list provider
+*
+*/
+
+
+// SYSTEM INCLUDES
+#include <EPos_CPosLmPartialReadParameters.h>
+#include <EPos_CPosLandmark.h>
+#include <EPos_TPosLmSortPref.h>
+#include <EPos_CPosLandmarkDatabase.h>
+#include <EPos_CPosLmItemIterator.h>
+#include <EPos_CPosLmSearchCriteria.h>
+#include <EPos_CPosLandmarkSearch.h>
+#include <e32math.h>
+#include <EPos_CPosLmCompositeCriteria.h>
+#include <EPos_CPosLmCategoryCriteria.h>
+#include <EPos_CPosLmIdListCriteria.h>
+#include <EPos_CPosLmTextCriteria.h>
+#include <AknWaitDialog.h>
+#include <lmkui.rsg>
+
+// USER INCLUDES
+#include "CLmkSearchedLmListProvider.h"
+#include "CLmkLandmarkUiItem.h"
+#include "CLmkAOOperation.h"
+#include "MLmkSelectorIconMgr.h"
+#include <lmkerrors.h>
+
+// CONSTANTS
+_LIT(KSpaceTextCriteria,"* ");
+_LIT(KDefaultTextCriteria,"*");
+
+#if defined(_DEBUG)
+// CONSTANTS
+/// Unnamed namespace for local definitions
+namespace {
+
+_LIT( KPanicMsg, "CLmkSearchedLmListProvider" );
+
+void Panic( TPanicCode aReason )
+    {
+    User::Panic( KPanicMsg, aReason );
+    }
+}  // namespace
+#endif
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CLmkSearchedLmListProvider::CLmkSearchedLmListProvider
+// C++ constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLmkSearchedLmListProvider::CLmkSearchedLmListProvider(
+    CPosLandmarkDatabase& aDb,
+    CPosLmSearchCriteria& aCriteria )
+    : CLmkLmItemListProvider( aDb ),
+      iCriteria( aCriteria ),
+      iIsSecondSearchStarted(EFalse)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkSearchedLmListProvider::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::ConstructL()
+    {
+    // base class 2nd phase constructor
+    CLmkLmItemListProvider::BaseConstructL();
+
+    iReadParams = CPosLmPartialReadParameters::NewLC();
+    CleanupStack::Pop(); // iReadParams
+    iReadParams->SetRequestedAttributes( CPosLandmark::ELandmarkName |
+                                         CPosLandmark::EIcon | CPosLandmark::ECategoryInfo);
+
+    iSearch = CPosLandmarkSearch::NewL( iDb );
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkSearchedLmListProvider::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CLmkSearchedLmListProvider* CLmkSearchedLmListProvider::NewL(
+    CPosLandmarkDatabase& aDb,
+    CPosLmSearchCriteria& aCriteria )
+    {
+    CLmkSearchedLmListProvider* self =
+        new ( ELeave ) CLmkSearchedLmListProvider( aDb, aCriteria );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::~CLmkSearchedLmListProvider
+// ---------------------------------------------------------
+//
+CLmkSearchedLmListProvider::~CLmkSearchedLmListProvider()
+    {
+    delete iReadParams;
+    delete iSearch;
+    if (iSearchAO)
+		{
+    	iSearchAO->StopOperation();
+    	}
+    delete iSearchAO;
+    }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::ItemAtL
+// ---------------------------------------------------------
+//
+CLmkUiItemBase* CLmkSearchedLmListProvider::ItemAtL( TInt aIndex )
+    {
+    __ASSERT_DEBUG( iIconMgr, Panic( KLmkPanicNullMember ) );
+    //landmark with updated icon, if associated with one cat.
+    CPosLandmark* landmark = GetLandmarkLC(aIndex);
+    TPtrC mbmFile;
+    TInt iconFileIndex = -1;
+    TInt iconListIndex = -1;
+    TInt iconMasktIndex = -1;
+    TInt result = landmark->GetIcon( mbmFile, iconFileIndex, iconMasktIndex );
+    if ( result == KErrNone )
+        {
+        TRAPD(err, iconListIndex =
+                    iIconMgr->GetIconL( mbmFile, iconFileIndex ) );
+        if ( err == KErrNotFound ) // icon file not found -> fallback to default
+            {
+            iconListIndex = iIconMgr->GetDefaultIconL(
+                MLmkSelectorIconMgr::ELandmarkDefaultIcon );
+            }
+        }
+    else
+        {
+        iconListIndex = iIconMgr->GetDefaultIconL(
+            MLmkSelectorIconMgr::ELandmarkDefaultIcon );
+        }
+
+    CLmkLandmarkUiItem* uiItem =
+        CLmkLandmarkUiItem::NewL( landmark, iconListIndex );
+    CleanupStack::Pop(); // landmark, ownership transferred
+    return uiItem;
+    }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::PrepareListL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::PrepareListL()
+    {    
+    iCount = 0;
+
+    iDb.SetPartialReadParametersL( *iReadParams );
+
+    TPosLmSortPref sortOrder( CPosLandmark::ELandmarkName,
+                              TPosLmSortPref::EAscending );
+    CPosLmOperation* operation =
+        iSearch->StartLandmarkSearchL( iCriteria, sortOrder );
+    CleanupStack::PushL( operation );
+    if (iSearchAO)
+		{
+    	iSearchAO->StopOperation();
+	    delete iSearchAO; // cancel possibly pending operation
+	    iSearchAO = NULL;
+    	}
+    iSearchAO = CLmkAOOperation::NewL( operation,
+                                       *this,
+                                       MLmkAOOperationObserver::ESearch,
+                                       iOperationNotInUse );
+	iOperationNotInUse = ETrue;
+    CleanupStack::Pop( operation ); // ownership transferred
+    iSearchAO->StartOperation();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkSearchedLmListProvider::PrepareListL
+// -----------------------------------------------------------------------------
+//
+TBool CLmkSearchedLmListProvider::PrepareListL(const TDesC& aSearchPattern,
+    							TBool aSearchOnlyInPreviousMatches)
+	{
+    iCount = 0;
+	iRequestFromFindBox = ETrue;
+	iOperationNotInUse = ETrue;
+    iIsSecondSearchStarted = EFalse;
+
+	if( aSearchPattern.Compare( KDefaultTextCriteria ) == 0
+			|| aSearchPattern.Length() <= 0  )
+		{
+		PrepareListL();
+		iRequestFromFindBox = EFalse;
+		return ETrue;
+		}
+
+	// We need to cancel if we are searching/reading landmarks.
+ 	if (iSearchAO)
+	 	{
+	 	iSearchAO->StopOperation();
+	 	delete iSearchAO; // cancel possibly pending operation
+		iSearchAO = NULL;
+	 	}
+
+	// Create the composite criterion
+	CPosLmCompositeCriteria* compCrit = CPosLmCompositeCriteria::NewLC(
+	    CPosLmCompositeCriteria::ECompositionOR );
+
+	// Create the text search criterion and add it to composite
+	CPosLmTextCriteria* textCrit1 = CPosLmTextCriteria::NewLC();
+
+    const TInt KExtraChars = 3; // 2 chars wildcards
+    HBufC* filterBuf = HBufC::NewLC(aSearchPattern.Length() + KExtraChars);
+    TPtr filter = filterBuf->Des();
+	filter.Copy(KSpaceTextCriteria);
+	filter.Append(aSearchPattern);
+
+	textCrit1->SetTextL( filter );
+    textCrit1->SetAttributesToSearch(CPosLandmark::ELandmarkName);
+
+	User::LeaveIfError( compCrit->AddArgument( textCrit1 ) );
+	// Ownership of the text criterion has been passed to the composite
+	CleanupStack::PopAndDestroy( filterBuf );
+	CleanupStack::Pop( textCrit1 );
+
+	// Create the text search criterion and add it to composite
+	CPosLmTextCriteria* textCrit2 = CPosLmTextCriteria::NewLC();
+	textCrit2->SetTextL( aSearchPattern );
+    textCrit2->SetAttributesToSearch(CPosLandmark::ELandmarkName);
+
+	User::LeaveIfError( compCrit->AddArgument( textCrit2 ) );
+	// Ownership of the text criterion has been passed to the composite
+	CleanupStack::Pop( textCrit2 );
+
+    iDb.SetPartialReadParametersL( *iReadParams );
+
+    TPosLmSortPref sortOrder( CPosLandmark::ELandmarkName,
+                              TPosLmSortPref::EAscending );
+	// Start the search
+    // Create search operation
+    CPosLmOperation* operation = iSearch->StartLandmarkSearchL(
+    					*compCrit, sortOrder, aSearchOnlyInPreviousMatches );
+
+ 	CleanupStack::PopAndDestroy( compCrit );
+ 	CleanupStack::PushL( operation );
+
+	iSearchAO = CLmkAOOperation::NewL( operation,
+                                   *this,
+                                   MLmkAOOperationObserver::ESearch,
+                                   ETrue );
+	CleanupStack::Pop( operation ); // ownership transferred
+
+    iSearchAO->StartOperation();
+
+    return ETrue;
+ 	}
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::StartSecondSearchL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::StartSecondSearchL()
+	{
+	// Create the composite criterion
+	CPosLmCompositeCriteria* compCrit = CPosLmCompositeCriteria::NewLC(
+	    CPosLmCompositeCriteria::ECompositionAND );
+
+	// Create the category search criterion and add it to composite
+	CPosLmCategoryCriteria* catCrit = CPosLmCategoryCriteria::NewLC();
+	catCrit->SetCategoryItemId( (static_cast<CPosLmCategoryCriteria&>(iCriteria)).CategoryItemId() );
+
+	User::LeaveIfError( compCrit->AddArgument( catCrit ) );
+	// Ownership of the category criterion has been passed to the composite
+	CleanupStack::Pop( catCrit );
+
+	// Create the text search criterion and add it to composite
+	CPosLmIdListCriteria* idListCrit = CPosLmIdListCriteria::NewLC();
+	idListCrit->SetLandmarkIdsL( iIdArray );
+
+	User::LeaveIfError( compCrit->AddArgument( idListCrit ) );
+	// Ownership of the text criterion has been passed to the composite
+	CleanupStack::Pop( idListCrit );
+
+    iDb.SetPartialReadParametersL( *iReadParams );
+
+    TPosLmSortPref sortOrder( CPosLandmark::ELandmarkName,
+                              TPosLmSortPref::EAscending );
+	// Start the search
+    // Create search operation
+    CPosLmOperation* operation = iSearch->StartLandmarkSearchL( *compCrit, sortOrder );
+
+ 	CleanupStack::PopAndDestroy( compCrit );
+ 	CleanupStack::PushL( operation );
+
+	iSearchAO = CLmkAOOperation::NewL( operation,
+                                   *this,
+                                   MLmkAOOperationObserver::ESearch,
+                                   ETrue );
+	CleanupStack::Pop( operation ); // ownership transferred
+
+	iIsSecondSearchStarted = EFalse;
+    iSearchAO->StartOperation();
+
+	}
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::HandleOperationL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::HandleOperationL(
+    TOperationTypes aType,
+    TReal32 aProgress,
+    TInt aStatus )
+    {
+    if ( aType == MLmkAOOperationObserver::EDeleteLandmarks )
+    	{
+    	return;
+    	}
+    if ( aType == MLmkAOOperationObserver::ERemoveCategory )
+    	{
+    	return;
+    	}
+    if ( aType == MLmkAOOperationObserver::ESearch )
+        {
+   		ReadItemsToArrayL();
+       	if ( aStatus == KErrNone )
+	        {
+	        if( iSearchAO )
+	        	{
+	        	iSearchAO->StopOperation();
+				delete iSearchAO;
+		        iSearchAO = NULL;
+	        	}
+
+			// reset operation values
+	        iOperationCmd = ELmkCmdStopOperation;//temp default value
+	        iCount = 0;
+
+	        if( iIsSecondSearchStarted )
+	        	{
+	        	StartSecondSearchL();
+	        	}
+
+	        if(iOperationNotInUse == EFalse )
+	        	{
+	        	NotifyObservers( ELmkEventItemAdditionComplete );
+	        	}
+	        else
+		        {
+		        if (iRequestFromFindBox)
+			        {
+			        NotifyObservers( ELmkEventFindListReady );
+			        }
+				else
+					{
+		        	NotifyObservers( ELmkEventListReady );
+					}
+		        }
+
+	        iOperationNotInUse = ETrue;
+
+            if ( iCatDelete )
+                {
+                NotifyObservers( ELmkEventCategoryDeleted );
+                iCatDelete = EFalse;
+                }
+            else if(iCatUpdate)
+	            {
+	            NotifyObservers( ELmkEventCategoryUpdated );
+                iCatUpdate = EFalse;
+                }
+
+    		if(iItemsDeleted < iItemsToDelete)
+    			{
+    			PrepareForDeleteL();
+    			}
+    		else
+    			{
+    			if(iWaitNote)
+    				{
+		            iWaitNote->ProcessFinishedL();
+		            iWaitNote = NULL;
+    				}
+    			}
+	        return;
+	        } // end of if ( aStatus == KErrNone )
+
+	    if ( iCount == ELmkStepOne || iCount == ELmkStepTwo )
+	        {
+			if (iOperationNotInUse == EFalse )
+	        	{
+	        	NotifyObservers( ELmkEventItemAdditionComplete );
+	        	}
+	        else
+		        {
+		        if (iRequestFromFindBox)
+			        {
+			        NotifyObservers( ELmkEventFindListReady );
+			        }
+				else
+					{
+		        	NotifyObservers( ELmkEventListReady );
+					}
+		        }
+		    iOperationNotInUse = EFalse;
+	        }
+        }
+    else
+        { // This is not this classes' operation
+        CLmkLmItemListProvider::HandleOperationL( aType, aProgress, aStatus);
+        }
+    }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::HandleDatabaseEvent
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::HandleDatabaseEvent( TPosLmEvent& aEvent )
+    {
+    iCatDelete = EFalse;
+
+	TBool needRefresh = ETrue;
+
+	// check any items are selected to do operations like iconchanges or add to category.
+	if( iSelectedItemsCount > 0 
+		&& iOperationCmd != ELmkCmdAddToCat
+		&& iOperationCmd != ERemoveFromCat )
+		{
+		iCount++;
+		if( iSelectedItemsCount == iCount )
+			{
+			iSelectedItemsCount = 0;
+			iCount = 0;
+			}
+		needRefresh = EFalse;
+		}
+
+    switch ( aEvent.iEventType )
+        {
+        case EPosLmEventLandmarkUpdated: 		// lm icon changes, lm renaming
+        case EPosLmEventLandmarkUnknownChanges:	// lm multiple deletion, lm add to category
+        case EPosLmEventUnknownChanges:
+        case EPosLmEventLandmarkCreated:
+        case EPosLmEventCategoryDeleted:
+        case EPosLmEventCategoryUpdated:
+            {
+            iOperationNotInUse = EFalse;
+           	if (aEvent.iEventType == EPosLmEventCategoryDeleted )
+	            {
+	            iCatDelete = ETrue;
+	            }
+	        if (aEvent.iEventType == EPosLmEventCategoryUpdated )
+	            {
+	            iCatUpdate = ETrue;
+	            }
+
+			if( needRefresh )
+				{
+		        if( iSearchAO )
+		        	{
+		        	iSearchAO->StopOperation();
+					delete iSearchAO;
+			        iSearchAO = NULL;
+		        	}
+	            iOperationNotInUse = EFalse;
+	            TInt err = KErrNone;
+	            do
+	                {
+	                TRAP( err, PrepareListL() );
+	                }while(err == KErrLocked);
+	            if ( err )
+	                {
+	                HandleError( err );
+	                }
+				}
+			else
+				{
+				NotifyObservers( ELmkEventListReady );
+				}
+            break;
+            }
+        case EPosLmEventLandmarkDeleted:
+        	{
+		   	TInt index = iIdArray.Find( aEvent.iLandmarkItemId );
+		   	if( index != KErrNotFound && index < iIdArray.Count())
+		   		{
+		   		iIdArray.Remove(index);
+			   	NotifyObservers( ELmkEventListReady );
+		   		}
+		   	break;
+        	}
+        default:
+            { // Not interesting event for this provider
+            break;
+            }
+        }
+    // Remember to call base class observer method too
+    CLmkLmItemListProvider::HandleDatabaseEvent( aEvent );
+    }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::ReadItemsToArrayL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::ReadItemsToArrayL()
+    {
+    iIdArray.Reset();
+    CPosLmItemIterator* iterator = iSearch->MatchIteratorL();
+    CleanupStack::PushL( iterator );
+    iCount = iterator->NumOfItemsL();
+    if ( iCount > 0 )
+        { // can only be called if there are some items
+        iterator->GetItemIdsL( iIdArray, 0, iCount ); // array is first reseted
+        }
+    CleanupStack::PopAndDestroy( iterator );
+    }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::RemoveLandmarksL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::RemoveLandmarksL(const RArray<TPosLmItemId>& aSelectedItems )
+	{
+	iItemsToDelete = aSelectedItems.Count();
+	iSelectedForDelete.Reset();
+	for(TInt i=0;i<iItemsToDelete;i++)
+		iSelectedForDelete.Append(aSelectedItems[i]);
+	iItemsDeleted = 0;
+	iIsRemoveLandmarks = ETrue;
+
+	if(iWaitNote)
+		{
+		delete iWaitNote;
+		iWaitNote = NULL;
+		}
+	PrepareForDeleteL();
+	}
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::PrepareForDelete
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::PrepareForDeleteL()
+	{
+	RArray<TPosLmItemId> lmItemsChunk;
+	TInt count = iItemsDeleted;
+	if(iItemsToDelete > (iItemsDeleted + 10))
+		{
+		iItemsDeleted = iItemsDeleted + 10;
+		}
+	else
+		{
+		iItemsDeleted = iItemsDeleted + (iItemsToDelete - iItemsDeleted);
+		}
+
+	for(TInt i=count;i<iItemsDeleted;i++)
+		{
+		lmItemsChunk.Append(iSelectedForDelete[i]);
+		}
+
+	CPosLmOperation* operation = NULL;
+	if(iType == MLmkAOOperationObserver::EDeleteLandmarks)
+		{
+		operation = iDb.RemoveLandmarksL( lmItemsChunk );
+		}
+	if(iType == MLmkAOOperationObserver::ERemoveCategory)
+		{
+		CPosLmCategoryManager* mgr = CPosLmCategoryManager::NewL( iDb );
+		CleanupStack::PushL(mgr);
+		operation = mgr->RemoveCategoryFromLandmarksL( iCategoryId, lmItemsChunk );
+		CleanupStack::PopAndDestroy();//mgr
+		}
+	User::LeaveIfNull( operation );
+
+	CleanupStack::PushL( operation );
+	iSearchAO = CLmkAOOperation::NewL( operation,
+	               *this,
+	               iType,
+	               EFalse );
+	CleanupStack::Pop( operation ); // ownership transferred
+
+    if( iSearchAO )
+        {
+        iSearchAO->StartOperation();
+
+        if(!iWaitNote)
+            {
+            iWaitNote = new (ELeave) CAknWaitDialog(NULL, ETrue);
+            if(!iWaitNote->ExecuteLD(R_LMK_PROCESSING_WAIT_NOTE))
+                {
+                iSearchAO->StopOperation();
+                delete iSearchAO;
+                iSearchAO = NULL;
+                iWaitNote = NULL;
+                }
+            }
+        }
+	
+	lmItemsChunk.Close();
+	}
+
+//  End of File