landmarksui/engine/src/CLmkCategoryListProvider.cpp
branchRCL_3
changeset 18 870918037e16
parent 0 522cd55cc3d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarksui/engine/src/CLmkCategoryListProvider.cpp	Wed Sep 01 12:31:27 2010 +0100
@@ -0,0 +1,490 @@
+/*
+* 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:    Category List info provider for listbox model
+*
+*/
+
+
+
+
+// INCLUDE FILES
+
+#include <eikenv.h>
+#include <StringLoader.h>
+#include <EPos_CPosLandmarkDatabase.h>
+#include <EPos_CPosLandmarkCategory.h>
+#include <EPos_CPosLmCategoryManager.h>
+#include <EPos_CPosLmItemIterator.h>
+#include <EPos_TPosLmSortPref.h>
+#include <EPos_CPosLmSearchCriteria.h>
+#include <EPos_CPosLandmarkSearch.h>
+#include <EPos_CPosLmCategoryCriteria.h>
+#include <lmkui.rsg>
+#include "LmkConsts.h"
+#include "CLmkAOOperation.h"
+#include "CLmkCategoryUiItem.h"
+#include "MLmkSelectorIconMgr.h"
+#include "CLmkCategoryListProvider.h"
+#include <lmkerrors.h>
+
+#if defined(_DEBUG)
+// CONSTANTS
+/// Unnamed namespace for local definitions
+namespace {
+
+_LIT( KPanicMsg, "CLmkCategoryListProvider" );
+
+void Panic( TPanicCode aReason )
+    {
+    User::Panic( KPanicMsg, aReason );
+    }
+}  // namespace
+#endif
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::CLmkCategoryListProvider
+// C++ constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLmkCategoryListProvider::CLmkCategoryListProvider(
+    CPosLandmarkDatabase& aDb,
+    TLmkProviderType aShowType )
+    : CLmkLmItemListProvider( aDb ),
+      iShowType( aShowType ),
+      iAreUncategorisedItems( EFalse )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CLmkCategoryListProvider::ConstructL()
+	{
+	// base class 2nd phase constructor
+	CLmkLmItemListProvider::BaseConstructL();
+	iCategoryMgr = CPosLmCategoryManager::NewL( iDb );
+	iSearch = CPosLandmarkSearch::NewL( iDb );
+	}
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CLmkCategoryListProvider* CLmkCategoryListProvider::NewL(
+    CPosLandmarkDatabase& aDb,
+    TLmkProviderType aShowType )
+    {
+    CLmkCategoryListProvider* self =
+        new ( ELeave ) CLmkCategoryListProvider( aDb, aShowType );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::~CLmkCategoryListProvider
+// -----------------------------------------------------------------------------
+//
+CLmkCategoryListProvider::~CLmkCategoryListProvider()
+    {
+    delete iCategoryMgr;
+    delete iSearch;
+    if( iSearchAO )
+    	{
+    	delete iSearchAO;
+    	}
+    delete iCriteria;
+    iUsageArray.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::ItemAtL
+// -----------------------------------------------------------------------------
+//
+CLmkUiItemBase* CLmkCategoryListProvider::ItemAtL( TInt aIndex )
+    {
+    __ASSERT_DEBUG( iIconMgr, Panic( KLmkPanicNullMember ) );
+    CLmkCategoryUiItem* uiItem = NULL;
+
+	if (iIdArray[aIndex] != KPosLmNullItemId)
+		{
+		CPosLandmarkCategory* category =
+		iCategoryMgr->ReadCategoryLC( iIdArray[aIndex] );
+
+		TPtrC mbmFile;
+		TInt iconFileIndex = -1;
+		TInt iconListIndex = -1;
+
+		TInt iconMaskIndex = -1;
+		TInt result = category->GetIcon( mbmFile, iconFileIndex ,iconMaskIndex);
+		if ( result == KErrNone )
+			{
+			TRAPD(err, iconListIndex =
+			    iIconMgr->GetIconL( mbmFile, iconFileIndex ) );
+			if ( err == KErrNotFound ) // icon file not found -> fallback to default
+				{
+				iconListIndex = iIconMgr->GetDefaultIconL(
+				MLmkSelectorIconMgr::ECategoryDefaultIcon );
+				}
+			}
+		else
+			{
+			iconListIndex = iIconMgr->GetDefaultIconL(
+			MLmkSelectorIconMgr::ECategoryDefaultIcon );
+			}
+
+		switch( iShowType )
+			{
+			//these are same
+			case ELmkNotShowEmptyCategories:
+			case ELmkShowEmptyCategories:
+				{
+				uiItem =
+				CLmkCategoryUiItem::NewL( category, iconListIndex );
+				break;
+				}
+			case ELmkShowExtendedCategories:
+				{
+				uiItem =
+				CLmkCategoryUiItem::NewL( category, iconListIndex );
+				uiItem->SetExtensionInt( IsUsedL( *category) );
+				break;
+				}
+			default:
+				{
+				break;
+				}
+			}
+		}
+	else // if category id is 'uncategorised'
+		{
+		CPosLandmarkCategory* category = CPosLandmarkCategory::NewL();
+		CleanupStack::PushL( category);
+
+		// Set category name
+		CEikonEnv* env = CEikonEnv::Static();
+		HBufC* catNameText = NULL;
+		catNameText = StringLoader::LoadLC( R_LMK_LM_LIST_UNCATEGORISED, env );
+		TPtrC categoryName;
+		categoryName.Set(*catNameText);
+		category->SetCategoryNameL(categoryName);
+		CleanupStack::PopAndDestroy( catNameText );
+		TInt iconListIndex = -1;
+		iconListIndex
+		    = iIconMgr->GetDefaultIconL(
+			 			            MLmkSelectorIconMgr::ECategoryDefaultIcon );
+		uiItem = CLmkCategoryUiItem::NewL( category, iconListIndex );
+		}
+    CleanupStack::Pop(); // category, ownership transferred
+    return uiItem;
+    }
+
+// ---------------------------------------------------------
+// CLmkCategoryListProvider::ReadItemsToArrayL
+// ---------------------------------------------------------
+//
+void CLmkCategoryListProvider::ReadItemsToArrayL()
+	{
+	// Update the IdArray to have 'uncategorised' category Id
+	CPosLmItemIterator* lmIterator = iSearch->MatchIteratorL();
+	CleanupStack::PushL( lmIterator );
+	TInt lmCount = lmIterator->NumOfItemsL();
+	CleanupStack::PopAndDestroy( lmIterator );
+	if ( lmCount > 0 )
+		{
+		// There is atleast 'one' landmark which is 'uncategorised'
+		// can only be called if there are some items
+		// Append 'uncategorised' category ID to the idArray
+		iIdArray.Append(KPosLmNullItemId);
+		iAreUncategorisedItems = ETrue;
+		if(iCount == -1 )
+			{
+			NotifyObservers( ELmkEventItemAdditionComplete );
+			}
+		else
+       		{
+       		NotifyObservers( ELmkEventListReady );
+       		}
+	    iSearchAO->StopOperation();
+	    iCount = 1;
+		}
+	}
+
+// ---------------------------------------------------------
+//  CLmkCategoryListProvider::HandleOperationL
+// ---------------------------------------------------------
+//
+void CLmkCategoryListProvider::HandleOperationL(
+    TOperationTypes aType,
+    TReal32 aProgress,
+    TInt aStatus )
+    {
+    if ( aType == MLmkAOOperationObserver::ESearch )
+        {
+        if( iCount < 1 )
+        	{
+        	ReadItemsToArrayL();
+        	}
+       	if ( aStatus == KErrNone )
+            {
+            if(iCount == 0)
+            	{
+            	NotifyObservers( ELmkEventListReady );
+            	}
+	        delete iSearchAO;
+	        iSearchAO = NULL;
+	        iCount = 0;
+            }
+        }
+    else
+        { // This is not this classes' operation
+        CLmkLmItemListProvider::HandleOperationL( aType, aProgress, aStatus);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::PrepareListL
+// -----------------------------------------------------------------------------
+//
+void CLmkCategoryListProvider::PrepareListL()
+    {
+    if ( iListAllItemsInDb )
+        {
+        CPosLmItemIterator* iterator = NULL;
+
+        switch( iShowType )
+            {
+			case ELmkNotShowEmptyCategories:
+				{
+				iCount = 0;
+				iIdArray.Reset();
+
+				// Query for 'referenced categories' from Category manager here
+				CPosLmItemIterator* categoryIterator  = iCategoryMgr->ReferencedCategoryIteratorL(
+				    CPosLmCategoryManager::ECategorySortOrderNameAscending );
+				CleanupStack::PushL( categoryIterator );
+				TUint categoryCount = categoryIterator->NumOfItemsL();
+
+				if ( categoryCount > 0 )
+					{ // can only be called if there are some items
+					categoryIterator->GetItemIdsL( iIdArray, 0, categoryCount );
+					if( iAreUncategorisedItems )
+						{
+						iIdArray.Append(KPosLmNullItemId);
+						}
+					NotifyObservers( ELmkEventListReady );
+					iCount = -1;
+					}
+				CleanupStack::PopAndDestroy( categoryIterator );
+
+				if( iAreUncategorisedItems )
+					{
+					if( iIdArray.Count() == 0)
+						{
+						iIdArray.Append(KPosLmNullItemId);
+						}
+					NotifyObservers( ELmkEventListReady );
+					return;
+					}
+
+				// Set criteria parameters here -- for uncategorised landmarks
+				if (iCriteria)
+					{
+					delete   iCriteria;
+					iCriteria = NULL;
+					}
+				iCriteria = CPosLmCategoryCriteria::NewLC();
+				CleanupStack::Pop(  iCriteria );
+				iCriteria->SetCategoryItemId(KPosLmNullItemId);
+
+				TPosLmSortPref sortOrder( CPosLandmark::ELandmarkName,
+				          TPosLmSortPref::EAscending );
+
+
+				CPosLmOperation* operation =
+				iSearch->StartLandmarkSearchL( *iCriteria , sortOrder );
+				CleanupStack::PushL( operation );
+				delete iSearchAO; // cancel possibly pending operation
+				iSearchAO = NULL;
+				iSearchAO = CLmkAOOperation::NewL( operation,
+				                   				   *this,
+				                  				   MLmkAOOperationObserver::ESearch,
+				                   				   iOperationNotInUse );
+
+				CleanupStack::Pop( operation ); // ownership transferred
+				iSearchAO->StartOperation();
+				return;
+				}
+            case ELmkShowEmptyCategories:
+                {
+                iterator = iCategoryMgr->CategoryIteratorL(
+                    CPosLmCategoryManager::ECategorySortOrderNameAscending );
+                CleanupStack::PushL( iterator );
+                break;
+                }
+            case ELmkShowExtendedCategories:
+                {
+                iterator = iCategoryMgr->CategoryIteratorL(
+                    CPosLmCategoryManager::ECategorySortOrderNameAscending );
+                CleanupStack::PushL( iterator );
+                PrepareCategoryUsageListL();
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            }
+        
+        if( iterator )
+            {
+            TUint count = iterator->NumOfItemsL();
+            iIdArray.Reset();
+            if ( count > 0 )
+                { // can only be called if there are some items
+                iterator->GetItemIdsL( iIdArray, 0, count );
+                }
+            CleanupStack::PopAndDestroy( iterator );
+            }
+        }
+
+    NotifyObservers( ELmkEventListReady );
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::PrepareListL
+// -----------------------------------------------------------------------------
+//
+TBool CLmkCategoryListProvider::PrepareListL(const TDesC& /*aSearchPattern*/,
+    							TBool /*aSearchOnlyInPreviousMatches*/)
+	{
+	// not preparing the new list based on search criteria,
+	// as using the avkon's search api
+	return EFalse;
+	}
+
+// ---------------------------------------------------------
+// CLmkCategoryListProvider::RemoveLandmarksL
+// ---------------------------------------------------------
+//
+void CLmkCategoryListProvider::RemoveLandmarksL(const RArray<TPosLmItemId>& /*aSelectedItems*/ )
+	{
+	// no implementation required
+	}
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::HandleDatabaseEvent
+// -----------------------------------------------------------------------------
+//
+void CLmkCategoryListProvider::HandleDatabaseEvent( TPosLmEvent& aEvent )
+    {
+    TBool needRefresh = EFalse;
+    	
+    switch ( aEvent.iEventType )
+        {
+	 	case EPosLmEventLandmarkUnknownChanges:
+        case EPosLmEventLandmarkDeleted:
+        case EPosLmEventLandmarkUpdated:
+        case EPosLmEventUnknownChanges:
+			{
+			iAreUncategorisedItems = EFalse;
+			needRefresh = ETrue;
+			break;
+			}
+        case EPosLmEventLandmarkCreated:
+        case EPosLmEventCategoryUnknownChanges:
+        case EPosLmEventCategoryCreated:
+        case EPosLmEventCategoryDeleted:
+        case EPosLmEventCategoryUpdated:
+            {
+            needRefresh = ETrue;
+            break;
+            }
+        default:
+            {
+            // Not interesting event for this provider
+            break;
+            }
+        }
+        
+    if( needRefresh )    
+    	{
+		TRAPD( err, PrepareListL() );
+		if ( err )
+			{
+			HandleError( err );
+			}  				
+    	}
+    	
+    // Remember to call base class observer method too
+    CLmkLmItemListProvider::HandleDatabaseEvent( aEvent );
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::PrepareCategoryUsageListL
+// -----------------------------------------------------------------------------
+//
+void CLmkCategoryListProvider::PrepareCategoryUsageListL()
+    {
+    iUsageArray.Reset();
+    iUsageIndex = 0;
+    CPosLmItemIterator* iterator = iCategoryMgr->ReferencedCategoryIteratorL(
+                      CPosLmCategoryManager::ECategorySortOrderNameAscending );
+
+    CleanupStack::PushL( iterator );
+    TUint count = iterator->NumOfItemsL();
+    if ( count > 0 )
+        { // can only be called if there are some items
+        iterator->GetItemIdsL( iUsageArray, 0, count );
+        }
+    CleanupStack::PopAndDestroy( iterator );
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkCategoryListProvider::IsUsedL
+// -----------------------------------------------------------------------------
+//
+TBool CLmkCategoryListProvider::IsUsedL( CPosLandmarkCategory& aCategory )
+    {
+    TBool result( EFalse );
+
+    TInt count( iUsageArray.Count() );
+    CPosLandmarkCategory* usageCat = NULL;
+
+    for ( TInt i=0; i<count; i++ )
+        {
+        usageCat = iCategoryMgr->ReadCategoryLC( iUsageArray[i] );
+
+        if ( aCategory.CategoryId() ==  usageCat->CategoryId() )
+            {
+            result = ETrue;
+            CleanupStack::PopAndDestroy();
+            break;
+            }
+        CleanupStack::PopAndDestroy();
+        }
+    return result;
+    }
+
+
+
+//  End of File