locationdataharvester/mylocationsdatabasemanager/src/mylocationsdatabasemanager.cpp
changeset 26 f3533f6eae3f
child 30 96df3ab41000
equal deleted inserted replaced
24:ccec19943943 26:f3533f6eae3f
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Database manager implementation 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <EPos_CPosLandmarkCategory.h>
       
    19 #include <EPos_CPosLmTextCriteria.h>
       
    20 #include <EPos_CPosLandmarkSearch.h>
       
    21 #include <EPos_CPosLmDatabaseManager.h>
       
    22 #include <EPos_CPosLmNearestCriteria.h>
       
    23 #include <EPos_CPosLandmarkDatabase.h>
       
    24 #include <EPos_CPosLmCategoryManager.h>
       
    25 
       
    26 #include <lbsposition.h>
       
    27 #include <barsread.h>
       
    28 #include <barsc.h>
       
    29 #include <locationservicedefines.h>
       
    30 #include "mylocationsdatabasemanager.h"
       
    31 #include "mylocationlogger.h"
       
    32 #include "mylocationsdefines.h"
       
    33 
       
    34 #include <locationdatalookupdb.h>
       
    35 
       
    36 // separator
       
    37 _LIT( KSeparator, ",");
       
    38 // space
       
    39 _LIT( KSpace, " ");
       
    40 
       
    41 // QString separator
       
    42 const QString KQStringSeparator = ",";
       
    43 // QString space
       
    44 const QString KQStringSpace = " ";
       
    45 
       
    46 // Used to set nearest landmarks search distance criteria
       
    47 const TUint32 KSearchCriteriaDistance = 100; 
       
    48 
       
    49 // Maximum string length of landmark address.
       
    50 const TUint32 KMaxAddressLength = 255; 
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CMyLocationsDatabaseManager::ConstructL()
       
    54 // 2nd phase constructor.
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 EXPORT_C void CMyLocationsDatabaseManager::ConstructL()
       
    58 {
       
    59     __TRACE_CALLSTACK;//Open and intialize Landmark DB
       
    60     iLandmarkDb = CPosLandmarkDatabase::OpenL();
       
    61     ExecuteAndDeleteLD(iLandmarkDb->InitializeL());
       
    62  
       
    63     iLocationAppLookupDb = new LocationDataLookupDb();
       
    64     if( !iLocationAppLookupDb->open() )
       
    65     {
       
    66         User::Leave( KErrUnknown );
       
    67     }
       
    68     
       
    69     // Create category manager for landmarks
       
    70     iLandmarksCatManager = CPosLmCategoryManager::NewL(*iLandmarkDb);
       
    71 
       
    72     // open file session
       
    73     User::LeaveIfError(iFsSession.Connect());
       
    74 
       
    75     // Add contacts and calendar  categories
       
    76     iLmContactsCatId = AddMylocationsCategoryL(KContactsCategory);
       
    77     iLmCalendarCatId = AddMylocationsCategoryL( KCalendarCategory );
       
    78 
       
    79 }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CMyLocationsDatabaseManager::CMyLocationsDatabaseManager()
       
    83 // Default constructor.
       
    84 // -----------------------------------------------------------------------------
       
    85 //
       
    86 EXPORT_C  CMyLocationsDatabaseManager::CMyLocationsDatabaseManager() : iLandmarkDb( NULL ),
       
    87                 iLmContactsCatId( 0 ), //iLandmarksLookupDb( NULL ), 
       
    88                 iLocationAppLookupDb( NULL ),
       
    89                 iLandmarksCatManager( NULL )
       
    90 {
       
    91 }
       
    92 
       
    93 // -----------------------------------------------------------------------------
       
    94 // CMyLocationsDatabaseManager::_CMyLocationsDatabaseManager()
       
    95 // Destructor.
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 CMyLocationsDatabaseManager::~CMyLocationsDatabaseManager()
       
    99 {
       
   100     __TRACE_CALLSTACK;// delete member variables.
       
   101 
       
   102     if (iLocationAppLookupDb)
       
   103     {
       
   104         iLocationAppLookupDb->close();
       
   105         delete iLocationAppLookupDb;
       
   106     }
       
   107 
       
   108     delete iLandmarksCatManager;
       
   109 
       
   110     delete iLandmarkDb;
       
   111 
       
   112     // close the file session
       
   113     iFsSession.Close();
       
   114 
       
   115 }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CMyLocationsDatabaseManager::AddMylocationsCategoryL()
       
   119 // Adds the category to the mylocations and landmarks database..
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 TUint32 CMyLocationsDatabaseManager::AddMylocationsCategoryL( const TDesC&  aCategoryName )
       
   123 {
       
   124     __TRACE_CALLSTACK;//Open the resource file
       
   125     
       
   126     TPosLmItemId catId = 0;
       
   127     
       
   128     //create category
       
   129     CPosLandmarkCategory *category = CPosLandmarkCategory::NewL();
       
   130     CleanupStack::PushL(category);
       
   131     category->SetCategoryNameL( aCategoryName );
       
   132     
       
   133     // Add category to landmarks database
       
   134     TRAPD ( error, ( catId = iLandmarksCatManager->AddCategoryL( *category ) ) );
       
   135     if (error == KErrNone || error == KErrAlreadyExists)
       
   136     {
       
   137         catId = iLandmarksCatManager->GetCategoryL( aCategoryName );
       
   138     }
       
   139 
       
   140     CleanupStack::PopAndDestroy(category);
       
   141 
       
   142     return catId;
       
   143 }
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CMyLocationsDatabaseManager::UpdateDatabaseL()
       
   147 // Updates the location into the landmark database and lookup table. Based on 
       
   148 // the entry source type and the entry change type the updation can be 
       
   149 // addition/modification/deletion.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 EXPORT_C void CMyLocationsDatabaseManager::UpdateDatabaseL(CPosLandmark* aLandmark,
       
   153         const TUint32 aUid, const TUint32 aSourceType, const TUint32 aChangeType)
       
   154 {
       
   155     __TRACE_CALLSTACK;//open the lookup database
       
   156     switch (aChangeType)
       
   157     {
       
   158     // if the entry is added
       
   159     case EEntryAdded:
       
   160     {
       
   161         // Handle this entry in the lookup table and update landmarks db.
       
   162         HandleEntryAdditionL(aLandmark, aUid, aSourceType);
       
   163         break;
       
   164     }
       
   165         // if the entry is modified
       
   166     case EEntryModified:
       
   167     {
       
   168         // Handle this entry in the lookup table and update landmarks db.
       
   169         HandleEntryModificationL(aLandmark, aUid, aSourceType);
       
   170         break;
       
   171     }
       
   172         // if the entry is deleted
       
   173     case EEntryDeleted:
       
   174     {
       
   175         // Handle this entry in the lookup table and update landmarks db.
       
   176         HandleEntryDeletionL(aUid, aSourceType);
       
   177         break;
       
   178     }
       
   179     }
       
   180 
       
   181 }
       
   182 
       
   183 // -----------------------------------------------------------------------------
       
   184 // CMyLocationsDatabaseManager::CheckIfDuplicateExistsL()
       
   185 // Checks if this landmark is already present in database. If present returns the landmark id, else 0
       
   186 // -----------------------------------------------------------------------------
       
   187 //
       
   188 TPosLmItemId CMyLocationsDatabaseManager::CheckIfDuplicateExistsL(
       
   189                                     const CPosLandmark* aLandmark)
       
   190 {
       
   191     __TRACE_CALLSTACK;// Stores the found duplicate landmark's id. 
       
   192     TPosLmItemId retId = 0;
       
   193 
       
   194     // Initially filter only the landmarks which are nearer to the current landmark.
       
   195     // Then we can make a duplicate check on each of the found landmarks.
       
   196 
       
   197     // create a search object.
       
   198     CPosLandmarkSearch* search = CPosLandmarkSearch::NewL(
       
   199             *iLandmarkDb);
       
   200     CleanupStack::PushL(search);
       
   201 
       
   202     TBuf<KMaxAddressLength> lmAddress1;
       
   203     GetLandmarkFullAddress( lmAddress1, aLandmark );
       
   204     QString str1 = QString( (QChar*)lmAddress1.Ptr(), lmAddress1.Length());
       
   205 
       
   206     // create nearest search criteria object
       
   207     TLocality position( TCoordinate( 0, 0), 0 );
       
   208     aLandmark->GetPosition( position );
       
   209     CPosLmNearestCriteria* nearestCriteria = 
       
   210                 CPosLmNearestCriteria::NewLC( 
       
   211                         TCoordinate( position.Latitude(), position.Longitude() ) );
       
   212     nearestCriteria->SetMaxDistance( KSearchCriteriaDistance );
       
   213     
       
   214     // Start the search and execute it at once.
       
   215     ExecuteAndDeleteLD( search->StartLandmarkSearchL( *nearestCriteria ) );
       
   216     CleanupStack::PopAndDestroy( nearestCriteria );
       
   217 
       
   218     // Retrieve an iterator to access the matching landmarks.
       
   219     CPosLmItemIterator* iter = search->MatchIteratorL();
       
   220     CleanupStack::PushL(iter);
       
   221 
       
   222     // Iterate the search matches.
       
   223     TPosLmItemId lmId;
       
   224 
       
   225     while( ( lmId = iter->NextL() ) != KPosLmNullItemId )
       
   226     {
       
   227         CPosLandmark* lm = iLandmarkDb->ReadLandmarkLC( lmId );
       
   228         TBuf<KMaxAddressLength> lmAddress2;
       
   229         GetLandmarkFullAddress( lmAddress2, lm );
       
   230         QString str2 = QString( (QChar*)lmAddress2.Ptr(), lmAddress2.Length());
       
   231         CleanupStack::PopAndDestroy( lm );
       
   232         
       
   233         if( str1 == str2 )
       
   234         {
       
   235             retId = lmId;
       
   236             break;
       
   237         }
       
   238     }
       
   239 
       
   240     CleanupStack::PopAndDestroy(iter);
       
   241     CleanupStack::PopAndDestroy(search);
       
   242 
       
   243     return retId;
       
   244 }
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // CMyLocationsDatabaseManager::CompareLandmarks()
       
   248 // Compares two landmarks. Only the text fields, landmark name, street, city, state country and 
       
   249 // postal code are compared.
       
   250 // -----------------------------------------------------------------------------
       
   251 //
       
   252 TBool CMyLocationsDatabaseManager::CompareLandmarks(
       
   253         const CPosLandmark* aLandmark1, const CPosLandmark* aLandmark2 )
       
   254 {
       
   255     __TRACE_CALLSTACK;
       
   256 
       
   257     TBuf<KMaxAddressLength> lmAddress1;
       
   258     GetLandmarkFullAddress( lmAddress1, aLandmark1 );
       
   259     QString str1 = QString( (QChar*)lmAddress1.Ptr(), lmAddress1.Length());
       
   260 
       
   261     TBuf<KMaxAddressLength> lmAddress2;
       
   262     GetLandmarkFullAddress( lmAddress2, aLandmark2 );
       
   263     QString str2 = QString( (QChar*)lmAddress2.Ptr(), lmAddress2.Length());
       
   264 
       
   265     if( str1 == str2 )
       
   266         return ETrue;
       
   267     else
       
   268         return EFalse;
       
   269     
       
   270     
       
   271 }
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // CMyLocationsDatabaseManager::HandleEntryAdditionL()
       
   275 // Handles the entry addition in lookup table and landmarks db
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 void CMyLocationsDatabaseManager::HandleEntryAdditionL(CPosLandmark* aLandmark,
       
   279         const TUint32 aUid, const TUint32 aSourceType)
       
   280 {
       
   281     __TRACE_CALLSTACK;
       
   282     // Create a lookup item
       
   283     QLookupItem lookupItem;
       
   284     lookupItem.mSourceUid = aUid;
       
   285     lookupItem.mSourceType = aSourceType;
       
   286     lookupItem.mDestId = 0;
       
   287     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   288     lookupItem.mIsDuplicate = 0;
       
   289     lookupItem.mIconPath = "";
       
   290     lookupItem.mMapTilePath = "";
       
   291     
       
   292     //fill address into lookup item.
       
   293     FillLookupItemAddressDetails( aLandmark, lookupItem );
       
   294 
       
   295     if ( aSourceType == ESourceLandmarks )
       
   296     {
       
   297         // Logic: check if the entry is already present in lookupdb. 
       
   298         // If present, it means the landmark corresponds to a contact/calendar. So ignore it.
       
   299         // If not present, it means the landmark is created directly into the landmarks db. So add
       
   300         // it in lookupdb as well.
       
   301         
       
   302         // check if the entry is already present in lookup db.
       
   303         QList<QLookupItem> itemArray;
       
   304         iLocationAppLookupDb->findEntriesByLandmarkId( aUid, itemArray );
       
   305         if( itemArray.count() )
       
   306         {
       
   307             return;
       
   308         }
       
   309         else
       
   310         {
       
   311             lookupItem.mDestId = aUid;
       
   312             iLocationAppLookupDb->createEntry( lookupItem );
       
   313             return;
       
   314         }
       
   315     }
       
   316 
       
   317     TPosLmItemId catId;
       
   318     if( aSourceType == ESourceCalendar )
       
   319     {
       
   320         // category id to calendar
       
   321         catId = iLmCalendarCatId;
       
   322     }
       
   323     else 
       
   324     {
       
   325         // remove landmark name, which is basically contact's name.
       
   326         aLandmark->SetLandmarkNameL( KNullDesC );
       
   327         // category id to contacts
       
   328         catId = iLmContactsCatId;
       
   329     }
       
   330     // check if this landmark is already present in database
       
   331     TPosLmItemId dupLmId = CheckIfDuplicateExistsL( aLandmark );
       
   332     if ( dupLmId )
       
   333     {
       
   334         // landmark already present in db. get the details
       
   335         CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC(dupLmId);
       
   336         if( dupLandmark )
       
   337         {
       
   338             // add category.
       
   339             dupLandmark->AddCategoryL( catId );
       
   340             // update the landmark object in the db
       
   341             iLandmarkDb->UpdateLandmarkL( *dupLandmark );
       
   342             CleanupStack::PopAndDestroy( dupLandmark );
       
   343         }
       
   344 
       
   345         // point the lookup item's landmark uid to the existing landmark.
       
   346         lookupItem.mDestId = dupLmId;
       
   347         if( aSourceType == ESourceCalendar )
       
   348         {
       
   349             // set duplicate flag to true. only if it is calendar entry.
       
   350             // for contacts duplicate doesnot hold good as the location name is the contact name.
       
   351         
       
   352             // set duplicate only if there are calendar entries already pointing to this landmark. 
       
   353             if( IsDuplicateEntry( dupLmId ) )
       
   354             {
       
   355                 lookupItem.mIsDuplicate = 1;
       
   356             }
       
   357         }
       
   358     }
       
   359     else // it is a new entry, so add into the database
       
   360     {
       
   361         // add category.
       
   362         aLandmark->AddCategoryL( catId );
       
   363         // add the landmark into the db. 
       
   364         // point the lookup item's landmark uid to the newly created landmark in the db.
       
   365         lookupItem.mDestId = iLandmarkDb->AddLandmarkL( *aLandmark );
       
   366     }
       
   367 
       
   368     // create the entry in the lookup table.
       
   369     iLocationAppLookupDb->createEntry( lookupItem );
       
   370 }
       
   371 
       
   372 // -----------------------------------------------------------------------------
       
   373 // CMyLocationsDatabaseManager::HandleEntryModificationL()
       
   374 // Handles the entry modification in the lookup table and landmarks db.
       
   375 // -----------------------------------------------------------------------------
       
   376 //
       
   377 void CMyLocationsDatabaseManager::HandleEntryModificationL(
       
   378         CPosLandmark* aLandmark, const TUint32 aUid, const TUint32 aSourceType )
       
   379 {
       
   380     __TRACE_CALLSTACK;
       
   381     if ( aSourceType == ESourceLandmarks )
       
   382     {
       
   383         HandleLandmarkModificationL( aLandmark, aUid );
       
   384         return;
       
   385     }
       
   386 
       
   387     QLookupItem lookupItem;
       
   388     lookupItem.mSourceUid = aUid;
       
   389     lookupItem.mSourceType = aSourceType;
       
   390     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   391 
       
   392     // Behavior: If an entry is modified, 
       
   393     // If this entry is not present in lookup table. add the entry and update the landmarks db.
       
   394     // If this entry is already present in lookup table, check if the location info is modified or not.
       
   395     // If the location info is modified, delete the landmark from db and add the new landmark
       
   396     // into the db. 
       
   397     // Before deletion make sure that the landmark is not being refered by other lookup entries.
       
   398 
       
   399     // find the entry in the lookup table.
       
   400     if ( iLocationAppLookupDb->findEntryBySourceIdAndType( lookupItem ) )
       
   401     {
       
   402         //fill address into lookup item.
       
   403         FillLookupItemAddressDetails( aLandmark, lookupItem );
       
   404         
       
   405         QString locationName = lookupItem.mName;
       
   406     
       
   407         TPosLmItemId catId;
       
   408         
       
   409         if( aSourceType == ESourceCalendar )
       
   410         {
       
   411             catId = iLmCalendarCatId;
       
   412         }
       
   413         else
       
   414         {
       
   415             // remove landmark name, which is basically contact's name.
       
   416             aLandmark->SetLandmarkNameL( KNullDesC );
       
   417             
       
   418             // category id to contacts
       
   419             catId = iLmContactsCatId;
       
   420         }
       
   421 
       
   422         
       
   423         // check if the location info is modified by comparing the new landmark with the existing landmark
       
   424         CPosLandmark* existingLandmark = NULL;
       
   425         TRAPD( error, ( existingLandmark = 
       
   426                CheckAndReadLandmarkL( iLandmarkDb, lookupItem.mDestId ) ) );
       
   427         CleanupStack::PushL( existingLandmark );
       
   428         if ( error == KErrNotFound )
       
   429         {
       
   430             // Landmarks item deleted. So delete corresponding lookup entries.
       
   431             QList<QLookupItem> itemArray;
       
   432             iLocationAppLookupDb->findEntriesByLandmarkId( lookupItem.mDestId, itemArray );
       
   433             for ( int i = 0; i < itemArray.count(); i++)
       
   434             {
       
   435                 iLocationAppLookupDb->deleteEntryBySourceIdAndType( itemArray[i] );
       
   436             }
       
   437 
       
   438             // Add the entry into the lookup table and update landmarks db.
       
   439             HandleEntryAdditionL( aLandmark, aUid, aSourceType );
       
   440             
       
   441             CleanupStack::PopAndDestroy( existingLandmark );
       
   442             return;
       
   443         }
       
   444 
       
   445         if ( !CompareLandmarks( existingLandmark, aLandmark ) )
       
   446         {
       
   447             // landmarks are not same, means location information is modified.
       
   448 
       
   449             // Check if the new landmark is already in db.
       
   450             TPosLmItemId dupLmId = CheckIfDuplicateExistsL( aLandmark );
       
   451             if ( dupLmId )
       
   452             {
       
   453                 // landmark already present in db. get the details
       
   454                 CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC( dupLmId );
       
   455                 if ( dupLandmark )
       
   456                 {
       
   457                     // add category.
       
   458                     dupLandmark->AddCategoryL( catId );
       
   459 
       
   460                     // update the landmark object in the db
       
   461                     iLandmarkDb->UpdateLandmarkL( *dupLandmark );
       
   462                 }
       
   463                 CleanupStack::PopAndDestroy( dupLandmark );
       
   464 
       
   465                 // update the lookup item to refer to the newly created landmark.
       
   466                 lookupItem.mDestId = dupLmId;
       
   467                 if( aSourceType == ESourceCalendar )
       
   468                 {
       
   469                     // for contacts duplicate doesnot hold good as the location name is the contact name.
       
   470                     if( !lookupItem.mIsDuplicate )
       
   471                     {
       
   472                         // if current lookup item duplicate property is 0, then remove next corresponding
       
   473                         // calendar lookup entry duplicate property.
       
   474                         // this is required because the current entry will be pointing to a new landmark.
       
   475                         UnsetDuplicateNextCalEntry( existingLandmark->LandmarkId() );
       
   476                     } 
       
   477 
       
   478                     // set duplicate only if there are calendar entries already pointing to this landmark. 
       
   479                     if( IsDuplicateEntry( dupLmId ) )
       
   480                     {
       
   481                         lookupItem.mIsDuplicate = 1;
       
   482                     }
       
   483 
       
   484                 }
       
   485                 
       
   486                 iLocationAppLookupDb->updateEntryBySourceIdAndType( lookupItem );
       
   487             }
       
   488             else
       
   489             {
       
   490                 // landmark not already present in db.
       
   491                 // Create a new entry in the db
       
   492                 aLandmark->AddCategoryL( catId );
       
   493                 lookupItem.mDestId = iLandmarkDb->AddLandmarkL( *aLandmark );
       
   494                 if( aSourceType == ESourceCalendar )
       
   495                 {
       
   496                     // for contacts duplicate doesnot hold good as the location name is the contact name.
       
   497                     if( !lookupItem.mIsDuplicate )
       
   498                     {
       
   499                         // if current lookup item duplicate property is 0, then remove next corresponding
       
   500                         // calendar lookup entry duplicate property.
       
   501                         // this is required because the current entry will be pointing to a new landmark.
       
   502                         UnsetDuplicateNextCalEntry( existingLandmark->LandmarkId() );
       
   503                     } 
       
   504                 }
       
   505                 
       
   506                 lookupItem.mIsDuplicate = 0;
       
   507                 // update the lookup table
       
   508                 iLocationAppLookupDb->updateEntryBySourceIdAndType( lookupItem );
       
   509             }
       
   510         }
       
   511         else
       
   512         {
       
   513             // landmarks are same, means location not modified. So return.
       
   514             if( aSourceType == ESourceContactsPref
       
   515                                     || aSourceType == ESourceContactsWork
       
   516                                     || aSourceType == ESourceContactsHome
       
   517                                     )
       
   518             {
       
   519                 // in case of contacts, there is a chance that contact name is modified. 
       
   520                 // so update the lookup database entry with that name.
       
   521                 lookupItem.mName = locationName;
       
   522                 iLocationAppLookupDb->updateEntryBySourceIdAndType( lookupItem );
       
   523             }
       
   524 
       
   525             CleanupStack::PopAndDestroy( existingLandmark );
       
   526             return;
       
   527         }
       
   528 
       
   529         // delete the existing landmark only if it not being refered by other lookup entries.
       
   530 
       
   531         // Check if any other entries are refering this landmark.
       
   532         QList<QLookupItem> itemArray;
       
   533         iLocationAppLookupDb->findEntriesByLandmarkId(
       
   534                 existingLandmark->LandmarkId(), itemArray );
       
   535 
       
   536         if ( itemArray.count() )
       
   537         {
       
   538             // There are other lookup entries refering this landmark. So do not delete the landmark
       
   539 
       
   540             // If none of these lookup item's source type is current source type, disassociate 'catId' category
       
   541             // from this landmark.
       
   542             TInt i = 0;
       
   543             while ( i < itemArray.count() )
       
   544             {
       
   545                 if( aSourceType == ESourceCalendar )
       
   546                 {
       
   547                     if ( itemArray[i].mSourceType == aSourceType )
       
   548                     {
       
   549                         // a lookup item exists which is from calendar, so 'catId' is still valid.
       
   550                         break;
       
   551                     }
       
   552                  }
       
   553                 else 
       
   554                 {
       
   555                     // a lookup item exists which is from contacts, so 'catId' is still valid.
       
   556                     break;
       
   557                 }
       
   558                 i++;
       
   559             }
       
   560             if ( i == itemArray.count() )
       
   561             {
       
   562                 // no lookup items from current source type exists refering this landmark.
       
   563                 // so disassociate 'catId' from this landmark
       
   564 
       
   565                 existingLandmark->RemoveCategory( catId );
       
   566                 iLandmarkDb->UpdateLandmarkL( *existingLandmark );
       
   567             }
       
   568         }
       
   569         else
       
   570         {
       
   571             // no other lookup entry is refering this landmark. 
       
   572             // delete the landmark.
       
   573             iLandmarkDb->RemoveLandmarkL( existingLandmark->LandmarkId() );
       
   574         }
       
   575         CleanupStack::PopAndDestroy( existingLandmark );
       
   576 
       
   577     }
       
   578     else // entry not present in lookup table
       
   579     {
       
   580         // Add the entry into the lookup table and update landmarks db.
       
   581         HandleEntryAdditionL( aLandmark, aUid, aSourceType );
       
   582     }
       
   583 }
       
   584 
       
   585 // -----------------------------------------------------------------------------
       
   586 // CMyLocationsDatabaseManager::HandleEntryDeletionL()
       
   587 // Handles the entry deletion in lookup table and landmarks db.
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 void CMyLocationsDatabaseManager::HandleEntryDeletionL(const TUint32 aUid,
       
   591                                                 const TUint32 aSourceType)
       
   592 {
       
   593     __TRACE_CALLSTACK;
       
   594     QLookupItem lookupItem;
       
   595     lookupItem.mSourceUid = aUid;
       
   596     lookupItem.mSourceType = aSourceType;
       
   597 
       
   598     // Behavior: if an entry is deleted, delete the corresponding entries from 
       
   599     // both lookup table and iLandmarkDb.  
       
   600     // Before deleting the entry from iLandmarkDb, make sure that this entry is not being refered by
       
   601     // other entries of the lookup table. If it is being refered by other entries in lookup table, then
       
   602     // do not delete the landmark.
       
   603  
       
   604     if ( !iLocationAppLookupDb->findEntryBySourceIdAndType( lookupItem ) )
       
   605     {
       
   606         if( aSourceType == ESourceLandmarks )
       
   607         {
       
   608             lookupItem.mDestId = aUid;
       
   609         }
       
   610         else
       
   611         {
       
   612             return;
       
   613         }
       
   614     }
       
   615     
       
   616     // Find the corresponding landmark uid
       
   617     
       
   618 
       
   619     // delete the lookup entry.
       
   620     iLocationAppLookupDb->deleteEntryBySourceIdAndType( lookupItem );
       
   621 
       
   622     // Check if any other entries are refering this landmark.
       
   623     QList<QLookupItem> itemArray;
       
   624     iLocationAppLookupDb->findEntriesByLandmarkId( lookupItem.mDestId, itemArray );
       
   625 
       
   626     if ( itemArray.count() )
       
   627     {
       
   628     
       
   629         if( aSourceType == ESourceLandmarks )
       
   630         {
       
   631             CPosLandmark* lm = NULL;
       
   632         
       
   633             for( int i = 0; i < itemArray.count(); i++ )
       
   634             {
       
   635                 if( itemArray[i].mSourceType == ESourceCalendar )
       
   636                 {
       
   637                     // add landmark entry since a calendar item is present with this location.
       
   638                    if( !lm )
       
   639                    {
       
   640                        lm = CreateLandmarkItemLC( itemArray[i] );
       
   641                    }
       
   642                    lm->AddCategoryL( iLmCalendarCatId );
       
   643                 }
       
   644                 else
       
   645                 {
       
   646                    // add landmark entry since a contact item is present with this location.
       
   647                    if( !lm )
       
   648                    {
       
   649                        QString tempStr = itemArray[i].mName;
       
   650                        itemArray[i].mName = "";
       
   651                        lm = CreateLandmarkItemLC( itemArray[i] );
       
   652                        itemArray[i].mName = tempStr;
       
   653                    }
       
   654                    lm->AddCategoryL( iLmCalendarCatId );
       
   655                 }    
       
   656             }
       
   657 
       
   658             lookupItem.mDestId = iLandmarkDb->AddLandmarkL( *lm );
       
   659             CleanupStack::PopAndDestroy( lm );
       
   660 
       
   661             bool dupUnset = false;
       
   662             for( int i=0; i<itemArray.count(); i++ )
       
   663             {
       
   664                 itemArray[i].mDestId = lookupItem.mDestId;
       
   665                 if( itemArray[i].mSourceType == ESourceCalendar && dupUnset == false )
       
   666                 {
       
   667                     dupUnset = true;
       
   668                     itemArray[i].mIsDuplicate = 0;
       
   669                 }
       
   670                 iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
   671             }   
       
   672             
       
   673             return;
       
   674         }
       
   675 
       
   676         // There are other lookup entries refering this landmark. So do not delete the landmark
       
   677 
       
   678         // If none of these lookup item's source type is current source type, disassociate current source category
       
   679         // from this landmark.
       
   680         TInt i = 0;
       
   681         while ( i < itemArray.count() )
       
   682         {
       
   683             if( aSourceType == ESourceCalendar )
       
   684             {
       
   685                 if( itemArray[i].mSourceType == aSourceType )
       
   686                 {
       
   687                     if( lookupItem.mIsDuplicate == 0 )
       
   688                     {
       
   689                         itemArray[i].mIsDuplicate = 0;
       
   690                         iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
   691                     }
       
   692                     // a lookup item exists which is from calendar, so 'iLmCalendarCatId' is still valid.
       
   693                     break;
       
   694                 }
       
   695         
       
   696             }
       
   697             else if ( itemArray[i].mSourceType == ESourceContactsPref
       
   698                     || itemArray[i].mSourceType == ESourceContactsWork
       
   699                     || itemArray[i].mSourceType == ESourceContactsHome)
       
   700             {
       
   701                 // a lookup item exists which is from contacts, so 'iLmContactsCatId' is still valid.
       
   702                 break;
       
   703             }
       
   704             i++;
       
   705         }
       
   706         if ( i == itemArray.count() )
       
   707         {
       
   708             // no lookup items from current source type exists refering this landmark.
       
   709             // so disassociate current source category from this landmark
       
   710 
       
   711             CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC( lookupItem.mDestId );
       
   712             if( aSourceType == ESourceCalendar )
       
   713             {
       
   714                 landmark->RemoveCategory( iLmCalendarCatId );
       
   715             }
       
   716             else
       
   717             {
       
   718                 landmark->RemoveCategory( iLmContactsCatId );
       
   719             }
       
   720             
       
   721             iLandmarkDb->UpdateLandmarkL( *landmark );
       
   722             CleanupStack::PopAndDestroy( landmark );
       
   723         }
       
   724     }
       
   725     else
       
   726     {
       
   727         // no other lookup entry is refering this landmark. 
       
   728         // delete the landmark.
       
   729         if ( aSourceType != ESourceLandmarks )
       
   730         {
       
   731             iLandmarkDb->RemoveLandmarkL( lookupItem.mDestId );
       
   732         }
       
   733     }
       
   734 }
       
   735 
       
   736 // -----------------------------------------------------------------------------
       
   737 // CMyLocationsDatabaseManager::HandleLandmarkModificationL()
       
   738 // -----------------------------------------------------------------------------
       
   739 //
       
   740 void CMyLocationsDatabaseManager::HandleLandmarkModificationL(
       
   741         CPosLandmark* aLandmark, const TUint32 aUid )
       
   742 {
       
   743     // logic: if a landmark is modified, 
       
   744     // first update the corresponding landmark lookup entry if present, else create a new entry.
       
   745     // Check for any contact/calendar entries refering this landmark entry,
       
   746     // if exists, create a new landmark entry with that location details and update all those 
       
   747     // lookup entry's destid with the newly created landmark id.
       
   748     
       
   749     QLookupItem lookupItem;
       
   750     lookupItem.mSourceUid = aUid;
       
   751     lookupItem.mSourceType = ESourceLandmarks;
       
   752     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   753 
       
   754     bool found = iLocationAppLookupDb->findEntryBySourceIdAndType( lookupItem );
       
   755     //fill address into lookup item.
       
   756     FillLookupItemAddressDetails( aLandmark, lookupItem );
       
   757     lookupItem.mDestId = aUid;
       
   758     lookupItem.mIsDuplicate = 0;
       
   759     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   760     lookupItem.mIconPath = "";
       
   761     lookupItem.mMapTilePath = "";
       
   762 
       
   763     // update entry in lookup table.
       
   764     if ( found )
       
   765     {
       
   766         iLocationAppLookupDb->updateEntryById( lookupItem );
       
   767     }
       
   768     else
       
   769     {
       
   770         iLocationAppLookupDb->createEntry( lookupItem );
       
   771     }
       
   772     
       
   773     QList<QLookupItem> itemArray;
       
   774     iLocationAppLookupDb->findEntriesByLandmarkId( lookupItem.mDestId, itemArray );
       
   775     
       
   776     if( itemArray.count() == 1 )
       
   777     {
       
   778         //only one entry ie the entry corresponding to landmark db is present.
       
   779         return;
       
   780     }
       
   781     
       
   782     CPosLandmark* lm = NULL;
       
   783     
       
   784     for( int i = 0; i < itemArray.count(); i++ )
       
   785     {
       
   786         if( itemArray[i].mSourceType != ESourceLandmarks )
       
   787         {
       
   788             if( itemArray[i].mSourceType == ESourceCalendar )
       
   789             {
       
   790                 // add landmark entry since a calendar item is present with this location.
       
   791                if( !lm )
       
   792                {
       
   793                    lm = CreateLandmarkItemLC( itemArray[i] );
       
   794                }
       
   795                lm->AddCategoryL( iLmCalendarCatId );
       
   796             }
       
   797             else
       
   798             {
       
   799                // add landmark entry since a calendar item is present with this location.
       
   800                if( !lm )
       
   801                {
       
   802                    QString tempStr = itemArray[i].mName;
       
   803                    itemArray[i].mName = "";
       
   804                    lm = CreateLandmarkItemLC( itemArray[i] );
       
   805                    itemArray[i].mName = tempStr;
       
   806                }
       
   807                lm->AddCategoryL( iLmCalendarCatId );
       
   808             }    
       
   809         }
       
   810     }
       
   811     
       
   812     // add the entry to landmarks db
       
   813     quint32 newDestId = iLandmarkDb->AddLandmarkL( *lm );
       
   814     CleanupStack::PopAndDestroy( lm );
       
   815 
       
   816     bool calDuplicateUnset = false;
       
   817     // update all the lookup entries with new landmark id
       
   818     for( int i = 0; i < itemArray.count(); i++ )
       
   819     {
       
   820         if( itemArray[i].mSourceType != ESourceLandmarks )
       
   821         {
       
   822             itemArray[i].mDestId = newDestId;
       
   823             
       
   824             if( itemArray[i].mSourceType == ESourceCalendar )
       
   825             {
       
   826                 if( !calDuplicateUnset )
       
   827                 {
       
   828                     itemArray[i].mIsDuplicate = 0;
       
   829                     calDuplicateUnset = true;
       
   830                 }
       
   831                 else
       
   832                 {
       
   833                     itemArray[i].mIsDuplicate = 1;
       
   834                 }
       
   835             }
       
   836             iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
   837         }
       
   838     }
       
   839 }
       
   840 // -----------------------------------------------------------------------------
       
   841 // CMyLocationsDatabaseManager::GetLandmarkFullAddress()
       
   842 // Gets the comma separated full address of the given landmark.
       
   843 // -----------------------------------------------------------------------------
       
   844 //
       
   845 EXPORT_C void CMyLocationsDatabaseManager::GetLandmarkFullAddress(
       
   846         TBuf<KMaxAddressLength>& aLandmarkAddress,
       
   847         const CPosLandmark* aLandmark)
       
   848 {
       
   849     TPtrC tempStr;
       
   850     TInt retStatus;
       
   851     TBool addressEmtpy = ETrue;
       
   852     retStatus = aLandmark->GetPositionField(EPositionFieldStreet, tempStr);
       
   853     if (retStatus == KErrNone && tempStr.Length())
       
   854     {
       
   855         {
       
   856             aLandmarkAddress.Copy(tempStr);
       
   857             addressEmtpy = EFalse;
       
   858         }
       
   859     }
       
   860 
       
   861     retStatus = aLandmark->GetPositionField(EPositionFieldCity, tempStr);
       
   862     if (retStatus == KErrNone && tempStr.Length())
       
   863     {
       
   864         if (!addressEmtpy)
       
   865         {
       
   866             aLandmarkAddress.Append(KSeparator);
       
   867             aLandmarkAddress.Append(KSpace);
       
   868             aLandmarkAddress.Append(tempStr);
       
   869         }
       
   870         else
       
   871         {
       
   872             aLandmarkAddress.Copy(tempStr);
       
   873             addressEmtpy = EFalse;
       
   874         }
       
   875     }
       
   876 
       
   877     retStatus = aLandmark->GetPositionField(EPositionFieldState, tempStr);
       
   878     if (retStatus == KErrNone && tempStr.Length())
       
   879     {
       
   880         if (!addressEmtpy)
       
   881         {
       
   882             aLandmarkAddress.Append(KSeparator);
       
   883             aLandmarkAddress.Append(KSpace);
       
   884             aLandmarkAddress.Append(tempStr);
       
   885         }
       
   886         else
       
   887         {
       
   888             aLandmarkAddress.Copy(tempStr);
       
   889             addressEmtpy = EFalse;
       
   890         }
       
   891     }
       
   892 
       
   893     retStatus = aLandmark->GetPositionField(EPositionFieldCountry, tempStr);
       
   894     if (retStatus == KErrNone && tempStr.Length())
       
   895     {
       
   896         if (!addressEmtpy)
       
   897         {
       
   898             aLandmarkAddress.Append(KSeparator);
       
   899             aLandmarkAddress.Append(KSpace);
       
   900             aLandmarkAddress.Append(tempStr);
       
   901         }
       
   902         else
       
   903         {
       
   904             aLandmarkAddress.Copy(tempStr);
       
   905             addressEmtpy = EFalse;
       
   906         }
       
   907     }
       
   908 }
       
   909 
       
   910 // -----------------------------------------------------------------------------
       
   911 // CMyLocationsDatabaseManager::CheckAndReadLandmarkL()
       
   912 // Checks if given landmark id is found in the database and returns the read landmark.
       
   913 // -----------------------------------------------------------------------------
       
   914 //
       
   915 CPosLandmark* CMyLocationsDatabaseManager::CheckAndReadLandmarkL(
       
   916         CPosLandmarkDatabase* aDb, const TUint32 aLmId)
       
   917 {
       
   918     __TRACE_CALLSTACK;
       
   919     CPosLandmark* lm = aDb->ReadLandmarkLC(aLmId);
       
   920     CleanupStack::Pop(lm);    
       
   921     return lm;
       
   922 }
       
   923 
       
   924 // -----------------------------------------------------------------------------
       
   925 // CMyLocationsDatabaseManager::FillLookupItemAddressDetails()
       
   926 // Creates a new category in Mylocations Db and adds a corresponding entry in 
       
   927 // mylocations lookup table.
       
   928 // -----------------------------------------------------------------------------
       
   929 //
       
   930 void CMyLocationsDatabaseManager::FillLookupItemAddressDetails( CPosLandmark* aLandmark, QLookupItem& aLookupItem )
       
   931 {
       
   932     __TRACE_CALLSTACK;// Read the category.
       
   933 
       
   934     // fill geo-coordinates
       
   935     TLocality position;
       
   936     aLandmark->GetPosition( position );
       
   937     aLookupItem.mLatitude = position.Latitude();
       
   938     aLookupItem.mLongitude = position.Longitude();
       
   939 
       
   940     TPtrC tempStr;
       
   941     TInt retStatus;
       
   942 
       
   943     // Copy landmark name in address 1
       
   944     retStatus = aLandmark->GetLandmarkName( tempStr );
       
   945     aLookupItem.mName = "";
       
   946     if( retStatus == KErrNone && tempStr.Length() > 0 )
       
   947     {
       
   948         aLookupItem.mName = QString( (QChar*)tempStr.Ptr(), tempStr.Length() );
       
   949     }
       
   950 
       
   951     // get street
       
   952     aLookupItem.mStreet = "";
       
   953     retStatus = aLandmark->GetPositionField( EPositionFieldStreet, tempStr );
       
   954     if( retStatus == KErrNone && tempStr.Length() )
       
   955     {
       
   956         aLookupItem.mStreet = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   957     }
       
   958 
       
   959     // get postal code
       
   960     aLookupItem.mPostalCode = "";
       
   961     retStatus = aLandmark->GetPositionField( EPositionFieldPostalCode, tempStr );
       
   962     if( retStatus == KErrNone && tempStr.Length() )
       
   963     {
       
   964         aLookupItem.mPostalCode = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   965     }
       
   966 
       
   967     // get city
       
   968     aLookupItem.mCity = "";
       
   969     retStatus = aLandmark->GetPositionField( EPositionFieldCity, tempStr );
       
   970     if( retStatus == KErrNone && tempStr.Length() )
       
   971     {
       
   972         aLookupItem.mCity = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   973     }
       
   974 
       
   975     // get State
       
   976     aLookupItem.mState = "";
       
   977     retStatus = aLandmark->GetPositionField( EPositionFieldState, tempStr );
       
   978     if( retStatus == KErrNone && tempStr.Length() )
       
   979     {
       
   980         aLookupItem.mState = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   981     }
       
   982 
       
   983     // get country
       
   984     aLookupItem.mCountry = "";
       
   985     retStatus = aLandmark->GetPositionField( EPositionFieldCountry, tempStr );
       
   986     if( retStatus == KErrNone && tempStr.Length() )
       
   987     {
       
   988         aLookupItem.mCountry = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   989     }
       
   990 }
       
   991 
       
   992 // -----------------------------------------------------------------------------
       
   993 // CMyLocationsDatabaseManager::UnsetDuplicateNextCalEntry()
       
   994 // -----------------------------------------------------------------------------
       
   995 //
       
   996 void CMyLocationsDatabaseManager::UnsetDuplicateNextCalEntry( quint32 aLandmarkId )
       
   997 {
       
   998     // get next duplicate item
       
   999     QList<QLookupItem> itemArray;
       
  1000     iLocationAppLookupDb->findEntriesByLandmarkId( aLandmarkId, itemArray );
       
  1001     for ( int i = 0; i < itemArray.count(); i++)
       
  1002     {
       
  1003         if( itemArray[i].mSourceType == ESourceCalendar )
       
  1004         {
       
  1005             itemArray[i].mIsDuplicate = 0;
       
  1006             iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
  1007             break;
       
  1008         }
       
  1009     }
       
  1010 
       
  1011 }
       
  1012 // -----------------------------------------------------------------------------
       
  1013 // CMyLocationsDatabaseManager::IsDuplicateEntry()
       
  1014 // -----------------------------------------------------------------------------
       
  1015 //
       
  1016 bool CMyLocationsDatabaseManager::IsDuplicateEntry( quint32 aLandmarkId )
       
  1017 {
       
  1018     // get next duplicate item
       
  1019     QList<QLookupItem> itemArray;
       
  1020     iLocationAppLookupDb->findEntriesByLandmarkId( aLandmarkId, itemArray );
       
  1021     for ( int i = 0; i < itemArray.count(); i++)
       
  1022     {
       
  1023         if( itemArray[i].mSourceType == ESourceCalendar ||
       
  1024             itemArray[i].mSourceType == ESourceLandmarks )
       
  1025         {
       
  1026             return true;
       
  1027         }
       
  1028     }
       
  1029     
       
  1030     return false;
       
  1031 }
       
  1032 
       
  1033 // -----------------------------------------------------------------------------
       
  1034 // CMyLocationsDatabaseManager::CreateLandmarkItemLC()
       
  1035 // -----------------------------------------------------------------------------
       
  1036 //
       
  1037 CPosLandmark* CMyLocationsDatabaseManager::CreateLandmarkItemLC( const QLookupItem &aLookupItem )
       
  1038 {
       
  1039     __TRACE_CALLSTACK;//return value
       
  1040     CPosLandmark *landmark = NULL;
       
  1041     TLocality loc( TCoordinate( aLookupItem.mLatitude, aLookupItem.mLongitude ), 0 );
       
  1042 
       
  1043     landmark = CPosLandmark::NewL();
       
  1044     CleanupStack::PushL( landmark );
       
  1045 
       
  1046     // Fill the location details into the landmark object
       
  1047     landmark->SetPositionL( loc );
       
  1048 
       
  1049     // Set the landmark name as contact name
       
  1050     TBuf<KBufSize> text( aLookupItem.mName.utf16() );
       
  1051     TRAP_IGNORE( landmark->SetLandmarkNameL( text ) );
       
  1052 
       
  1053     text.Copy( aLookupItem.mStreet.utf16() );
       
  1054     landmark->SetPositionFieldL( EPositionFieldStreet, text );
       
  1055     
       
  1056     // Set the City
       
  1057     text.Copy( aLookupItem.mCity.utf16() );
       
  1058     landmark->SetPositionFieldL( EPositionFieldCity, text );
       
  1059 
       
  1060     // Set the state/region
       
  1061     text.Copy( aLookupItem.mState.utf16() );
       
  1062     landmark->SetPositionFieldL( EPositionFieldState, text );
       
  1063 
       
  1064     // Set the Postal code
       
  1065     text.Copy( aLookupItem.mPostalCode.utf16() );
       
  1066     landmark->SetPositionFieldL( EPositionFieldPostalCode, text );
       
  1067 
       
  1068     // Set the country
       
  1069     text.Copy( aLookupItem.mCountry.utf16() );
       
  1070     landmark->SetPositionFieldL( EPositionFieldCountry, text );
       
  1071 
       
  1072     return landmark;
       
  1073 }
       
  1074 
       
  1075 // -----------------------------------------------------------------------------
       
  1076 // CMyLocationsDatabaseManager::UpdateMapTilePath()
       
  1077 // -----------------------------------------------------------------------------
       
  1078 //
       
  1079 EXPORT_C void CMyLocationsDatabaseManager::UpdateMapTilePath( TUint32 aSourceId, TUint32 aSourceType, 
       
  1080                                             TFileName aFilePath )
       
  1081 {
       
  1082     QString filePath = QString( (QChar*)aFilePath.Ptr(), aFilePath.Length() );
       
  1083     iLocationAppLookupDb->updateMaptileBySourceIdAndType( aSourceId, aSourceType, filePath );
       
  1084 }
       
  1085 
       
  1086 // End of file