S60 3rd Edition SDK for Symbian OS
Example Applications Guide

LandmarksCategoriesContainer.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : LandmarksCategoriesContainer.cpp
00004 *  Part of     : Landmark Reference Application
00005 *  Interface   : -
00006 *  Description : Implements the CLandmarksCategoriesContainer class
00007 *  Version     : 1.0
00008 *
00009 *  Copyright (c) 2004-2006 Nokia Corporation.
00010 *  This material, including documentation and any related 
00011 *  computer programs, is protected by copyright controlled by 
00012 *  Nokia Corporation.
00013 * ==============================================================================
00014 */
00015 
00016 // INCLUDE FILES
00017 #include <aknsfld.h>
00018 #include <aknquerydialog.h>
00019 #include <eikclbd.h>
00020 #include <eikmenub.h>
00021 
00022 #include <EPos_CPosLandmarkCategory.h>
00023 
00024 #include <LmRefApp.rsg>
00025 #include "LandmarksCategoriesContainer.h"
00026 #include "LandmarksCommonData.h"
00027 #include "LandmarksListBox.h"
00028 #include "LandmarksListBoxModel.h"
00029 #include "LandmarksApplicationEngine.h"
00030 #include "LandmarksCategoriesModel.h"
00031 
00032 // ============================= LOCAL FUNCTIONS ===============================
00033 
00034 // -----------------------------------------------------------------------------
00035 // ResetAndDestroyCategories
00036 // Resets and destroys an array of categories. This function is used as a 
00037 // TCleanupOperation in CLandmarksCategoriesModel.
00038 // Params: aAny: The categories array to reset ands destroy
00039 // -----------------------------------------------------------------------------
00040 //
00041 void ResetAndDestroyCategories(TAny* aAny)
00042     {
00043     CArrayPtr<CPosLandmarkCategory>* categories = 
00044         reinterpret_cast <CArrayPtr<CPosLandmarkCategory>*> (aAny);
00045     categories->ResetAndDestroy();
00046     }
00047 
00048 // ============================ MEMBER FUNCTIONS ===============================
00049 
00050 // -----------------------------------------------------------------------------
00051 // CLandmarksCategoriesContainer::CLandmarksCategoriesContainer
00052 // C++ constructor can NOT contain any code, that
00053 // might leave.
00054 // -----------------------------------------------------------------------------
00055 //
00056 CLandmarksCategoriesContainer::CLandmarksCategoriesContainer(
00057     CAknView& aView,
00058     CLandmarksApplicationEngine& aEngine, 
00059     CEikMenuBar& aMenuBar)
00060 :   CLandmarksContainerBase(aView, aEngine), 
00061     iMenuBar(aMenuBar)
00062     {
00063     }
00064 
00065 // -----------------------------------------------------------------------------
00066 // CLandmarksCategoriesContainer::ConstructL
00067 // Symbian 2nd phase constructor can leave.
00068 // -----------------------------------------------------------------------------
00069 //
00070 void CLandmarksCategoriesContainer::ConstructL(
00071     const TRect& aRect)
00072     {
00073     // Create listbox and findbox.
00074     CLandmarksContainerBase::ConstructL(aRect);
00075 
00076     // Start observer db events.
00077     iEngine.AddDbObserverL(this);
00078 
00079     // Create data model.
00080     iModel = CLandmarksCategoriesModel::NewL();
00081 
00082     // Create a descriptor array that will contain the landmark names and 
00083     // icon indeces.
00084     CLandmarksListBoxModel* listBoxModel = iListBox->Model();
00085     listBoxModel->SetItemTextArray(iModel->ItemList());
00086     listBoxModel->SetOwnershipType(ELbmDoesNotOwnItemArray);
00087 
00088     // Create an icon array the will be displayed in the listbox.
00089 
00090     CIconList* icons = iModel->CreateIconListL();
00091     iListBox->ItemDrawer()->ColumnData()->SetIconArray(icons);
00092 
00093     // Observe listbox for state changes.
00094     iListBox->SetObserver(this);
00095 
00096     // Observe findbox for state changes.
00097     iFindBox->SetObserver(this);
00098 
00099     // Populate listbox with categories and icons.
00100     StartUpdateListBoxL();
00101     }
00102 
00103 // Destructor
00104 CLandmarksCategoriesContainer::~CLandmarksCategoriesContainer()
00105     {
00106     delete iModel;
00107     }
00108 
00109 // -----------------------------------------------------------------------------
00110 // CLandmarksCategoriesContainer::DeleteCategoryL
00111 // 
00112 // (other items were commented in a header).
00113 // -----------------------------------------------------------------------------
00114 //
00115 void CLandmarksCategoriesContainer::DeleteCategoryL()
00116     {
00117     // Format query.
00118     HBufC* queryFormat = 
00119         iCoeEnv->AllocReadResourceAsDes16LC(R_LMREFAPP_DELETE_CATEGORY);
00120 
00121     CPosLandmarkCategory* category = iEngine.CategoryLC(CurrentCategoryId());
00122     TPtrC name;
00123     category->GetCategoryName(name);
00124     
00125     HBufC* query = HBufC::NewLC(name.Length() + queryFormat->Length());
00126     query->Des().Format(*queryFormat, &name);
00127 
00128     // Launch dialog.
00129     CAknQueryDialog* queryDialog = CAknQueryDialog::NewL();
00130     if (queryDialog->ExecuteLD(R_LMREFAPP_GENERAL_QUERY, *query))
00131         {
00132         // Delete category if positive response.
00133         iEngine.DeleteCategoryL(category->CategoryId());
00134         }
00135     CleanupStack::PopAndDestroy(3, queryFormat);
00136     }
00137 
00138 // -----------------------------------------------------------------------------
00139 // CLandmarksCategoriesContainer::CurrentCategoryId
00140 // 
00141 // (other items were commented in a header).
00142 // -----------------------------------------------------------------------------
00143 //
00144 TPosLmItemId CLandmarksCategoriesContainer::CurrentCategoryId()
00145     {
00146     return iModel->CurrentItemId();
00147     }
00148 
00149 // -----------------------------------------------------------------------------
00150 // CLandmarksCategoriesContainer::IsGlobalL
00151 // 
00152 // (other items were commented in a header).
00153 // -----------------------------------------------------------------------------
00154 //
00155 TBool CLandmarksCategoriesContainer::IsGlobalL()
00156     {
00157     CPosLandmarkCategory* category = iEngine.CategoryLC(CurrentCategoryId());
00158     TBool isGlobal = (category->GlobalCategory() != KPosLmNullGlobalCategory);
00159     CleanupStack::PopAndDestroy(category);
00160 
00161     return isGlobal;
00162     }
00163 
00164 // -----------------------------------------------------------------------------
00165 // CLandmarksCategoriesContainer::OfferKeyEventL
00166 // 
00167 // (other items were commented in a header).
00168 // -----------------------------------------------------------------------------
00169 //
00170 TKeyResponse CLandmarksCategoriesContainer::OfferKeyEventL(
00171     const TKeyEvent& aKeyEvent, TEventCode aType)
00172     {
00173         TKeyResponse response = EKeyWasNotConsumed;
00174 
00175     switch (aKeyEvent.iCode)
00176         {
00177         case EKeyUpArrow:
00178         case EKeyDownArrow:
00179             // Scrolling the listbox. Forward to iListBox.
00180             response = iListBox->OfferKeyEventL(aKeyEvent, aType);
00181             break;
00182 
00183         case EKeyDevice3:
00184             // Select key pressed. Display menu.
00185             iMenuBar.SetMenuTitleResourceId(R_LMREFAPP_CATEGORIES_MENUBAR);
00186             iMenuBar.TryDisplayMenuBarL();
00187             response = EKeyWasConsumed;
00188             break;
00189 
00190         case EKeyBackspace:
00191             if (iFindBox->TextLength() == 0 &&
00192                 IsItemSelected() &&
00193                 !IsGlobalL())
00194                 {
00195                 // If there is no text in the search field backspace will 
00196                 // delete a category.
00197                 DeleteCategoryL();
00198                 response = EKeyWasConsumed;
00199                 break;
00200                 }
00201             // erase character in find box
00202         default:
00203             // Forward to findbox.
00204             response =  iFindBox->OfferKeyEventL(aKeyEvent, aType);
00205             break;
00206         }
00207 
00208     return response;
00209     }
00210 
00211 // -----------------------------------------------------------------------------
00212 // CLandmarksCategoriesContainer::NotifyOperationProgressL
00213 // 
00214 // (other items were commented in a header).
00215 // -----------------------------------------------------------------------------
00216 //
00217 void CLandmarksCategoriesContainer::NotifyOperationProgressL(
00218     TOperation aOperation, 
00219     TInt /*aProgress*/, 
00220     TInt aErrorCode)
00221     {
00222     switch (aOperation)
00223         {
00224         case ECategorySearch:
00225             HandleSearchReadyL(aErrorCode);
00226             break;
00227 
00228         case ECategoryRead:
00229             HandleReadReadyL(aErrorCode);
00230             break;
00231 
00232         default:
00233             break;
00234         }
00235     }
00236 
00237 // -----------------------------------------------------------------------------
00238 // CLandmarksCategoriesContainer::NotifyDbEventL
00239 // 
00240 // (other items were commented in a header).
00241 // -----------------------------------------------------------------------------
00242 //
00243 void CLandmarksCategoriesContainer::NotifyDbEventL(
00244     TPosLmEvent& aEvent, 
00245     TInt aErrorCode)
00246     {
00247     if (aErrorCode == KErrNone)
00248         {
00249         switch (aEvent.iEventType)
00250             {
00251             case EPosLmEventUnknownChanges:
00252             case EPosLmEventLandmarkUnknownChanges:
00253             case EPosLmEventCategoryUnknownChanges:
00254             // Any of the events below might have cancelled an ongoing 
00255             // categories search/read operation => we must restart refreshing listbox
00256             case EPosLmEventLandmarkCreated:
00257             case EPosLmEventLandmarkDeleted:
00258             case EPosLmEventLandmarkUpdated:
00259             case EPosLmEventCategoryCreated:
00260             case EPosLmEventCategoryDeleted:
00261             case EPosLmEventCategoryUpdated:
00262                 StartUpdateListBoxL();
00263                 break;
00264             case EPosLmEventNewDefaultDatabaseLocation:
00265                 // Not supported by this application
00266                 break;
00267             case EPosLmEventMediaRemoved:
00268                 // Not supported by this application
00269                 break;
00270             default:
00271                 // Ignore other non-category events
00272                 break;
00273             }
00274         }
00275     }
00276 
00277 // -----------------------------------------------------------------------------
00278 // CLandmarksCategoriesContainer::HandleControlEventL
00279 // 
00280 // (other items were commented in a header).
00281 // -----------------------------------------------------------------------------
00282 //
00283 void CLandmarksCategoriesContainer::HandleControlEventL(
00284     CCoeControl* aControl, 
00285     TCoeEvent aEventType)
00286     {
00287         if (aEventType == EEventStateChanged && aControl == iListBox)
00288                 {
00289                 // Take the index of the current item in the list
00290                 TInt itemIndex = iListBox->CurrentItemIndex();
00291 
00292                 // Set the current item in the model object regarding to the list box.
00293                 iModel->SetCurrentItem(itemIndex);
00294                 }
00295 
00296         if (aEventType == EEventStateChanged && aControl == iFindBox)
00297                 {
00298         // Fetch filter from search field
00299         TInt searchTextLength = iFindBox->TextLength();
00300         HBufC* filterBuf = HBufC::NewLC(searchTextLength);
00301         TPtr filter = filterBuf->Des();
00302         iFindBox->GetSearchText(filter);
00303 
00304         // If filter has changed repopulate list box. (It is necessary to check
00305         // if filter has changed since each filter change generates several 
00306         // EEventStateChanged events for find box)
00307         if (filter != *iOldFilter)
00308             {
00309             // Filter has changed. Start filtering.
00310             StartUpdateListBoxL();
00311             }
00312 
00313         CleanupStack::PopAndDestroy(filterBuf);
00314                 }
00315     }
00316 
00317 // -----------------------------------------------------------------------------
00318 // CLandmarksCategoriesContainer::StartUpdateListBoxL
00319 // 
00320 // (other items were commented in a header).
00321 // -----------------------------------------------------------------------------
00322 //
00323 void CLandmarksCategoriesContainer::StartUpdateListBoxL()
00324     {
00325     // Fetch filter from search field
00326     TInt searchTextLength = iFindBox->TextLength();
00327     const TInt KExtraChars = 2; // 2 chars wildcards
00328     HBufC* filterBuf = HBufC::NewLC(searchTextLength + KExtraChars);
00329     TPtr filter = filterBuf->Des();
00330     iFindBox->GetSearchText(filter);
00331 
00332     // Find out if there is any prevoius result to limit the search to
00333     TInt oldFilterLength = iOldFilter->Length();
00334     TBool searchOnlyInPreviousMatches = 
00335         // If previous filter is empty there is no search results
00336         oldFilterLength > 0 && 
00337 
00338         // If chars have been removed from filter we abandon previous results
00339         filter.Length() > oldFilterLength && 
00340 
00341         // There must exist at least one previous match
00342         IsItemSelected();
00343 
00344     // old filter used - now we can update it
00345     delete iOldFilter;
00346     iOldFilter = NULL;
00347     iOldFilter = filter.AllocL();
00348 
00349         // Start to asynchronously populate the listbox model according to filter
00350     if (filter.Length() == 0)
00351         {
00352         iEngine.StartSearchingCategoriesL(this);
00353         }
00354     else
00355         {
00356         filter.Append(KWildCard);
00357         iEngine.StartSearchingCategoriesL(
00358             filter, 
00359             searchOnlyInPreviousMatches, 
00360             this);
00361         }
00362 
00363     CleanupStack::PopAndDestroy(filterBuf);
00364     }
00365 
00366 // -----------------------------------------------------------------------------
00367 // CLandmarksCategoriesContainer::HandleSearchReadyL
00368 // 
00369 // (other items were commented in a header).
00370 // -----------------------------------------------------------------------------
00371 //
00372 void CLandmarksCategoriesContainer::HandleSearchReadyL(TInt aErrorCode)
00373     {
00374 
00375     // Delete old icon array and add new
00376         CColumnListBoxData* columnData = iListBox->ItemDrawer()->ColumnData();
00377     CArrayPtr<CGulIcon>* iconList = columnData->IconArray();
00378     iconList->ResetAndDestroy();
00379     delete iconList;
00380     columnData->SetIconArray(iModel->CreateIconListL());
00381 
00382     if (aErrorCode == KErrNone)
00383         {
00384         // Update model
00385         iModel->SetItemIds(iEngine.FetchCategorySearchResult());
00386         iListBox->HandleItemRemovalL();
00387 
00388         iEngine.StartReadingCategoriesL(KNrOfItemsDisplayed, this);
00389         iReadingFirstPage = ETrue;
00390         }
00391     else if (aErrorCode == KErrNotFound)
00392         {
00393         // Update model (indicate no item is selected)
00394         iModel->SetItemIds(NULL);
00395         iModel->SetCurrentItem(iListBox->CurrentItemIndex());
00396 
00397         // Update the listbox
00398         iListBox->HandleItemRemovalL();
00399         iListBox->DrawDeferred();
00400         }
00401     }
00402 
00403 // -----------------------------------------------------------------------------
00404 // CLandmarksCategoriesContainer::HandleReadReadyL
00405 // 
00406 // (other items were commented in a header).
00407 // -----------------------------------------------------------------------------
00408 //
00409 void CLandmarksCategoriesContainer::HandleReadReadyL(
00410     TInt aErrorCode)
00411     {
00412     // Update model with new categories
00413     CArrayPtr<CPosLandmarkCategory>* categories = iEngine.FetchCategoriesLC();
00414     CleanupStack::PushL(TCleanupItem(ResetAndDestroyCategories, categories));
00415     iModel->RepopulateModelL(categories);
00416     CleanupStack::PopAndDestroy(2, categories);
00417 
00418     if (aErrorCode == KErrNone)
00419         {
00420         if (iReadingFirstPage)
00421             {
00422             // First page ready
00423             iReadingFirstPage = EFalse;
00424 
00425             // Add the first page
00426             iListBox->HandleItemAdditionL();
00427 
00428             // Set the first item selected by default. We must do this since 
00429             // HandleItemRemovalL in HandleSearchReadyL resets the listbox.
00430             iModel->SetCurrentItem(0);
00431             iListBox->SetCurrentItemIndex(0);
00432             }
00433         else
00434             {
00435             iListBox->HandleItemAdditionL();
00436             }
00437         }
00438     }
00439 
00440 // End of File
00441 

© Nokia 2006

Back to top