browserui/browser/FavouritesSrc/BrowserFavouritesModel.cpp
branchRCL_3
changeset 48 8e6fa1719340
equal deleted inserted replaced
47:6385c4c93049 48:8e6fa1719340
       
     1 /*
       
     2 * Copyright (c) 2002-2007 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 the License "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: 
       
    15 *      Implementation of CBrowserFavouritesModel.
       
    16 *      
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <StringLoader.h>
       
    23 #include <aknviewappui.h>
       
    24 #include <Avkon.hrh>
       
    25 #include <AknForm.h>    // This contains CAknDialog
       
    26 #include <AknQueryDialog.h>
       
    27 #include <favouritesdb.h>
       
    28 #include <favouritesitem.h>
       
    29 #include <favouritesitemlist.h>
       
    30 #include <favouriteslimits.h>
       
    31 #include <activefavouritesdbnotifier.h>
       
    32 #include <BrowserNG.rsg>
       
    33 
       
    34 #include "BrowserFavouritesModel.h"
       
    35 #include "BrowserFavouritesModelObserver.h"
       
    36 #include "BrowserUtil.h"
       
    37 #include "BrowserDialogs.h"
       
    38 #include <browserdialogsprovider.h>
       
    39 #include "BrowserFavouritesView.h"
       
    40 
       
    41 #include "Browser.hrh"
       
    42 
       
    43 #include <FeatMgr.h>
       
    44 #include <collate.h>         // TCollateMethod
       
    45 #include "CommonConstants.h"
       
    46 
       
    47 
       
    48 // MACROS
       
    49 
       
    50 /// Cosmetic purpose macro (resource names are overly too long).
       
    51 #define _R(str) R_BROWSER_FAVOURITES_ ## str
       
    52 
       
    53 /// Time to wait before retry database OpenL() or BeginL() (==0.2 secs).
       
    54 #ifdef KRetryWait
       
    55 #undef KRetryWait
       
    56 #endif
       
    57 #define KRetryWait 200 /*TTimeIntervalMicroSeconds32*/
       
    58 
       
    59 // CONSTANTS
       
    60 
       
    61 /// Granularity of observer array.
       
    62 LOCAL_C const TInt KGranularityObservers = 4;
       
    63 
       
    64 /// Number of attempts to retry after unsuccesful database OpenL() or BeginL().
       
    65 LOCAL_C const TInt KLocalRetryCount = 2;
       
    66 
       
    67 /**
       
    68 * Estimated number of bytes in FFS for one writing operation. This amount
       
    69 * is checked to be available before each transaction which places write-lock.
       
    70 * Exact size is not known (because what happens in a transaction is unknown).
       
    71 * A typical bookmark is estimated to be less than ~200 bytes; so assuming the
       
    72 * typical operation of adding one bookmark (with database transaction
       
    73 * overhead and safety) is estimated to be 400 bytes. This should be a safe
       
    74 * guess.
       
    75 */
       
    76 LOCAL_C const TInt KEstimatedFfsUsage = 400;
       
    77 
       
    78 // ==================== LOCAL FUNCTIONS ====================
       
    79 
       
    80 /**
       
    81 * Comparison function for two items.
       
    82 * Comparison rule:
       
    83 *   - Start Page is smaller than anything else;
       
    84 *   - otherwise, Homepage is smaller than anything else;
       
    85 *   - otherwise, Last Visited is smaller than anything else;
       
    86 *   - otherwise, any item is smaller than any folder;
       
    87 *   - otherwise, Root Folder is smaller than any other;
       
    88 *   - otherwise compare by name.
       
    89 * @param aLeft item to compare to aRight.
       
    90 * @param aRight Item to compare to aLeft.
       
    91 * @return
       
    92 *   - negative value, if aLeft is less than aRight;
       
    93 *   - 0,              if aLeft equals to aRight;
       
    94 *   - positive value, if aLeft is greater than aRight.
       
    95 */
       
    96 LOCAL_C TInt CompareItemsL
       
    97 ( const CFavouritesItem& aLeft, const CFavouritesItem& aRight )
       
    98     {
       
    99     // Start Page is smaller than anything else;
       
   100     if ( aLeft.Uid() == KFavouritesStartPageUid )
       
   101         {
       
   102         return -1;
       
   103         }
       
   104     if ( aRight.Uid() == KFavouritesStartPageUid )
       
   105         {
       
   106         return 1;
       
   107         }
       
   108     // otherwise, Adaptive Bookmarks is smaller than anything else;
       
   109     if ( aLeft.Uid() == KFavouritesAdaptiveItemsFolderUid )
       
   110         {
       
   111         return -1;
       
   112         }
       
   113     if ( aRight.Uid() == KFavouritesAdaptiveItemsFolderUid )
       
   114         {
       
   115         return 1;
       
   116         }
       
   117     // otherwise, Homepage is smaller than anything else;
       
   118     if ( aLeft.Uid() == KFavouritesHomepageUid )
       
   119         {
       
   120         return -1;
       
   121         }
       
   122     if ( aRight.Uid() == KFavouritesHomepageUid )
       
   123         {
       
   124         return 1;
       
   125         }
       
   126     // otherwise, Last Visited is smaller than anything else;
       
   127     if ( aLeft.Uid() == KFavouritesLastVisitedUid )
       
   128         {
       
   129         return -1;
       
   130         }
       
   131     if ( aRight.Uid() == KFavouritesLastVisitedUid )
       
   132         {
       
   133         return 1;
       
   134         }
       
   135     // otherwise, any item is smaller than any folder;
       
   136     if ( aLeft.IsItem() && aRight.IsFolder() )
       
   137         {
       
   138         return -1;
       
   139         }
       
   140     if ( aRight.IsItem() && aLeft.IsFolder() )
       
   141         {
       
   142         return 1;
       
   143         }
       
   144     // otherwise, Root Folder is smaller than any other;
       
   145     if ( aLeft.Uid() == KFavouritesRootUid )
       
   146         {
       
   147         return -1;
       
   148         }
       
   149 	// otherwise, Null ContextId is smaller than any ContextId;
       
   150 	if ( aLeft.ContextId() == KFavouritesNullContextId && aRight.ContextId() != KFavouritesNullContextId )
       
   151 		{
       
   152 		return -1;
       
   153 		}
       
   154 	if ( aRight.ContextId() == KFavouritesNullContextId && aLeft.ContextId() != KFavouritesNullContextId )
       
   155 		{
       
   156 		return 1;
       
   157 		}
       
   158     // otherwise compare by name.
       
   159     return aLeft.Name().CompareC( aRight.Name() );
       
   160     }
       
   161 
       
   162 // ================= MEMBER FUNCTIONS =======================
       
   163 
       
   164 // ---------------------------------------------------------
       
   165 // CBrowserFavouritesModel::~CBrowserFavouritesModel
       
   166 // ---------------------------------------------------------
       
   167 //
       
   168 CBrowserFavouritesModel::~CBrowserFavouritesModel()
       
   169 	{
       
   170     delete iNotifier;
       
   171     iNotifier = NULL;
       
   172     delete iObservers;
       
   173     CloseDb();
       
   174     iFavouritesSess.Close(); 
       
   175 	}
       
   176 
       
   177 // ---------------------------------------------------------
       
   178 // CBrowserFavouritesModel::SetNameToDefaultL
       
   179 // ---------------------------------------------------------
       
   180 //
       
   181 void CBrowserFavouritesModel::SetNameToDefaultL
       
   182 ( CFavouritesItem& aItem ) const
       
   183     {
       
   184     HBufC* name = CCoeEnv::Static()->AllocReadResourceLC
       
   185         ( StringResourceId( aItem, EDefaultName ) );
       
   186     aItem.SetNameL( *name );
       
   187     CleanupStack::PopAndDestroy();  // name
       
   188     }
       
   189 
       
   190 // ---------------------------------------------------------
       
   191 // CBrowserFavouritesModel::OpenDbL
       
   192 // ---------------------------------------------------------
       
   193 //
       
   194 TInt CBrowserFavouritesModel::OpenDbL( TBool aDbErrorNote /*=ETrue*/ )
       
   195     {
       
   196     TInt err = KErrNone;
       
   197 
       
   198     switch ( iState )
       
   199         {
       
   200         case EOpen:
       
   201             {
       
   202             // Already open.
       
   203             break;
       
   204             }
       
   205 
       
   206         case ECorrupt:
       
   207             {
       
   208             // Useless.
       
   209             err = KErrNotReady;
       
   210             break;
       
   211             }
       
   212 
       
   213         case EClosed:
       
   214             {
       
   215             // Try to open now.
       
   216             err = TimedOpenDbL();
       
   217             if ( err )
       
   218                 {
       
   219                 // Failed to open.
       
   220                 if ( aDbErrorNote )
       
   221                     {
       
   222                     TBrowserDialogs::ErrorNoteL
       
   223                         ( _R(TEXT_CANNOT_ACCESS_DB) );
       
   224                     }
       
   225                 }
       
   226             else
       
   227                 {
       
   228                 // Success opening.
       
   229                 iState = EOpen;
       
   230                 iNotifier->Start();
       
   231                 }
       
   232             break;
       
   233             }
       
   234 
       
   235         default:
       
   236             {
       
   237             break;
       
   238             }
       
   239         }
       
   240 
       
   241     return err;
       
   242     }
       
   243 
       
   244 // ---------------------------------------------------------
       
   245 // CBrowserFavouritesModel::CloseDb
       
   246 // ---------------------------------------------------------
       
   247 //
       
   248 void CBrowserFavouritesModel::CloseDb()
       
   249 	{
       
   250     if ( iNotifier )
       
   251         {
       
   252         // Need to check existence - ConstructL can leave half the way!
       
   253         iNotifier->Cancel();
       
   254         }
       
   255     if ( iState == EOpen )
       
   256         {
       
   257         iDb.Close();
       
   258         }
       
   259     iState = EClosed;
       
   260 	}
       
   261 
       
   262 // ---------------------------------------------------------
       
   263 // CBrowserFavouritesModel::BeginL
       
   264 // ---------------------------------------------------------
       
   265 //
       
   266 TInt CBrowserFavouritesModel::BeginL
       
   267 ( TBool aWrite, TBool aDbErrorNote, TBool aLffsCheck /*=ETrue*/ )
       
   268     {
       
   269     TInt err;
       
   270 
       
   271     // Before attempting db modification, check if we would go below Critical
       
   272     // Level in FFS (disk). The value used for checking is an estimate.
       
   273     // Reading the db also allocates some bytes (transaction log), but
       
   274     // this is not estimated and not checked, because it should be small
       
   275     // enough, and would slow down operation. (Typical use is to read a lot
       
   276     // and write much less.)
       
   277     if (
       
   278             aLffsCheck &&
       
   279             aWrite &&
       
   280             Util::FFSSpaceBelowCriticalLevelL
       
   281                 ( /*aShowErrorNote=*/aDbErrorNote, KEstimatedFfsUsage )
       
   282        )
       
   283         {
       
   284         err = KErrDiskFull;
       
   285         return err;
       
   286         }
       
   287 
       
   288     // Open database.
       
   289     err = OpenDbL( /*aDbErrorNote=*/EFalse ); // Error note (if any) is here.
       
   290     // Start a transaction.
       
   291     if ( !err )
       
   292         {
       
   293         err = TimedBeginL( aWrite );
       
   294         }
       
   295 
       
   296     if ( err && aDbErrorNote )
       
   297         {
       
   298         TBrowserDialogs::ErrorNoteL( _R(TEXT_CANNOT_ACCESS_DB) );
       
   299         }
       
   300 
       
   301     return err;
       
   302     }
       
   303 
       
   304 // ---------------------------------------------------------
       
   305 // CBrowserFavouritesModel::CommitL
       
   306 // ---------------------------------------------------------
       
   307 //
       
   308 void CBrowserFavouritesModel::CommitL()
       
   309     {
       
   310     iDb.Commit();
       
   311     CleanupStack::Pop();  // DO NOT remove this hack.
       
   312     }
       
   313 
       
   314 // ---------------------------------------------------------
       
   315 // CBrowserFavouritesModel::AddObserverL
       
   316 // ---------------------------------------------------------
       
   317 //
       
   318 void CBrowserFavouritesModel::AddObserverL
       
   319 ( MBrowserFavouritesModelObserver& aObserver )
       
   320     {
       
   321     iObservers->AppendL( &aObserver );
       
   322     }
       
   323 
       
   324 // ---------------------------------------------------------
       
   325 // CBrowserFavouritesModel::RemoveObserver
       
   326 // ---------------------------------------------------------
       
   327 //
       
   328 void CBrowserFavouritesModel::RemoveObserver
       
   329 ( MBrowserFavouritesModelObserver& aObserver )
       
   330     {
       
   331     TInt i;
       
   332     TInt count = iObservers->Count();
       
   333     for ( i = 0; i < count; i++ )
       
   334         {
       
   335         if ( iObservers->At( i ) == &aObserver )
       
   336             {
       
   337             iObservers->Delete( i );
       
   338             return;
       
   339             }
       
   340         }
       
   341     }
       
   342 
       
   343 // ---------------------------------------------------------
       
   344 // CBrowserFavouritesModel::AddL
       
   345 // ---------------------------------------------------------
       
   346 //
       
   347 TInt CBrowserFavouritesModel::AddL
       
   348         (
       
   349         CFavouritesItem& aItem,
       
   350         TBool aDbErrorNote,
       
   351         CBrowserFavouritesModel::TRenameMode aRenameMode /*=EAskIfRename*/
       
   352         )
       
   353     {
       
   354     return AddUpdateL( aItem, KFavouritesNullUid, aDbErrorNote, aRenameMode );
       
   355     }
       
   356 
       
   357 // ---------------------------------------------------------
       
   358 // CBrowserFavouritesModel::UpdateL
       
   359 // ---------------------------------------------------------
       
   360 //
       
   361 TInt CBrowserFavouritesModel::UpdateL
       
   362         (
       
   363         CFavouritesItem& aItem,
       
   364         TInt aUid,
       
   365         TBool aDbErrorNote,
       
   366         CBrowserFavouritesModel::TRenameMode aRenameMode /*=EAskIfRename*/
       
   367         )
       
   368     {
       
   369     return AddUpdateL( aItem, aUid, aDbErrorNote, aRenameMode );
       
   370     }
       
   371 
       
   372 // ---------------------------------------------------------
       
   373 // CBrowserFavouritesModel::SetHomepageL
       
   374 // ---------------------------------------------------------
       
   375 //
       
   376 TInt CBrowserFavouritesModel::SetHomepageL
       
   377         (
       
   378         CFavouritesItem& aItem,
       
   379         TBool aDbErrorNote,
       
   380         CBrowserFavouritesModel::TRenameMode aRenameMode /*=EAskIfRename*/
       
   381         )
       
   382     {
       
   383     return AddUpdateL
       
   384         ( aItem, KFavouritesHomepageUid, aDbErrorNote, aRenameMode );
       
   385     }
       
   386 
       
   387 // ---------------------------------------------------------
       
   388 // CBrowserFavouritesModel::SetLastVisitedL
       
   389 // ---------------------------------------------------------
       
   390 //
       
   391 TInt CBrowserFavouritesModel::SetLastVisitedL
       
   392         (
       
   393         CFavouritesItem& aItem,
       
   394         TBool aDbErrorNote,
       
   395         CBrowserFavouritesModel::TRenameMode aRenameMode /*=EAskIfRename*/
       
   396         )
       
   397     {
       
   398     return AddUpdateL
       
   399         ( aItem, KFavouritesLastVisitedUid, aDbErrorNote, aRenameMode );
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------
       
   403 // CBrowserFavouritesModel::AnyFoldersL
       
   404 // ---------------------------------------------------------
       
   405 //
       
   406 CBrowserFavouritesModel::TDbQuery CBrowserFavouritesModel::AnyFoldersL()
       
   407     {
       
   408     TDbQuery ret = EError;
       
   409     if ( BeginL( /*aWrite=*/EFalse, /*aDbErrorNote=*/ETrue ) == KErrNone )
       
   410         {
       
   411         TInt count = 0;
       
   412         if ( iDb.Count( count, KFavouritesRootUid, CFavouritesItem::EFolder )
       
   413                                                                 == KErrNone )
       
   414             {
       
   415             ret = count ? EYes : ENo;
       
   416             }
       
   417         CommitL();
       
   418         }
       
   419     return ret;
       
   420     }
       
   421 
       
   422 // ---------------------------------------------------------
       
   423 // CBrowserFavouritesModel::AnyNonEmptyFoldersL
       
   424 // ---------------------------------------------------------
       
   425 //
       
   426 CBrowserFavouritesModel::TDbQuery
       
   427 CBrowserFavouritesModel::AnyNonEmptyFoldersL( CArrayFix<TInt>& aUids )
       
   428     {
       
   429     TDbQuery ret = EError;
       
   430     if ( BeginL( /*aWrite=*/EFalse, /*aDbErrorNote=*/ETrue ) == KErrNone )
       
   431         {
       
   432         ret = ENo;
       
   433         TInt itemCount;
       
   434         TInt i;
       
   435         TInt uidCount = aUids.Count();
       
   436         for ( i = 0; i < uidCount; i++ )
       
   437             {
       
   438             if ( iDb.Count( itemCount, aUids.At( i ) ) == KErrNone )
       
   439                 {
       
   440                 if ( itemCount )
       
   441                     {
       
   442                     // We have a non-empty folder.
       
   443                     ret = EYes;
       
   444                     break;
       
   445                     }
       
   446                 }
       
   447             else
       
   448                 {
       
   449                 // Error querying; quit.
       
   450                 ret = EError;
       
   451                 break;
       
   452                 }
       
   453             }
       
   454         CommitL();
       
   455         }
       
   456     return ret;
       
   457     }
       
   458 
       
   459 // ---------------------------------------------------------
       
   460 // CBrowserFavouritesModel::FolderInfoL
       
   461 // ---------------------------------------------------------
       
   462 //
       
   463 TInt CBrowserFavouritesModel::FolderInfoL
       
   464 ( TInt aFolder, TInt& aFolderCount, TInt& aFolderIndex )
       
   465     {
       
   466     TInt err = KErrNotFound;
       
   467     
       
   468     if(iApiProvider.CalledFromAnotherApp())
       
   469         {
       
   470         err = KErrNone;
       
   471         aFolderIndex = 0;
       
   472         aFolderCount = 1;
       
   473         return err;
       
   474         }
       
   475     
       
   476     CFavouritesItemList* folders = GetFoldersSortedLC();
       
   477     // Iterate until we find the folder.
       
   478     TInt i;
       
   479     TInt actualCount = 0;
       
   480     aFolderCount = actualCount = folders->Count();
       
   481     for ( i = 0; i < actualCount; i++ )
       
   482         {
       
   483         if(folders->At( i )->IsHidden())
       
   484             {
       
   485                 aFolderCount--;
       
   486             }
       
   487         if ( folders->At( i )->Uid() == aFolder )
       
   488             {
       
   489             aFolderIndex = i;
       
   490             err = KErrNone;
       
   491             }
       
   492         }
       
   493     if(aFolderIndex > aFolderCount)
       
   494         {
       
   495             aFolderIndex += (aFolderCount - actualCount);
       
   496         }
       
   497     CleanupStack::PopAndDestroy();  // folders
       
   498     return err;
       
   499     }
       
   500 
       
   501 // ---------------------------------------------------------
       
   502 // CBrowserFavouritesModel::NextFolderL
       
   503 // ---------------------------------------------------------
       
   504 //
       
   505 TInt CBrowserFavouritesModel::NextFolderL( TInt aFolder, TBool aForward )
       
   506     {
       
   507     if ( AknLayoutUtils::LayoutMirrored() )
       
   508         {
       
   509         aForward = !aForward;
       
   510         }
       
   511     TInt folder = KFavouritesNullUid;
       
   512     
       
   513     if(iApiProvider.CalledFromAnotherApp())
       
   514         {
       
   515         return folder;
       
   516         }
       
   517     
       
   518     CFavouritesItemList* folders = GetFoldersSortedLC();
       
   519     // Iterate until we find the folder.
       
   520     TInt i;
       
   521     TInt count = folders->Count();
       
   522     for ( i = 0; i < count; i++ )
       
   523         {
       
   524         if ( folders->At( i )->Uid() == aFolder )
       
   525             {
       
   526             i += aForward ? 1 : -1;
       
   527             if ( i >= 0 && i < count )
       
   528                 {
       
   529                 // Have the neighbour.
       
   530                 folder = folders->At( i )->Uid();
       
   531                 
       
   532                 while(folders->At( i )->IsHidden())
       
   533                     {
       
   534                     i += aForward ? 1 : -1;
       
   535                     if ( i < 0 || i >= count )
       
   536                         {
       
   537                         folder = KFavouritesNullUid;
       
   538                         break;
       
   539                         }
       
   540                      else
       
   541                         {
       
   542                         // Have the neighbour.
       
   543                         folder = folders->At( i )->Uid();
       
   544                         }
       
   545                     }
       
   546                 }
       
   547             break;
       
   548             }
       
   549         }
       
   550     CleanupStack::PopAndDestroy();  // folders
       
   551     return folder;
       
   552     }
       
   553 
       
   554 // ---------------------------------------------------------
       
   555 // CBrowserFavouritesModel::RenameQueryL
       
   556 // ---------------------------------------------------------
       
   557 //
       
   558 TBool CBrowserFavouritesModel::RenameQueryL( CFavouritesItem& aItem, TBool aNewItem )
       
   559     {
       
   560     TBool ret = EFalse;
       
   561     TBuf<KFavouritesMaxName> buf = aItem.Name();
       
   562     CAknTextQueryDialog* dialog = CAknTextQueryDialog::NewL( buf );
       
   563     dialog->PrepareLC( _R(NAME_QUERY_OK_CANCEL) );
       
   564     dialog->SetPredictiveTextInputPermitted(ETrue);
       
   565     HBufC* prompt;
       
   566     if ( aNewItem )
       
   567         {
       
   568         prompt =
       
   569             StringLoader::LoadLC( StringResourceId( aItem, ENewPrompt ) );
       
   570         }
       
   571     else
       
   572         {
       
   573         prompt =
       
   574             StringLoader::LoadLC( StringResourceId( aItem, ERenamePrompt ) );
       
   575         }
       
   576     dialog->SetPromptL( *prompt );
       
   577     CleanupStack::PopAndDestroy();  // prompt
       
   578     TInt button = dialog->RunLD();
       
   579     if ( button )
       
   580         {
       
   581         aItem.SetNameL( buf.Left(KFavouritesMaxName) );
       
   582         ret = ETrue;
       
   583         }
       
   584     return ret;
       
   585     }
       
   586 
       
   587 // ---------------------------------------------------------
       
   588 // CBrowserFavouritesModel::SortL
       
   589 // ---------------------------------------------------------
       
   590 //
       
   591 void CBrowserFavouritesModel::SortL( CFavouritesItemList& aList )
       
   592     {
       
   593     TBuf<KFavouritesMaxName> name;
       
   594     TInt i;
       
   595     TInt count = aList.Count();
       
   596 
       
   597     TInt resId = 0;
       
   598 
       
   599     for ( i = 0; i < count; i++ )
       
   600         {
       
   601         resId = CBrowserFavouritesView::GetSeamlessFolderResourceID( 
       
   602         			aList.At(i)->ContextId() );
       
   603         
       
   604         if(resId) // a seamless link folder. Get the localised name.
       
   605             {
       
   606             HBufC* seamlessLinkName = CCoeEnv::Static()->AllocReadResourceLC( resId );
       
   607             name = seamlessLinkName->Des();
       
   608             CleanupStack::PopAndDestroy(); // seamlessLinkName
       
   609 			aList.At( i )->SetNameL( name );
       
   610             }
       
   611 		}
       
   612 
       
   613     aList.SortL( &CompareItemsL );
       
   614     }
       
   615 
       
   616 // ---------------------------------------------------------
       
   617 // CBrowserFavouritesModel::MakeUniqueNameL
       
   618 // ---------------------------------------------------------
       
   619 //
       
   620 TInt CBrowserFavouritesModel::MakeUniqueNameL
       
   621 ( CFavouritesItem& aItem )
       
   622     {
       
   623     TInt err = BeginL( /*aWrite=*/EFalse, /*aDbErrorNote=*/ETrue );
       
   624     if ( !err )
       
   625         {
       
   626         err = iDb.MakeUniqueName( aItem );
       
   627         CommitL();
       
   628         }
       
   629     return err;
       
   630     }
       
   631 
       
   632 // ---------------------------------------------------------
       
   633 // CBrowserFavouritesModel::HandleFavouritesDbEventL
       
   634 // ---------------------------------------------------------
       
   635 //
       
   636 void CBrowserFavouritesModel::HandleFavouritesDbEventL
       
   637 ( RDbNotifier::TEvent aEvent )
       
   638     {
       
   639     switch ( aEvent )
       
   640         {
       
   641         case RDbNotifier::ECommit:
       
   642             {
       
   643             // Database has changed, notify observers.
       
   644             NotifyObserversL();
       
   645             break;
       
   646             }
       
   647 
       
   648         case RDbNotifier::ERollback:
       
   649             {
       
   650             // Database corrupted, close now and wait until everyone closes it.
       
   651             iState = ECorrupt;
       
   652             iDb.Close();
       
   653             // But keep the notifier alive.
       
   654             break;
       
   655             }
       
   656 
       
   657         case RDbNotifier::EClose:
       
   658             {
       
   659             // Database is closed by all clients.
       
   660             if ( iState == ECorrupt )
       
   661                 {
       
   662                 // Database was closed by the model (by damage), not the user.
       
   663                 // Try to reopen it now; that will recover it.
       
   664                 iState = EClosed;
       
   665                 iNotifier->Cancel();
       
   666                 if ( OpenDbL( /*aDbErrorNote=*/EFalse ) == KErrNone )
       
   667                     {
       
   668                     // Succesfully reopened. Data may have changed.
       
   669                     NotifyObserversL();
       
   670                     }
       
   671                 }
       
   672             break;
       
   673             }
       
   674 
       
   675 		default:
       
   676             {
       
   677 			break;
       
   678             }
       
   679         }
       
   680     }
       
   681 
       
   682 // ---------------------------------------------------------
       
   683 // CBrowserFavouritesModel::CBrowserFavouritesModel
       
   684 // ---------------------------------------------------------
       
   685 //
       
   686 CBrowserFavouritesModel::CBrowserFavouritesModel( MApiProvider& aApiProvider )
       
   687 	:
       
   688 	iApiProvider( aApiProvider )
       
   689 	{
       
   690     iState = EClosed;
       
   691 	}
       
   692 
       
   693 // ---------------------------------------------------------
       
   694 // CBrowserFavouritesModel::ConstructL
       
   695 // ---------------------------------------------------------
       
   696 //
       
   697 void CBrowserFavouritesModel::ConstructL()
       
   698 	{
       
   699     iObservers = new (ELeave) CArrayPtrFlat<MBrowserFavouritesModelObserver>
       
   700         ( KGranularityObservers );
       
   701     iNotifier = new (ELeave) CActiveFavouritesDbNotifier( iDb, *this );
       
   702     User::LeaveIfError( iFavouritesSess.Connect() );
       
   703 	}
       
   704 
       
   705 // ---------------------------------------------------------
       
   706 // CBrowserFavouritesModel::TimedOpenDbL
       
   707 // ---------------------------------------------------------
       
   708 //
       
   709 TInt CBrowserFavouritesModel::TimedOpenDbL()
       
   710     {
       
   711     TInt retriesLeft = KLocalRetryCount;
       
   712     TInt err = ( iDb.Open( iFavouritesSess, GetDBName() ));
       
   713     while ( err && retriesLeft-- )
       
   714         {        
       
   715         User::After( KRetryWait );
       
   716         err = ( iDb.Open( iFavouritesSess, GetDBName() ));
       
   717         }
       
   718     return err;
       
   719     }
       
   720     
       
   721 // ---------------------------------------------------------
       
   722 // CBrowserFavouritesModel::GetDBName
       
   723 // ---------------------------------------------------------
       
   724 //
       
   725 const TDesC& CBrowserFavouritesModel::GetDBName()
       
   726     {
       
   727     //should be overridden by bookmarks model
       
   728     return KBrowserSavedPages; //default value
       
   729     }
       
   730 
       
   731 // ---------------------------------------------------------
       
   732 // CBrowserFavouritesModel::TimedBeginL
       
   733 // ---------------------------------------------------------
       
   734 //
       
   735 TInt CBrowserFavouritesModel::TimedBeginL( TBool /*aWrite*/ )
       
   736     {
       
   737     TInt retriesLeft = KLocalRetryCount;
       
   738     TInt err =  iDb.Begin();
       
   739     if ( err == KErrNone )
       
   740         {
       
   741         iDb.CleanupRollbackPushL();  
       
   742         }
       
   743     while ( err && retriesLeft-- )
       
   744         {
       
   745         err = iDb.Begin() ;
       
   746         if ( err == KErrNone )
       
   747             {
       
   748             iDb.CleanupRollbackPushL();  
       
   749             }
       
   750         }
       
   751     return err;
       
   752     }
       
   753 
       
   754 // ---------------------------------------------------------
       
   755 // CBrowserFavouritesModel::AddUpdateL
       
   756 // ---------------------------------------------------------
       
   757 //
       
   758 TInt CBrowserFavouritesModel::AddUpdateL
       
   759         (
       
   760         CFavouritesItem& aItem,
       
   761         TInt aUid,
       
   762         TBool aDbErrorNote,
       
   763         TRenameMode aRenameMode
       
   764         )
       
   765     {
       
   766     TBool done = EFalse;
       
   767     TInt err = KErrNone;
       
   768 
       
   769     while ( !done )
       
   770         {
       
   771         err = BeginL( /*aWrite=*/ETrue, aDbErrorNote );
       
   772         if ( err )
       
   773             {
       
   774             // Database error.
       
   775             done = ETrue;
       
   776             }
       
   777         else
       
   778             {
       
   779             // Database OK, try to add/update item...
       
   780             switch ( aUid )
       
   781                 {
       
   782                     {
       
   783                 case KFavouritesHomepageUid:
       
   784                     // Homepage update.
       
   785                     err = iDb.SetHomepage( aItem );
       
   786                     break;
       
   787                     }
       
   788 
       
   789                 case KFavouritesLastVisitedUid:
       
   790                     {
       
   791                     // Last Visited update.
       
   792                     err = iDb.SetLastVisited( aItem );
       
   793                     break;
       
   794                     }
       
   795 
       
   796                 case KFavouritesNullUid:
       
   797                 default: 
       
   798                     {
       
   799                     // Check first if the item added has the same name as any of the special folders
       
   800                     
       
   801                     TBool itemExists = EFalse;
       
   802                     if (aItem.Type() == CFavouritesItem::EFolder)
       
   803                         {   
       
   804                         #ifdef __RSS_FEEDS
       
   805                         HBufC* webFeedsBuf = StringLoader::LoadLC( R_BROWSER_APPS_FEEDS_LIST );
       
   806                         TPtrC webFeeds = webFeedsBuf->Des();
       
   807                         if(CompareIgnoreCase(aItem.Name(),webFeeds))
       
   808                             {
       
   809                             itemExists = ETrue;
       
   810                             }
       
   811                         CleanupStack::PopAndDestroy(); 
       
   812                         #endif
       
   813                         
       
   814                		    if ( ( ADAPTIVEBOOKMARKS ) &&
       
   815                             ( iApiProvider.Preferences().AdaptiveBookmarks() ==
       
   816                                             EWmlSettingsAdaptiveBookmarksOn ))
       
   817                		        {
       
   818                		        HBufC* recentUrlsBuf = StringLoader::LoadLC( R_BROWSER_ADAPTIVE_BOOKMARKS_FOLDER);
       
   819                             TPtrC recentUrls = recentUrlsBuf->Des();
       
   820                             if(CompareIgnoreCase(aItem.Name(),recentUrls))
       
   821                                 {
       
   822                                 itemExists = ETrue;
       
   823                                 }
       
   824                             CleanupStack::PopAndDestroy(); 
       
   825                		        }
       
   826                         }
       
   827                     
       
   828                       if (( itemExists ) && (aItem.Type() == CFavouritesItem::EFolder))
       
   829                         {
       
   830                         err = KErrAlreadyExists;
       
   831                         }
       
   832                     else
       
   833                         {
       
   834                         // New item addition.
       
   835                         if ( aUid == KFavouritesNullUid)
       
   836                             err = iDb.Add( aItem, aRenameMode == EAutoRename );
       
   837                         else  // Existing item update.
       
   838                             err = iDb.Update( aItem, aUid, aRenameMode == EAutoRename );                            
       
   839                         }
       
   840                     break;
       
   841                     }
       
   842                 }
       
   843             CommitL();
       
   844             
       
   845             // ...and see the outcome.
       
   846             switch( err )
       
   847                 {
       
   848                 case KErrNone:
       
   849                     {
       
   850                     // All is well.
       
   851                     done = ETrue;
       
   852                     break;
       
   853                     }
       
   854                 case KErrAlreadyExists:
       
   855                     {
       
   856                     // The name is conflicting.
       
   857                     switch ( aRenameMode )
       
   858                         {
       
   859                         case EAutoRename:
       
   860                             {
       
   861                             // We should never get here;
       
   862                             // this is handled by the Engine's AutoRename.
       
   863                             __ASSERT_DEBUG( EFalse, Util::Panic\
       
   864                                 ( Util::EFavouritesInternal ) );
       
   865                             done = ETrue;
       
   866                             break;
       
   867                             }
       
   868                         case EDontRename:
       
   869                             {
       
   870                             // No rename is needed.
       
   871                             // Return with KErrAlreadyExists.
       
   872                             done = ETrue;
       
   873                             break;
       
   874                             }
       
   875                         case EAskIfRename:
       
   876                         default:
       
   877                             {
       
   878                             // Prompt the user for new name.
       
   879                             // Retry with new name, or return if Cancelled.
       
   880 							TBrowserDialogs::InfoNoteL
       
   881 											(
       
   882 											R_BROWSER_INFO_NOTE,
       
   883 											_R(TEXT_FLDR_NAME_ALREADY_USED),
       
   884 											aItem.Name()
       
   885 											);
       
   886                             done = !RenameQueryL( aItem, EFalse );
       
   887                             break;
       
   888                             }
       
   889                         }
       
   890                     break;
       
   891                     }
       
   892                 case KErrPathNotFound:
       
   893                     {
       
   894                     // The name is conflicting.
       
   895                     switch ( aRenameMode )
       
   896                         {
       
   897                         case EAutoRename:
       
   898                             {
       
   899                             // We should never get here;
       
   900                             // this is handled by the Engine's AutoRename.
       
   901                             __ASSERT_DEBUG( EFalse, Util::Panic\
       
   902                                 ( Util::EFavouritesInternal ) );
       
   903                             done = ETrue;
       
   904                             break;
       
   905                             }
       
   906                         case EDontRename:
       
   907                             {
       
   908                             // No rename is needed.
       
   909                             // Return with KErrAlreadyExists.
       
   910                             done = ETrue;
       
   911                             break;
       
   912                             }
       
   913                         case EAskIfRename:
       
   914                         default:
       
   915                             {
       
   916                             // Prompt the user for new name.
       
   917                             // Retry with new name, or return if Cancelled.
       
   918 							TBrowserDialogs::InfoNoteL
       
   919 												(
       
   920 												R_BROWSER_INFO_NOTE,
       
   921 												_R( TEXT_PRMPT_ILLEGAL_CHAR ),
       
   922 												aItem.Name()
       
   923 												);							
       
   924                             done = !RenameQueryL( aItem, EFalse );
       
   925                             break;
       
   926                             }
       
   927                         }
       
   928                     break;
       
   929 					}
       
   930                     
       
   931                 case KErrNotFound:
       
   932                     {
       
   933                     // Update leaved with KErrNotFound meaning someone deleted entry while it was edited
       
   934                     // Add entry as new item instead.
       
   935                     if (aUid != KFavouritesNullUid)
       
   936                         {
       
   937                         aUid = KFavouritesNullUid;
       
   938                         }
       
   939                     break;
       
   940                     }
       
   941                     
       
   942                 default:
       
   943                     {
       
   944                     // Some error; quit.
       
   945                     done = ETrue;
       
   946                     break;
       
   947                     }
       
   948                 }
       
   949             }
       
   950         }
       
   951     return err;
       
   952     }
       
   953 
       
   954 // ---------------------------------------------------------
       
   955 // CBrowserFavouritesModel::GetFoldersSortedLC
       
   956 // ---------------------------------------------------------
       
   957 //
       
   958 CFavouritesItemList* CBrowserFavouritesModel::GetFoldersSortedLC()
       
   959     {
       
   960     CFavouritesItemList* folders = new (ELeave) CFavouritesItemList();
       
   961     CleanupStack::PushL( folders );
       
   962     // Get all folders.
       
   963     iDb.GetAll( *folders, KFavouritesRootUid, CFavouritesItem::EFolder );
       
   964      // Sort folders,
       
   965     folders->SortL( &CompareItemsL );
       
   966     return folders;
       
   967     }
       
   968 
       
   969 // ---------------------------------------------------------
       
   970 // CBrowserFavouritesModel::NotifyObserversL
       
   971 // ---------------------------------------------------------
       
   972 //
       
   973 void CBrowserFavouritesModel::NotifyObserversL()
       
   974     {
       
   975     TInt i;
       
   976     TInt count = iObservers->Count();
       
   977     for ( i = 0; i < count; i++ )
       
   978         {
       
   979         iObservers->At( i )->HandleFavouritesModelChangeL();
       
   980         }
       
   981     }
       
   982 
       
   983 // ---------------------------------------------------------
       
   984 // CBrowserBookmarksModel::ManualSortL
       
   985 // ---------------------------------------------------------
       
   986 //
       
   987 void CBrowserFavouritesModel::ManualSortL(TInt aFolder, CBrowserBookmarksOrder* aBMOrder, CArrayFixFlat<TInt>* aOrderArray, CFavouritesItemList* aItems)
       
   988     {
       
   989     if ( Database().GetData( aFolder ,*aBMOrder ) == KErrNone)
       
   990         {
       
   991         if( aOrderArray->Count() )
       
   992             {
       
   993             TInt swapTo = 0;
       
   994             CFavouritesItem* swappedItem = CFavouritesItem::NewL();
       
   995             CleanupStack::PushL(swappedItem);
       
   996             for ( TInt i=0; i<aOrderArray->Count();i++ )    
       
   997                 {
       
   998                 TInt swapFrom = aItems->UidToIndex( ( *aOrderArray )[i] );
       
   999                 if (swapFrom != KErrNotFound)
       
  1000                     {
       
  1001                     if ((swapFrom != swapTo) && (swapTo < aItems->Count() ) )
       
  1002                         {
       
  1003                         (*swappedItem) = *( *aItems )[swapFrom];
       
  1004                         *( *aItems )[swapFrom] = *( *aItems )[swapTo];
       
  1005                         *( *aItems )[swapTo] = (*swappedItem);
       
  1006                         }
       
  1007                     swapTo++;
       
  1008                     }
       
  1009                 }
       
  1010             CleanupStack::PopAndDestroy(swappedItem);
       
  1011             }
       
  1012         else
       
  1013             {
       
  1014               SortL(*aItems);
       
  1015             }
       
  1016         }
       
  1017     else
       
  1018         {
       
  1019         SortL(*aItems);
       
  1020         }
       
  1021     }
       
  1022 
       
  1023 // ---------------------------------------------------------
       
  1024 // CBrowserFavouritesModel::AddUidToLastPlaceL
       
  1025 // ---------------------------------------------------------
       
  1026 //
       
  1027 void CBrowserFavouritesModel::AddUidToLastPlaceL(
       
  1028         TInt aUid,
       
  1029         CArrayFixFlat<TInt>* aOrderArray,
       
  1030         CBrowserBookmarksOrder* aCurrentOrder )
       
  1031     {
       
  1032     if( aCurrentOrder )
       
  1033         {
       
  1034         TInt index(0);
       
  1035         if( aOrderArray->Count() )
       
  1036             {
       
  1037            	index = aOrderArray->Count();
       
  1038             }
       
  1039         aOrderArray->InsertL( index , aUid );
       
  1040         }
       
  1041     }
       
  1042 
       
  1043 // ---------------------------------------------------------
       
  1044 // CBrowserFavouritesModel::OpenFavouritesFile
       
  1045 // ---------------------------------------------------------
       
  1046 //
       
  1047 
       
  1048 TInt CBrowserFavouritesModel::OpenFavouritesFile ( RFavouritesFile & aFavFile, TInt aUid )
       
  1049 {
       
  1050 return aFavFile.Open( iDb, aUid );
       
  1051 }
       
  1052 
       
  1053 // ---------------------------------------------------------
       
  1054 // CBrowserFavouritesModel::ReplaceFavouritesFile
       
  1055 // ---------------------------------------------------------
       
  1056 //
       
  1057 
       
  1058 TInt CBrowserFavouritesModel::ReplaceFavouritesFile ( RFavouritesFile & aFavFile, TInt aUid )
       
  1059 {
       
  1060 return aFavFile.Replace( iDb, aUid );
       
  1061 }
       
  1062 
       
  1063 // ---------------------------------------------------------------------------
       
  1064 // CBrowserFavouritesModel::CompareIgnoreCase
       
  1065 // Compare two descriptors
       
  1066 // ---------------------------------------------------------------------------
       
  1067 //
       
  1068 TBool CBrowserFavouritesModel::CompareIgnoreCase( const TDesC& aFirst, 
       
  1069                                       const TDesC& aSecond )
       
  1070     {
       
  1071     // Get the standard method
       
  1072     TCollationMethod meth = *Mem::CollationMethodByIndex( 0 );
       
  1073     meth.iFlags |= TCollationMethod::EFoldCase;
       
  1074     meth.iFlags |= TCollationMethod::EIgnoreNone;
       
  1075 
       
  1076     // Magic: Collation level 3 is used
       
  1077     return aFirst.CompareC( aSecond, 3, &meth ) == 0;
       
  1078     }
       
  1079 
       
  1080 
       
  1081 // End of File