S60 3rd Edition SDK for Symbian OS
Example Applications Guide

LandmarksContainer.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : LandmarksContainer.cpp
00004 *  Part of     : Landmark Reference Application
00005 *  Interface   : -
00006 *  Description : Implements the CLandmarksContainer 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 <aknnavi.h>
00019 #include <eikclbd.h>
00020 #include <AknView.h>
00021 #include <AknQueryDialog.h>
00022 
00023 #include "LmRefApp.hrh"
00024 #include <LmRefApp.rsg>
00025 #include "LandmarksContainer.h"
00026 #include "LandmarksCommonData.h"
00027 #include "LandmarksListBoxModel.h"
00028 #include "LandmarksModel.h"
00029 #include "LandmarksEditDialog.h"
00030 #include "LandmarksApplicationEngine.h"
00031 #include "LandmarksListBox.h"
00032 
00033 // ============================= LOCAL FUNCTIONS ===============================
00034 
00035 // -----------------------------------------------------------------------------
00036 // ResetAndDestroyLandmarks resets and destroys all landmarks owned by the 
00037 // supplied landmark array.
00038 // Param: aAny: an instance of CArrayPtr<CPosLandmark>* to reset and destroy
00039 // -----------------------------------------------------------------------------
00040 //
00041 void ResetAndDestroyLandmarks(TAny* aAny)
00042     {
00043     CArrayPtr<CPosLandmark>* landmarks = 
00044         reinterpret_cast <CArrayPtr<CPosLandmark>*> (aAny);
00045     landmarks->ResetAndDestroy();
00046     }
00047 
00048 // ============================ MEMBER FUNCTIONS ===============================
00049 
00050 // -----------------------------------------------------------------------------
00051 // CLandmarksContainer::CLandmarksContainer
00052 // C++ constructor can NOT contain any code, that
00053 // might leave.
00054 // -----------------------------------------------------------------------------
00055 //
00056 CLandmarksContainer::CLandmarksContainer(
00057     CAknView& aView,
00058     CLandmarksApplicationEngine& aEngine,
00059     CAknNavigationDecorator* aNaviDecorator)
00060 :   CLandmarksContainerBase(aView, aEngine), 
00061     iNaviDecorator(aNaviDecorator)
00062     {
00063     }
00064 
00065 // -----------------------------------------------------------------------------
00066 // CLandmarksContainer::ConstructL
00067 // Symbian 2nd phase constructor can leave.
00068 // -----------------------------------------------------------------------------
00069 //
00070 void CLandmarksContainer::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 = CLandmarksModel::NewL();
00081 
00082     // Create a descriptor array that will contain the landmark names and 
00083     // icon indeces.
00084     CLandmarksListBoxModel* model = iListBox->Model();
00085     model->SetItemTextArray(iModel->ItemList());
00086     model->SetOwnershipType(ELbmDoesNotOwnItemArray);
00087 
00088     // Create an icon array that 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 landmarks and icons.
00100     StartUpdateListBoxL();
00101     }
00102 
00103 // Destructor
00104 CLandmarksContainer::~CLandmarksContainer()
00105     {
00106     delete iModel;
00107     delete iCurrentName;
00108     }
00109 
00110 // -----------------------------------------------------------------------------
00111 // CLandmarksContainer::MakeNaviPaneVisibleL
00112 // 
00113 // (other items were commented in a header).
00114 // -----------------------------------------------------------------------------
00115 //
00116 void CLandmarksContainer::MakeNaviPaneVisibleL(TBool aVisible)
00117     {
00118     CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
00119     CAknNavigationControlContainer* naviPane = 
00120         (CAknNavigationControlContainer*) statusPane->
00121             ControlL(TUid::Uid(EEikStatusPaneUidNavi));
00122 
00123     if (!aVisible)
00124         {
00125         // Remove tabs from this view's navi pane
00126         naviPane->Pop(iNaviDecorator);
00127         }
00128     else
00129         {
00130         // Recreate tabs to this view's navi pane
00131         naviPane->PushL(*iNaviDecorator);
00132         }
00133     }
00134 
00135 // -----------------------------------------------------------------------------
00136 // CLandmarksContainer::CurrentLandmark
00137 // 
00138 // (other items were commented in a header).
00139 // -----------------------------------------------------------------------------
00140 //
00141 TPosLmItemId CLandmarksContainer::CurrentLandmark()
00142     {
00143     return iModel->CurrentItemId();
00144     }
00145 
00146 // -----------------------------------------------------------------------------
00147 // CLandmarksContainer::DeleteLandmarkL
00148 // 
00149 // (other items were commented in a header).
00150 // -----------------------------------------------------------------------------
00151 //
00152 void CLandmarksContainer::DeleteLandmarkL()
00153     {
00154     // Extract landmark name
00155     TPtrC name;
00156     CPosLandmark* currentLandmark = 
00157         iEngine.LandmarkLC(iModel->CurrentItemId());
00158     currentLandmark->GetLandmarkName(name);
00159 
00160     // Format query
00161     HBufC* queryFormat = 
00162         iCoeEnv->AllocReadResourceAsDes16LC(R_LMREFAPP_DELETE_LANDMARK);
00163     HBufC* queryBuf = HBufC::NewLC(name.Length() + queryFormat->Length());
00164     TPtr query = queryBuf->Des();
00165     query.Format(*queryFormat, &name);
00166 
00167     // Launch dialog
00168     CAknQueryDialog* queryDialog = CAknQueryDialog::NewL();
00169     if (queryDialog->ExecuteLD(R_LMREFAPP_GENERAL_QUERY, query))
00170         {
00171         iEngine.DeleteLandmarkL(currentLandmark->LandmarkId());
00172         }
00173 
00174     CleanupStack::PopAndDestroy(3, currentLandmark);
00175     }
00176 
00177 // -----------------------------------------------------------------------------
00178 // CLandmarksContainer::OfferKeyEventL
00179 // 
00180 // (other items were commented in a header).
00181 // -----------------------------------------------------------------------------
00182 //
00183 TKeyResponse CLandmarksContainer::OfferKeyEventL(
00184     const TKeyEvent& aKeyEvent, TEventCode aType)
00185     {
00186         TKeyResponse response = EKeyWasNotConsumed;
00187 
00188     switch (aKeyEvent.iCode)
00189         {
00190         case EKeyUpArrow:
00191         case EKeyDownArrow:
00192             // Scrolling the list box. Forward to iListBox.
00193             response = iListBox->OfferKeyEventL(aKeyEvent, aType);
00194             break;
00195 
00196         case EKeyDevice3:
00197             // Select key pressed. Edit landmark.
00198             iView.ProcessCommandL(ELandmarksOpen);
00199             response = EKeyWasConsumed;
00200             break;
00201 
00202         case EKeyBackspace:
00203             if ((iFindBox->TextLength() == 0) && IsItemSelected())
00204                 {
00205                 // If search field is empty backspace deletes a landmark.
00206                 DeleteLandmarkL();
00207                 response = EKeyWasConsumed;
00208                 break;
00209                 }
00210             // remove letter in find box
00211         default:
00212             // Forward key events to find box.
00213             response = iFindBox->OfferKeyEventL(aKeyEvent, aType);
00214             break;
00215         }
00216 
00217     return response;
00218     }
00219 
00220 // -----------------------------------------------------------------------------
00221 // CLandmarksContainer::NotifyOperationProgressL
00222 // 
00223 // (other items were commented in a header).
00224 // -----------------------------------------------------------------------------
00225 //
00226 void CLandmarksContainer::NotifyOperationProgressL(
00227     TOperation aOperation,
00228     TInt aProgress,
00229     TInt aErrorCode)
00230     {
00231     switch (aOperation)
00232         {
00233         case ELandmarkSearch:
00234             HandleSearchReadyL(aErrorCode);
00235             break;
00236 
00237         case ELandmarkRead:
00238             HandleReadReadyL(aErrorCode, aProgress == KOperationReady);
00239             break;
00240 
00241         default:
00242             break;
00243         }
00244     }
00245 
00246 // -----------------------------------------------------------------------------
00247 // CLandmarksContainer::NotifyDbEventL
00248 // 
00249 // (other items were commented in a header).
00250 // -----------------------------------------------------------------------------
00251 //
00252 void CLandmarksContainer::NotifyDbEventL(
00253     TPosLmEvent& aEvent, 
00254     TInt aErrorCode)
00255     {
00256     if (aErrorCode == KErrNone)
00257         {
00258         switch (aEvent.iEventType)
00259             {
00260             case EPosLmEventUnknownChanges:
00261             case EPosLmEventLandmarkUnknownChanges:
00262             case EPosLmEventCategoryUnknownChanges:
00263             case EPosLmEventLandmarkCreated:
00264             case EPosLmEventLandmarkDeleted:
00265                 StartUpdateListBoxL();
00266                 break;
00267             // Any of the 3 events below might have cancelled an ongoing 
00268             // landmark search/read operation => must restart refreshing list
00269             case EPosLmEventCategoryCreated:
00270             case EPosLmEventCategoryDeleted:
00271             case EPosLmEventCategoryUpdated:
00272                 if (iIsActive)
00273                     {
00274                     StartUpdateListBoxL();
00275                     }
00276                 break;
00277             case EPosLmEventLandmarkUpdated:
00278                 if (IsRefreshNeededL(aEvent.iLandmarkItemId))
00279                     {
00280                     StartUpdateListBoxL();
00281                     }
00282                 break;
00283             case EPosLmEventNewDefaultDatabaseLocation:
00284                 // Not supported by this application
00285                 break;
00286             case EPosLmEventMediaRemoved:
00287                 // Not supported by this application
00288                 break;
00289             default:
00290                 // Ignore other category events
00291                 break;
00292             }
00293         }
00294     }
00295 
00296 // -----------------------------------------------------------------------------
00297 // CLandmarksContainer::HandleControlEventL
00298 // 
00299 // (other items were commented in a header).
00300 // -----------------------------------------------------------------------------
00301 //
00302 void CLandmarksContainer::HandleControlEventL(
00303     CCoeControl* aControl, 
00304     TCoeEvent aEventType)
00305     {
00306         if (aEventType == EEventStateChanged && aControl == iListBox)
00307                 {
00308                 // Take the index of the current item in the list
00309                 TInt itemIndex = iListBox->CurrentItemIndex();
00310 
00311                 // Set the current item in the model object regarding to the list box.
00312                 iModel->SetCurrentItem(itemIndex);
00313 
00314         // Store the name of the current landmark
00315         StoreCurrentLandmarkNameL();
00316         }
00317 
00318         if (aEventType == EEventStateChanged && aControl == iFindBox)
00319                 {
00320         // Fetch filter from search field
00321         TInt searchTextLength = iFindBox->TextLength();
00322         HBufC* filterBuf = HBufC::NewLC(searchTextLength);
00323         TPtr filter = filterBuf->Des();
00324         iFindBox->GetSearchText(filter);
00325 
00326         // If filter has changed repopulate list box. (It is necessary to check
00327         // if filter has changed since each filter change generates several 
00328         // EEventStateChanged events for find box)
00329         if (filter != *iOldFilter)
00330             {
00331             // Filter has changed. Start filtering.
00332             StartUpdateListBoxL();
00333             }
00334 
00335         CleanupStack::PopAndDestroy(filterBuf);
00336                 }
00337     }
00338 
00339 // -----------------------------------------------------------------------------
00340 // CLandmarksContainer::StartUpdateListBoxL
00341 // 
00342 // (other items were commented in a header).
00343 // -----------------------------------------------------------------------------
00344 //
00345 void CLandmarksContainer::StartUpdateListBoxL()
00346     {
00347     // Fetch filter from find box
00348     TInt searchTextLength = iFindBox->TextLength();
00349     const TInt KExtraChars = 2; // 2 chars wildcards
00350     HBufC* filterBuf = HBufC::NewLC(searchTextLength + KExtraChars);
00351     TPtr filter = filterBuf->Des();
00352     iFindBox->GetSearchText(filter);
00353 
00354     // Find out if there is any prevoius result to limit the search to
00355     TInt oldFilterLength = iOldFilter->Length();
00356     TBool searchOnlyInPreviousMatches = 
00357         // If previous filter is empty there is no search results
00358         oldFilterLength > 0 && 
00359 
00360         // If chars have been removed from filter we abandon previous results
00361         filter.Length() > oldFilterLength && 
00362 
00363         // There must exist at least one previous match
00364         IsItemSelected();
00365 
00366     // old filter used - now we can update it
00367     delete iOldFilter;
00368     iOldFilter = NULL;
00369     iOldFilter = filter.AllocL();
00370 
00371         // Start to asynchronously populate the listbox model according to filter
00372     if (searchTextLength == 0)
00373         {
00374         iEngine.StartSearchingLandmarksL(this);
00375         }
00376     else
00377         {
00378         filter.Insert(0, KWildCard);
00379         filter.Append(KWildCard);
00380         iEngine.StartSearchingLandmarksL(
00381             filter, searchOnlyInPreviousMatches, this);
00382         }
00383 
00384     // Indicate we are active
00385     iIsActive = ETrue;
00386 
00387     CleanupStack::PopAndDestroy(filterBuf);
00388     }
00389 
00390 // -----------------------------------------------------------------------------
00391 // CLandmarksContainer::HandleSearchReadyL
00392 // 
00393 // (other items were commented in a header).
00394 // -----------------------------------------------------------------------------
00395 //
00396 void CLandmarksContainer::HandleSearchReadyL(TInt aErrorCode)
00397     {
00398 
00399     // Delete old icon array and add new
00400         CColumnListBoxData* columnData = iListBox->ItemDrawer()->ColumnData();
00401     CArrayPtr<CGulIcon>* iconList = columnData->IconArray();
00402     iconList->ResetAndDestroy();
00403     delete iconList;
00404     columnData->SetIconArray(iModel->CreateIconListL());
00405 
00406     if (aErrorCode == KErrNone)
00407         {
00408         // Update model
00409         iModel->SetItemIds(iEngine.FetchLandmarkSearchResult());
00410         iListBox->HandleItemRemovalL();
00411 
00412         iEngine.StartReadingLandmarksL(KNrOfItemsDisplayed, this);
00413         iReadingFirstPage = ETrue;
00414         }
00415     else if (aErrorCode == KErrNotFound)
00416         {
00417         // Updating list ready
00418         iIsActive = EFalse;
00419 
00420         // Update model (indicate no item is selected)
00421         iModel->SetItemIds(NULL);
00422         iModel->SetCurrentItem(iListBox->CurrentItemIndex());
00423 
00424                 // Update the view
00425         iListBox->HandleItemRemovalL();
00426         iListBox->DrawDeferred();
00427         }
00428     }
00429 
00430 // -----------------------------------------------------------------------------
00431 // CLandmarksContainer::HandleReadReadyL
00432 // 
00433 // (other items were commented in a header).
00434 // -----------------------------------------------------------------------------
00435 //
00436 void CLandmarksContainer::HandleReadReadyL(TInt aErrorCode, TBool aFinished)
00437     {
00438     // Update model with new landmarks
00439     CArrayPtr<CPosLandmark>* landmarks = iEngine.FetchLandmarksLC();
00440     CleanupStack::PushL(TCleanupItem(ResetAndDestroyLandmarks, landmarks));
00441     iModel->RepopulateModelL(landmarks);
00442     CleanupStack::PopAndDestroy(2, landmarks);
00443 
00444     if (aErrorCode == KErrNone)
00445         {
00446         if (aFinished)
00447             {
00448             // Updating list ready
00449             iIsActive = EFalse;
00450             }
00451         if (iReadingFirstPage)
00452             {
00453             // First page ready
00454             iReadingFirstPage = EFalse;
00455 
00456             // Add the first page
00457             iListBox->HandleItemAdditionL();
00458 
00459             // Set the first item selected by default. We must do this since 
00460             // HandleItemRemovalL in HandleSearchReadyL resets the listbox.
00461             iModel->SetCurrentItem(0);
00462             iListBox->SetCurrentItemIndex(0);
00463             StoreCurrentLandmarkNameL();
00464             }
00465         else
00466             {
00467             iListBox->HandleItemAdditionL();
00468             }
00469         }
00470     }
00471 
00472 // -----------------------------------------------------------------------------
00473 // CLandmarksContainer::IsRefreshNeededL
00474 // 
00475 // (other items were commented in a header).
00476 // -----------------------------------------------------------------------------
00477 //
00478 TBool CLandmarksContainer::IsRefreshNeededL(TPosLmItemId& aModifiedLandmark)
00479     {
00480     if (iIsActive)
00481         {
00482         return ETrue;
00483         }
00484     else
00485         {
00486         if (aModifiedLandmark == iModel->CurrentItemId())
00487             {
00488             // Investigate if we need to refresh. Compare name.
00489             CPosLandmark* landmark = iEngine.LandmarkLC(aModifiedLandmark);
00490             TPtrC name;
00491             landmark->GetLandmarkName(name);
00492             TBool isNameDifferent = 
00493                 iCurrentName && *iCurrentName != name ||
00494                 !iCurrentName && name != KNullDesC;
00495             CleanupStack::PopAndDestroy(landmark);
00496 
00497             // If name is different the list needs to be re-sorted. Otherwise 
00498             // some other field has been modified and the list is not affected.
00499             return isNameDifferent;
00500             }
00501         else 
00502             {
00503             // Some other process than this has modified a landmark
00504             return ETrue;
00505             }
00506         }
00507     }
00508 
00509 // -----------------------------------------------------------------------------
00510 // CLandmarksContainer::StoreCurrentLandmarkNameL
00511 // 
00512 // (other items were commented in a header).
00513 // -----------------------------------------------------------------------------
00514 //
00515 void CLandmarksContainer::StoreCurrentLandmarkNameL()
00516     {
00517     CPosLandmark* landmark = iEngine.LandmarkLC(iModel->CurrentItemId());
00518     TPtrC name;
00519     landmark->GetLandmarkName(name);
00520     delete iCurrentName;
00521     iCurrentName = NULL;
00522     iCurrentName = name.AllocL();
00523     CleanupStack::PopAndDestroy(landmark);
00524     }
00525 
00526 // End of File
00527 

© Nokia 2006

Back to top