--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarksui/engine/src/CLmkSearchedLmListProvider.cpp Wed Sep 01 12:31:27 2010 +0100
@@ -0,0 +1,625 @@
+/*
+ * Copyright (c) 2002-2010 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>
+#include "Debug.h"
+
+// CONSTANTS
+_LIT(KSpaceTextCriteria,"* ");
+_LIT(KDefaultTextCriteria,"*");
+
+#if defined(_DEBUG)
+/// 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()
+ {
+ DEBUG( CLmkSearchedLmListProvider::PrepareListL start );
+ 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();
+ DEBUG( CLmkSearchedLmListProvider::PrepareListL End );
+ }
+
+// -----------------------------------------------------------------------------
+// CLmkSearchedLmListProvider::PrepareListL
+// -----------------------------------------------------------------------------
+//
+TBool CLmkSearchedLmListProvider::PrepareListL(const TDesC& aSearchPattern,
+ TBool aSearchOnlyInPreviousMatches)
+ {
+ iCount = 0;
+ iRequestFromFindBox = ETrue;
+ iOperationNotInUse = ETrue;
+ iIsSecondSearchStarted = EFalse;
+ DEBUG1( CLmkSearchedLmListProvider::PrepareListL 2 start with aSearchPattern = %d,aSearchPattern.Length());
+
+ 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();
+ DEBUG( CLmkSearchedLmListProvider::PrepareListL 2 End );
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::StartSecondSearchL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::StartSecondSearchL()
+ {
+ DEBUG( CLmkSearchedLmListProvider::StartSecondSearchL start );
+
+ iIsSecondSearchStarted = ETrue;
+
+ // 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
+
+ iSearchAO->StartOperation();
+ DEBUG( CLmkSearchedLmListProvider::StartSecondSearchL End );
+ }
+
+// ---------------------------------------------------------
+// CLmkSearchedLmListProvider::HandleOperationL
+// ---------------------------------------------------------
+//
+void CLmkSearchedLmListProvider::HandleOperationL(TOperationTypes aType,
+ TReal32 aProgress, TInt aStatus)
+ {
+ DEBUG1( CLmkSearchedLmListProvider::HandleOperationL start aType=%d,aType);
+ 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;
+
+ DEBUG2( CLmkSearchedLmListProvider::HandleOperationL iRequestFromFindBox=%d iIsSecondSearchStarted=%d
+ ,iRequestFromFindBox,iIsSecondSearchStarted);
+
+ if (iRequestFromFindBox && iIsSecondSearchStarted == EFalse)
+ {
+ DEBUG( CLmkSearchedLmListProvider::HandleOperationL start secondsearch );
+ StartSecondSearchL();
+ return;
+ }
+
+ DEBUG( CLmkSearchedLmListProvider::HandleOperationL refresh list );
+
+ iIsSecondSearchStarted = EFalse;
+
+ 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);
+ }
+ }
+ iRequestFromFindBox = EFalse;
+ 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