|
S60 3rd Edition SDK for Symbian OS Example Applications Guide |
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 |