/*
* 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