diff -r 1fc85118c3ae -r 870918037e16 locationlandmarksrefappfors60/Src/LandmarksCategoriesContainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locationlandmarksrefappfors60/Src/LandmarksCategoriesContainer.cpp Wed Sep 01 12:31:27 2010 +0100 @@ -0,0 +1,410 @@ +/* +* Copyright (c) 2004-2005 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: Implements the CLandmarksCategoriesContainer class +* +*/ + + + +#include +#include +#include +#include + +#include + +#include +#include "LandmarksCategoriesContainer.h" +#include "LandmarksCommonData.h" +#include "LandmarksListbox.h" +#include "LandmarksListBoxModel.h" +#include "LandmarksApplicationEngine.h" +#include "LandmarksCategoriesModel.h" + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// ResetAndDestroyCategories +// Resets and destroys an array of categories. This function is used as a +// TCleanupOperation in CLandmarksCategoriesModel. +// Params: aAny: The categories array to reset ands destroy +// ----------------------------------------------------------------------------- +// +void ResetAndDestroyCategories(TAny* aAny) + { + CArrayPtr* categories = + reinterpret_cast *> (aAny); + categories->ResetAndDestroy(); + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +CLandmarksCategoriesContainer::CLandmarksCategoriesContainer( + CAknView& aView, + CLandmarksApplicationEngine& aEngine, + CEikMenuBar& aMenuBar) +: CLandmarksContainerBase(aView, aEngine), + iMenuBar(aMenuBar) + { + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::ConstructL( + const TRect& aRect) + { + // Create listbox and findbox. + CLandmarksContainerBase::ConstructL(aRect); + + // Start observer db events. + iEngine.AddDbObserverL(this); + + // Create data model. + iModel = CLandmarksCategoriesModel::NewL(); + + // Create a descriptor array that will contain the landmark names and + // icon indeces. + CLandmarksListBoxModel* listBoxModel = iListBox->Model(); + listBoxModel->SetItemTextArray(iModel->ItemList()); + listBoxModel->SetOwnershipType(ELbmDoesNotOwnItemArray); + + // Create an icon array the will be displayed in the listbox. + + CIconList* icons = iModel->CreateIconListL(); + iListBox->ItemDrawer()->ColumnData()->SetIconArray(icons); + + // Observe listbox for state changes. + iListBox->SetObserver(this); + + // Observe findbox for state changes. + iFindBox->SetObserver(this); + + // Populate listbox with categories and icons. + StartUpdateListBoxL(); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +CLandmarksCategoriesContainer::~CLandmarksCategoriesContainer() + { + delete iModel; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::DeleteCategoryL() + { + // Format query. + HBufC* queryFormat = + iCoeEnv->AllocReadResourceAsDes16LC(R_LMREFAPP_DELETE_CATEGORY); + + CPosLandmarkCategory* category = iEngine.CategoryLC(CurrentCategoryId()); + TPtrC name; + category->GetCategoryName(name); + + HBufC* query = HBufC::NewLC(name.Length() + queryFormat->Length()); + query->Des().Format(*queryFormat, &name); + + // Launch dialog. + CAknQueryDialog* queryDialog = CAknQueryDialog::NewL(); + if (queryDialog->ExecuteLD(R_LMREFAPP_GENERAL_QUERY, *query)) + { + // Delete category if positive response. + iEngine.DeleteCategoryL(category->CategoryId()); + } + CleanupStack::PopAndDestroy(3, queryFormat); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +TPosLmItemId CLandmarksCategoriesContainer::CurrentCategoryId() + { + return iModel->CurrentItemId(); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +TBool CLandmarksCategoriesContainer::IsGlobalL() + { + CPosLandmarkCategory* category = iEngine.CategoryLC(CurrentCategoryId()); + TBool isGlobal = (category->GlobalCategory() != KPosLmNullGlobalCategory); + CleanupStack::PopAndDestroy(category); + + return isGlobal; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +TKeyResponse CLandmarksCategoriesContainer::OfferKeyEventL( + const TKeyEvent& aKeyEvent, TEventCode aType) + { + TKeyResponse response = EKeyWasNotConsumed; + + switch (aKeyEvent.iCode) + { + case EKeyUpArrow: + case EKeyDownArrow: + // Scrolling the listbox. Forward to iListBox. + response = iListBox->OfferKeyEventL(aKeyEvent, aType); + break; + + case EKeyDevice3: + // Select key pressed. Display menu. + iMenuBar.SetMenuTitleResourceId(R_LMREFAPP_CATEGORIES_MENUBAR); + iMenuBar.TryDisplayMenuBarL(); + response = EKeyWasConsumed; + break; + + case EKeyBackspace: + if (iFindBox->TextLength() == 0 && + IsItemSelected() && + !IsGlobalL()) + { + // If there is no text in the search field backspace will + // delete a category. + DeleteCategoryL(); + response = EKeyWasConsumed; + break; + } + // erase character in find box + default: + // Forward to findbox. + response = iFindBox->OfferKeyEventL(aKeyEvent, aType); + break; + } + + return response; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::NotifyOperationProgressL( + TOperation aOperation, + TInt /*aProgress*/, + TInt aErrorCode) + { + switch (aOperation) + { + case ECategorySearch: + HandleSearchReadyL(aErrorCode); + break; + + case ECategoryRead: + HandleReadReadyL(aErrorCode); + break; + + default: + break; + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::NotifyDbEventL( + TPosLmEvent& aEvent, + TInt aErrorCode) + { + if (aErrorCode == KErrNone) + { + switch (aEvent.iEventType) + { + case EPosLmEventUnknownChanges: + case EPosLmEventLandmarkUnknownChanges: + case EPosLmEventCategoryUnknownChanges: + // Any of the events below might have cancelled an ongoing + // categories search/read operation => we must restart refreshing listbox + case EPosLmEventLandmarkCreated: + case EPosLmEventLandmarkDeleted: + case EPosLmEventLandmarkUpdated: + case EPosLmEventCategoryCreated: + case EPosLmEventCategoryDeleted: + case EPosLmEventCategoryUpdated: + StartUpdateListBoxL(); + break; + case EPosLmEventNewDefaultDatabaseLocation: + // Not supported by this application + break; + case EPosLmEventMediaRemoved: + // Not supported by this application + break; + default: + // Ignore other non-category events + break; + } + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::HandleControlEventL( + CCoeControl* aControl, + TCoeEvent aEventType) + { + if (aEventType == EEventStateChanged && aControl == iListBox) + { + // Take the index of the current item in the list + TInt itemIndex = iListBox->CurrentItemIndex(); + + // Set the current item in the model object regarding to the list box. + iModel->SetCurrentItem(itemIndex); + } + + if (aEventType == EEventStateChanged && aControl == iFindBox) + { + // Fetch filter from search field + TInt searchTextLength = iFindBox->TextLength(); + HBufC* filterBuf = HBufC::NewLC(searchTextLength); + TPtr filter = filterBuf->Des(); + iFindBox->GetSearchText(filter); + + // If filter has changed repopulate list box. (It is necessary to check + // if filter has changed since each filter change generates several + // EEventStateChanged events for find box) + if (filter != *iOldFilter) + { + // Filter has changed. Start filtering. + StartUpdateListBoxL(); + } + + CleanupStack::PopAndDestroy(filterBuf); + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::StartUpdateListBoxL() + { + // Fetch filter from search field + TInt searchTextLength = iFindBox->TextLength(); + const TInt KExtraChars = 2; // 2 chars wildcards + HBufC* filterBuf = HBufC::NewLC(searchTextLength + KExtraChars); + TPtr filter = filterBuf->Des(); + iFindBox->GetSearchText(filter); + + // Find out if there is any prevoius result to limit the search to + TInt oldFilterLength = iOldFilter->Length(); + TBool searchOnlyInPreviousMatches = + // If previous filter is empty there is no search results + oldFilterLength > 0 && + + // If chars have been removed from filter we abandon previous results + filter.Length() > oldFilterLength && + + // There must exist at least one previous match + IsItemSelected(); + + // old filter used - now we can update it + delete iOldFilter; + iOldFilter = NULL; + iOldFilter = filter.AllocL(); + + // Start to asynchronously populate the listbox model according to filter + if (filter.Length() == 0) + { + iEngine.StartSearchingCategoriesL(this); + } + else + { + filter.Append(KWildCard); + iEngine.StartSearchingCategoriesL( + filter, + searchOnlyInPreviousMatches, + this); + } + + CleanupStack::PopAndDestroy(filterBuf); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::HandleSearchReadyL(TInt aErrorCode) + { + + // Delete old icon array and add new + CColumnListBoxData* columnData = iListBox->ItemDrawer()->ColumnData(); + CArrayPtr* iconList = columnData->IconArray(); + iconList->ResetAndDestroy(); + delete iconList; + columnData->SetIconArray(iModel->CreateIconListL()); + + if (aErrorCode == KErrNone) + { + // Update model + iModel->SetItemIds(iEngine.FetchCategorySearchResult()); + iListBox->HandleItemRemovalL(); + + iEngine.StartReadingCategoriesL(KNrOfItemsDisplayed, this); + iReadingFirstPage = ETrue; + } + else if (aErrorCode == KErrNotFound) + { + // Update model (indicate no item is selected) + iModel->SetItemIds(NULL); + iModel->SetCurrentItem(iListBox->CurrentItemIndex()); + + // Update the listbox + iListBox->HandleItemRemovalL(); + iListBox->DrawDeferred(); + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CLandmarksCategoriesContainer::HandleReadReadyL( + TInt aErrorCode) + { + // Update model with new categories + CArrayPtr* categories = iEngine.FetchCategoriesLC(); + CleanupStack::PushL(TCleanupItem(ResetAndDestroyCategories, categories)); + iModel->RepopulateModelL(categories); + CleanupStack::PopAndDestroy(2, categories); + + if (aErrorCode == KErrNone) + { + if (iReadingFirstPage) + { + // First page ready + iReadingFirstPage = EFalse; + + // Add the first page + iListBox->HandleItemAdditionL(); + + // Set the first item selected by default. We must do this since + // HandleItemRemovalL in HandleSearchReadyL resets the listbox. + iModel->SetCurrentItem(0); + iListBox->SetCurrentItemIndex(0); + } + else + { + iListBox->HandleItemAdditionL(); + } + } + } + +