notepad/notepad1/LibSrc/NpdModel.cpp
changeset 89 b57382753122
child 67 1539a383d7b6
equal deleted inserted replaced
83:5aadd1120515 89:b57382753122
       
     1 /*
       
     2 * Copyright (c) 2002 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:  Implementation of Notepad engine.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include <gulutil.h>
       
    22 #include <sysutil.h>
       
    23 #include <eikenv.h>
       
    24 #include <barsread.h>
       
    25 #include "NpdLib.hrh"
       
    26 #include "NpdModel_platsec.h"
       
    27 #include "NpdApi.h"
       
    28 #include "NpdLibPanic.h"
       
    29 #include "AknUtils.h"
       
    30 
       
    31 // CONSTANTS
       
    32 _LIT(KNotepadMceFirstColumnData, "1");
       
    33 _LIT(KNotepadSqlSelect, 
       
    34     "SELECT * FROM Table1 ORDER BY time DESC");
       
    35 _LIT(KNotepadSqlMceSelect, 
       
    36     "SELECT * FROM Table1 ORDER BY memo ASC,key DESC");
       
    37 _LIT(KNotepadSqlDeleteByKeysAppend, " OR key="); // 8 chars
       
    38 const TInt KNotepadSqlDeleteByKeysAppendSize(18); // %d costs 10 chars in max
       
    39 const TInt KNotepadItemArrayGranularity(10);
       
    40 const TInt KNotepadMaxRunIntervalInMicroSeconds(500000); // 0.5 sec
       
    41 const TInt KNotepadBuildItemArrayProgressCount(10);
       
    42 const TInt KNotepadMaxDeleteCountInStep(300);
       
    43 const TInt KNotepadDiskSpaceNeededForMultipleDeletion(8192);
       
    44 const TInt KNotepadMaxCharactersForSort(100);
       
    45 
       
    46 // assert KNotepadListEntryLength >= KNotepadMaxCharactersForSort + length of
       
    47 //     1st column
       
    48 const TInt KNotepadListEntryLength( 60 ); 
       
    49 
       
    50 // ============================ MEMBER FUNCTIONS ===============================
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CNotepadModel::NewL
       
    54 // Constructor.
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 EXPORT_C CNotepadModel* CNotepadModel::NewL(RFs& /*aFs*/, TInt aResId)
       
    58     {
       
    59     CNotepadModel* self = new(ELeave) CNotepadModel();
       
    60     CleanupStack::PushL(self);
       
    61     self->ConstructL(aResId);
       
    62     CleanupStack::Pop(); //self
       
    63     return self;
       
    64     }
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CNotepadModel::~CNotepadModel
       
    68 // Destructor.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 EXPORT_C CNotepadModel::~CNotepadModel()
       
    72     {
       
    73     delete iDatabaseChangeNotifier;
       
    74     delete iExecuter;
       
    75     iSavedDeleteKeys.Close();
       
    76     iDbUpdate.Close();
       
    77     iDbView.Close();
       
    78     iKeyArray.Close(); //delete iKeyArray;
       
    79     delete iItemArray;
       
    80     delete iTimeFormat;
       
    81     delete iDateFormat;
       
    82     if ( iFixedFirstNote )
       
    83     	{
       
    84         delete iFixedFirstNote;
       
    85     	}    
       
    86     }
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // CNotepadModel::AddContentL
       
    90 // API. CNotepadApi call this.
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 EXPORT_C void CNotepadModel::AddContentL(const TDesC& aText)
       
    94     {
       
    95     TInt key(KNotepadPseudoKeyIdForNewNote);
       
    96     InsertL(aText, key);
       
    97     }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // CNotepadModel::OpenL
       
   101 // deprecated. (only for BC).
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 EXPORT_C void CNotepadModel::OpenL()
       
   105     {
       
   106     }
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CNotepadModel::Close
       
   110 // deprecated. (only for BC).
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 EXPORT_C void CNotepadModel::Close() 
       
   114     {
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CNotepadModel::IsOpen
       
   119 // deprecated. (only for BC).
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 EXPORT_C TBool CNotepadModel::IsOpen() 
       
   123     {
       
   124     return ETrue;
       
   125     } 
       
   126 
       
   127 // -----------------------------------------------------------------------------
       
   128 // CNotepadModel::SeekKey
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 EXPORT_C TInt CNotepadModel::SeekKey(const TInt aKey)
       
   132     {
       
   133     return iKeyArray.Find(aKey) >= 0 ? // found?
       
   134         0 : 1;
       
   135     }
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // CNotepadModel::ContentL
       
   139 // -----------------------------------------------------------------------------
       
   140 //
       
   141 HBufC* CNotepadModel::ContentL(TInt aItemIndex)
       
   142     {
       
   143     return ContentByKeyL(iKeyArray[aItemIndex]);
       
   144     }
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CNotepadModel::IndexOf
       
   148 // -----------------------------------------------------------------------------
       
   149 //
       
   150 TInt CNotepadModel::IndexOf(const TInt aKey) const
       
   151     {
       
   152     TInt returnIndex(KNotepadModelInvalidIndex);
       
   153     if ( aKey != KNotepadPseudoKeyIdForNewNote )
       
   154         {
       
   155         TInt index(iKeyArray.Find(aKey));
       
   156         if ( index >= 0 )
       
   157             {
       
   158             returnIndex = index;
       
   159             }
       
   160         }
       
   161     return returnIndex;
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // CNotepadModel::HandleDateChangedL
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 void CNotepadModel::HandleDateChangedL(TBool aSyncNow)
       
   169     {
       
   170     iFlag |= ENotepadRequireDbViewUpdate | ENotepadRequireItemArrayUpdate;
       
   171     if ( aSyncNow )
       
   172         {
       
   173         SyncL(EFalse);
       
   174         }
       
   175     }
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // CNotepadModel::DeleteByKeysL
       
   179 // -----------------------------------------------------------------------------
       
   180 //
       
   181 void CNotepadModel::DeleteByKeysL(const RArray<TInt>& aKeys)
       
   182     {
       
   183     __ASSERT_DEBUG( aKeys.Count() > 0, 
       
   184         Panic(ENotepadLibraryPanicInvalidArgument) );
       
   185     TRAPD( err, PrepareToDeleteByKeysL(aKeys); ); // execute RDbUpdate
       
   186     if ( err != KErrNone )
       
   187         {
       
   188         AbortDeletionL();
       
   189         User::Leave(err);
       
   190         }
       
   191     iFlag |= ENotepadIsDeleting;
       
   192     iFlag &= ~ENotepadIsRemovingLinks;
       
   193     iExecuter->Start(TCallBack(DeleteCallBack, this));
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CNotepadModel::CancelDeletion
       
   198 // -----------------------------------------------------------------------------
       
   199 //
       
   200 void CNotepadModel::CancelDeletion()
       
   201     {
       
   202     iDbUpdate.Close();
       
   203     delete iExecuter;
       
   204     iExecuter = NULL;
       
   205     iFlag &= ~ENotepadIsDeleting;
       
   206     iFlag &= ~ENotepadIsRemovingLinks;
       
   207     iFlag |= ENotepadRequireDbViewUpdate;
       
   208     if ( iDatabase.IsDamaged() )
       
   209         {
       
   210         iDatabase.Recover();
       
   211         }
       
   212     iSavedDeleteKeys.Reset();
       
   213 	}
       
   214 
       
   215 // -----------------------------------------------------------------------------
       
   216 // CNotepadModel::SyncL
       
   217 // Sync non-updated data.
       
   218 // -----------------------------------------------------------------------------
       
   219 //
       
   220 void CNotepadModel::SyncL( const TBool aForceSync )
       
   221     {
       
   222     // If iExecuter is creating iDbView, cancel the process and restart 
       
   223     // to create iDbView. If iExecuter is deleting items, this method does nothing.
       
   224     // (ie. Creating iDbView is postponed until the deleting process 
       
   225     // will be finished.
       
   226 	if ( !aForceSync && (iFlag & ENotepadItemArrayUpdateOnly) )
       
   227 	    {
       
   228 	    iFlag |= ENotepadItemArrayUpdateOnly;
       
   229     	if ( iModelObserver )
       
   230         	{
       
   231         	iModelObserver->HandleNotepadModelEventL(
       
   232           			MNotepadModelObserver::EStartItemArrayChange );
       
   233         	}
       
   234 	    TInt err(KErrNone);
       
   235 		TRAP(err,DoUpdateNotepadItemArrayAndKeyArrayL(*iItemArray,
       
   236 													  iKeyArray,
       
   237 													  *iTimeFormat));
       
   238 		if ( err != KErrNone)
       
   239 			{
       
   240 			iItemArray->Reset();
       
   241 			iKeyArray.Reset();
       
   242 			if ( iModelObserver )
       
   243 				{
       
   244 			    iModelObserver->HandleNotepadModelEventL(
       
   245 			        MNotepadModelObserver::EAbortItemArrayChange ); // not leave
       
   246 			    }
       
   247 			User::Leave(err);
       
   248 		    }
       
   249 		iFlag &= ~ENotepadItemArrayUpdateOnly; // now iItemArray is up to date
       
   250 		if ( iModelObserver )
       
   251 			{
       
   252 			iModelObserver->HandleNotepadModelEventL(
       
   253 			        MNotepadModelObserver::ECompleteItemArrayChange );
       
   254 		    }
       
   255 	    }
       
   256     else if(aForceSync || ( iFlag & ENotepadRequireDbViewUpdate ))
       
   257         {
       
   258         iFlag |= (ENotepadRequireDbViewUpdate | ENotepadRequireItemArrayUpdate);
       
   259         iDbView.Close();
       
   260         TDbTextComparison textComparison(EDbCompareCollated);
       
   261         User::LeaveIfError( iDbView.Prepare( iDatabase, 
       
   262             ( IsTemplates() ? TDbQuery(KNotepadSqlMceSelect, textComparison)
       
   263                 : TDbQuery(KNotepadSqlSelect, textComparison) ), 
       
   264         RDbView::EReadOnly ) );
       
   265         User::LeaveIfError( iDbView.EvaluateAll() );
       
   266         iFlag &= ~ENotepadRequireDbViewUpdate; // iDbView is now up to date
       
   267         BuildItemArrayL(ETrue); // force update
       
   268         }
       
   269     else 
       
   270         {
       
   271         BuildItemArrayL(aForceSync);
       
   272         }
       
   273     return;
       
   274     }
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CNotepadModel::HandleDatabaseChangedL
       
   278 // -----------------------------------------------------------------------------
       
   279 //
       
   280 void CNotepadModel::HandleDatabaseChangedL(TInt aStatus)
       
   281     {
       
   282     if ( ( ModeOp() == CNotepadCoreModel::ENotepadModelRowDeleted ) ||
       
   283     	 ( ModeOp() == CNotepadCoreModel::ENotepadModelRowAdded ) ||
       
   284     	 ( ModeOp() == CNotepadCoreModel::ENotepadModelRowUpdated ) )
       
   285     	{
       
   286  	  	iFlag |=ENotepadItemArrayUpdateOnly;
       
   287     	}
       
   288     else
       
   289     	{
       
   290     	iFlag |= ENotepadRequireDbViewUpdate; // delayed sync	
       
   291     	}
       
   292     if ( iModelObserver 
       
   293         && !(IsDeleting() && !(iFlag & ENotepadIsRemovingLinks)) )
       
   294         {
       
   295         iModelObserver->HandleNotepadModelEventL(
       
   296             MNotepadModelObserver::EDatabaseChanged, aStatus );
       
   297         }
       
   298     }
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CNotepadModel::SetNotepadModelObserver
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 void CNotepadModel::SetNotepadModelObserver(
       
   305     MNotepadModelObserver* aObserver )
       
   306     {
       
   307     iModelObserver = aObserver;
       
   308     }
       
   309 
       
   310 // -----------------------------------------------------------------------------
       
   311 // CNotepadModel::MdcaCount
       
   312 // from MDesCArray
       
   313 // -----------------------------------------------------------------------------
       
   314 //
       
   315 EXPORT_C TInt CNotepadModel::MdcaCount() const
       
   316     {
       
   317     return iItemArray->Count();
       
   318     }
       
   319 
       
   320 // -----------------------------------------------------------------------------
       
   321 // CNotepadModel::MdcaPoint
       
   322 // from MDesCArray
       
   323 // -----------------------------------------------------------------------------
       
   324 //
       
   325 EXPORT_C TPtrC CNotepadModel::MdcaPoint(TInt aIndex) const
       
   326     {
       
   327     return (*iItemArray)[aIndex];
       
   328     }
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // CNotepadModel::CNotepadModel
       
   332 // C++ constructor
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 CNotepadModel::CNotepadModel()
       
   336     : CNotepadCoreModel(),
       
   337     iListingStyle(ENotepadListingStyleNone)
       
   338     {
       
   339     }
       
   340 
       
   341 // -----------------------------------------------------------------------------
       
   342 // CNotepadModel::ConstructL
       
   343 // second phase constructor.
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 void CNotepadModel::ConstructL(TInt aResId)
       
   347     {
       
   348     TResourceReader rr;
       
   349     iEnv->CreateResourceReaderLC(rr, aResId); // Push rr
       
   350     CNotepadCoreModel::ConstructL(rr.ReadInt32()); // LLINK data_file
       
   351     iListingStyle 
       
   352         = rr.ReadInt16(); // WORD  listing_style;
       
   353     TInt dateResId(rr.ReadInt32());               // LLINK date_format
       
   354     TInt timeResId(rr.ReadInt32());               // LLINK time_format
       
   355     TInt firstNoteResId(rr.ReadInt32());          // LLINK first_note;
       
   356     CleanupStack::PopAndDestroy(); // rr
       
   357     if (dateResId)
       
   358         {
       
   359         iDateFormat = iEnv->AllocReadResourceL(dateResId);
       
   360         }
       
   361     if (timeResId)
       
   362         {
       
   363         iTimeFormat = iEnv->AllocReadResourceL(timeResId);
       
   364         }
       
   365     if ( firstNoteResId )
       
   366     	{
       
   367     iFixedFirstNote = iEnv->AllocReadResourceL( firstNoteResId );
       
   368     	}
       
   369     iItemArray = new(ELeave) CDesCArrayFlat(KNotepadItemArrayGranularity);
       
   370     iDatabaseChangeNotifier = 
       
   371         CNotepadModel::CDatabaseChangeNotifier::NewL(iDatabase, *this);
       
   372 
       
   373     SyncL(ETrue);
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CNotepadModel::PrepareToDeleteByKeysL
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 void CNotepadModel::PrepareToDeleteByKeysL(const RArray<TInt>& aKeys)
       
   381     {
       
   382     CancelDeletion();
       
   383     User::LeaveIfError(iFileSession.Connect());
       
   384    	CleanupClosePushL(iFileSession);
       
   385     iRetval = iFileSession.ReserveDriveSpace( KDefaultDrive, KNotepadDiskSpaceNeededForMultipleDeletion );
       
   386     if ( iRetval == KErrNone )
       
   387     {
       
   388     	iRetval = iFileSession.GetReserveAccess( KDefaultDrive );
       
   389     }
       
   390     // the priority of iExecuter must be lower than that of CAknProgressDialog
       
   391     iExecuter = CIdle::NewL(CActive::EPriorityLow); 
       
   392     const TInt count( aKeys.Count() );
       
   393     for (TInt i(0); i < count; i++)
       
   394         {
       
   395         User::LeaveIfError(iSavedDeleteKeys.Append(aKeys[i]));
       
   396         }
       
   397     iProgressCount = 0;
       
   398     ExecuteDeleteStepL();
       
   399     iRetval = iFileSession.ReleaseReserveAccess( KDefaultDrive );
       
   400     iFileSession.Close();
       
   401 	CleanupStack::PopAndDestroy();
       
   402     }
       
   403 
       
   404 // -----------------------------------------------------------------------------
       
   405 // CNotepadModel::ExecuteDeleteStepL
       
   406 // -----------------------------------------------------------------------------
       
   407 //
       
   408 void CNotepadModel::ExecuteDeleteStepL()
       
   409     {
       
   410     
       
   411     iStepCount = iSavedDeleteKeys.Count();
       
   412     if ( iStepCount > KNotepadMaxDeleteCountInStep )
       
   413         {
       
   414         iStepCount = KNotepadMaxDeleteCountInStep;
       
   415         }
       
   416     HBufC* hbuf = HBufC::NewLC( KNotepadSqlDeleteHeadSize + 
       
   417         ( iStepCount - 1 )* KNotepadSqlDeleteByKeysAppendSize);
       
   418     TPtr sql = hbuf->Des();
       
   419     sql.Append(KNotepadSqlDeleteHead);
       
   420     sql.AppendNum(iSavedDeleteKeys[0]);
       
   421     if ( IsTemplates() )
       
   422         {
       
   423         iSavedDeleteKeys.Remove(0);
       
   424         }
       
   425     else // If Notepad, Remove is postponed until remove link phase
       
   426         {
       
   427         for (TInt i(1); i < iStepCount; i++)
       
   428             {
       
   429             sql.Append(KNotepadSqlDeleteByKeysAppend);
       
   430             sql.AppendNum(iSavedDeleteKeys[i]);
       
   431             }
       
   432         }
       
   433     User::LeaveIfError(iDbUpdate.Execute(iDatabase, sql));
       
   434     CleanupStack::PopAndDestroy(); // hbuf
       
   435     }
       
   436 
       
   437 // -----------------------------------------------------------------------------
       
   438 // CNotepadModel::AbortDeletionL
       
   439 // -----------------------------------------------------------------------------
       
   440 //
       
   441 void CNotepadModel::AbortDeletionL()
       
   442     {
       
   443     CancelDeletion();
       
   444     if ( iModelObserver )
       
   445         {
       
   446         iModelObserver->HandleNotepadModelEventL(
       
   447             MNotepadModelObserver::EAbortDeletion );
       
   448         }
       
   449     }
       
   450 
       
   451 // -----------------------------------------------------------------------------
       
   452 // CNotepadModel::CompleteDeletionL
       
   453 // -----------------------------------------------------------------------------
       
   454 //
       
   455 void CNotepadModel::CompleteDeletionL()
       
   456     {
       
   457     CancelDeletion();
       
   458     if ( iModelObserver )
       
   459         {
       
   460         iModelObserver->HandleNotepadModelEventL(
       
   461             MNotepadModelObserver::ECompleteDeletion);
       
   462         }
       
   463     SyncL(ETrue);
       
   464     iItemArray->Compress();
       
   465     }
       
   466 
       
   467 // -----------------------------------------------------------------------------
       
   468 // CNotepadModel::DeleteCallBack
       
   469 //
       
   470 // be sure that this function never leave after AbortDeletionL
       
   471 // because iExecuter is deleted in AbortDeletionL.
       
   472 // -----------------------------------------------------------------------------
       
   473 //
       
   474 TInt CNotepadModel::DeleteCallBack(TAny *aSelf)
       
   475     {
       
   476     TInt needsRepeat(FALSE);
       
   477     CNotepadModel* self = STATIC_CAST(CNotepadModel*, aSelf);
       
   478     TRAPD(err, 
       
   479         needsRepeat = ( self->iFlag & ENotepadIsRemovingLinks ) ? 
       
   480             self->DoRemoveLinkCallBackL() : 
       
   481             self->DoDeleteCallBackL(); 
       
   482         );
       
   483     if ( err != KErrNone )
       
   484         {
       
   485         self->iEnv->HandleError(err);
       
   486         TRAP(err, self->AbortDeletionL(););
       
   487         if ( err != KErrNone )
       
   488             {
       
   489             self->iEnv->HandleError(err);
       
   490             }
       
   491         }
       
   492     return needsRepeat;
       
   493     }
       
   494 
       
   495 // -----------------------------------------------------------------------------
       
   496 // CNotepadModel::DoDeleteCallBackL
       
   497 // -----------------------------------------------------------------------------
       
   498 //
       
   499 TInt CNotepadModel::DoDeleteCallBackL()
       
   500     {
       
   501     TInt needsRepeat(TRUE);
       
   502     TInt increment(0);
       
   503     TBool deleteFinished(EFalse);
       
   504     const TInt stat(iDbUpdate.Next());
       
   505     if ( stat == 0 ) // current step has completed
       
   506         {
       
   507         iDbUpdate.Close();
       
   508         if ( IsTemplates() )
       
   509             {
       
   510             if ( iSavedDeleteKeys.Count() == 0 ) // MCE, finish all
       
   511                 {
       
   512                 needsRepeat = FALSE;
       
   513                 CompleteDeletionL();
       
   514                 deleteFinished = ETrue;
       
   515                 }
       
   516             else // do next step
       
   517                 {
       
   518                 increment = iStepCount - iProgressCount;
       
   519 
       
   520                 iProgressCount += increment;
       
   521                 if ( iModelObserver )
       
   522                     {
       
   523                     iModelObserver->HandleNotepadModelEventL(
       
   524                             MNotepadModelObserver::EProgressDeletion,
       
   525                             1 );
       
   526                     }
       
   527 
       
   528                 ExecuteDeleteStepL();
       
   529                 }
       
   530             }
       
   531         else
       
   532             {
       
   533             // switch to remove link phase
       
   534             iFlag |= ENotepadIsRemovingLinks; 
       
   535             increment = iStepCount - iProgressCount;
       
   536             if ( iSavedDeleteKeys.Count() == iStepCount ) // final step
       
   537                 {
       
   538                 deleteFinished = ETrue;
       
   539                 }
       
   540             }
       
   541         }
       
   542     if ( stat > 0 )
       
   543         {
       
   544         increment = iDbUpdate.RowCount() - iProgressCount;
       
   545         }            
       
   546     
       
   547     if ( deleteFinished || ( stat == 0 && 
       
   548         SysUtil::FFSSpaceBelowCriticalLevelL(&(iEnv->FsSession())) ) )
       
   549         {
       
   550         User::LeaveIfError(iDatabase.Compact());
       
   551         }
       
   552     User::LeaveIfError(stat);
       
   553     return needsRepeat;
       
   554     }
       
   555 
       
   556 // -----------------------------------------------------------------------------
       
   557 // CNotepadModel::DoRemoveLinkCallBackL
       
   558 // -----------------------------------------------------------------------------
       
   559 //
       
   560 TInt CNotepadModel::DoRemoveLinkCallBackL()
       
   561     {
       
   562     TInt needsRepeat(TRUE);
       
   563     TBool hasFinished(EFalse);
       
   564     TBool timeUp(EFalse);
       
   565     TInt count(0);
       
   566     TTime beginning;
       
   567     TTime now;
       
   568     TTimeIntervalMicroSeconds maxInterval(
       
   569         KNotepadMaxRunIntervalInMicroSeconds );
       
   570     beginning.UniversalTime();
       
   571     while ( !hasFinished && !timeUp )
       
   572         {
       
   573         if ( iStepCount == 0 ) // current step has completed
       
   574             {
       
   575             hasFinished = ETrue;
       
   576             }
       
   577         else
       
   578             {
       
   579             iSavedDeleteKeys.Remove(0);
       
   580             count++;
       
   581             iStepCount--;
       
   582             now.UniversalTime();
       
   583             timeUp = ( now.MicroSecondsFrom(beginning) > maxInterval );
       
   584             }
       
   585         }
       
   586     if ( hasFinished ) // current step has finished
       
   587         {
       
   588         if ( iSavedDeleteKeys.Count() == 0 ) // finish all
       
   589             {
       
   590             needsRepeat = FALSE;
       
   591             CompleteDeletionL();
       
   592             }
       
   593         else // switch to delete phase again
       
   594             {
       
   595             iFlag &= ~ENotepadIsRemovingLinks;
       
   596             ExecuteDeleteStepL();
       
   597             }
       
   598         }
       
   599     if ( needsRepeat && count > 0 )
       
   600         {
       
   601         iModelObserver->HandleNotepadModelEventL(
       
   602             MNotepadModelObserver::EProgressDeletion, count); 
       
   603         }
       
   604     return needsRepeat;
       
   605     }
       
   606 
       
   607 // -----------------------------------------------------------------------------
       
   608 // CNotepadModel::BuildItemArrayL
       
   609 // -----------------------------------------------------------------------------
       
   610 //
       
   611 void CNotepadModel::BuildItemArrayL( const TBool aForceSync )
       
   612     {
       
   613     if ( !aForceSync && !(iFlag & ENotepadRequireItemArrayUpdate) )
       
   614         {
       
   615         return;
       
   616         }
       
   617 
       
   618     iFlag |= ENotepadRequireItemArrayUpdate;
       
   619     if ( iModelObserver )
       
   620         {
       
   621         iModelObserver->HandleNotepadModelEventL(
       
   622             MNotepadModelObserver::EStartItemArrayChange );
       
   623         }
       
   624     iItemArray->Reset();
       
   625     iKeyArray.Reset();
       
   626     //insert the New note as the firt note
       
   627     if ( iFixedFirstNote != NULL )
       
   628 		{
       
   629 		TBuf<256> buf;
       
   630 		_LIT( KBlankSpace, "   " );
       
   631 		buf.Append( KBlankSpace );	
       
   632 		buf.Append( KColumnListSeparator );
       
   633 		buf.Append( *iFixedFirstNote );
       
   634 		iItemArray->AppendL( buf );
       
   635 		//default key for New note, -2 is never used for normal keys.
       
   636 		iKeyArray.Append( -2 );
       
   637 		}
       
   638     
       
   639   
       
   640     TRAPD( err, DoBuildItemArrayL() );
       
   641     if ( err != KErrNone)
       
   642         {
       
   643         iItemArray->Reset();
       
   644         iKeyArray.Reset();
       
   645         if ( iModelObserver )
       
   646             {
       
   647             iModelObserver->HandleNotepadModelEventL(
       
   648                 MNotepadModelObserver::EAbortItemArrayChange ); // not leave
       
   649             }
       
   650         User::Leave(err);
       
   651         }
       
   652     iFlag &= ~ENotepadRequireItemArrayUpdate; // now iItemArray is up to date
       
   653     if ( iModelObserver )
       
   654         {
       
   655         iModelObserver->HandleNotepadModelEventL(
       
   656             MNotepadModelObserver::ECompleteItemArrayChange );
       
   657         }
       
   658     }
       
   659 
       
   660 // -----------------------------------------------------------------------------
       
   661 // CNotepadModel::DoBuildItemArrayL
       
   662 // -----------------------------------------------------------------------------
       
   663 //
       
   664 void CNotepadModel::DoBuildItemArrayL()
       
   665     {
       
   666     HBufC* hbuf = HBufC::NewLC(KNotepadListEntryLength);
       
   667     TPtr buf = hbuf->Des();
       
   668     if ( IsTemplates() )
       
   669         {
       
   670         DoBuildTemplateItemArrayL(buf);
       
   671         }
       
   672     else
       
   673         {
       
   674         DoBuildNotepadItemArrayL(buf);
       
   675         }
       
   676     CleanupStack::PopAndDestroy(); // hbuf
       
   677     }
       
   678 
       
   679 // -----------------------------------------------------------------------------
       
   680 // CNotepadModel::DoBuildNotepadItemArrayL
       
   681 // -----------------------------------------------------------------------------
       
   682 //
       
   683 void CNotepadModel::DoBuildNotepadItemArrayL(
       
   684     TPtr& aBuf)
       
   685     {
       
   686     TTimeIntervalMinutes offset;
       
   687     TTime now;
       
   688     now.HomeTime();
       
   689     TTime gmt;
       
   690     gmt.UniversalTime();
       
   691     now.MinutesFrom(gmt, offset);
       
   692     TInt currentDay(now.DateTime().Day());
       
   693     TInt currentMonth(now.DateTime().Month());
       
   694     TInt currentYear(now.DateTime().Year());
       
   695 
       
   696     RArray<TInt> minutesArrayOfToday;
       
   697     CleanupClosePushL(minutesArrayOfToday);
       
   698     TInt minutesInToday(0);
       
   699 
       
   700     TInt firstIndexOfTheDay(KNotepadModelInvalidIndex);
       
   701     TDateTime prevDateTime;
       
   702 
       
   703     RArray<TPtrC> textArrayOfTheDay;
       
   704     CleanupClosePushL(textArrayOfTheDay);
       
   705     iDbView.FirstL();
       
   706     while (iDbView.AtRow())
       
   707         {
       
   708         iDbView.GetL();
       
   709         TInt thisKey(iDbView.ColInt(ENotepadKey));
       
   710         TTime time = iDbView.ColTime(ENotepadUpdateTime);
       
   711         time += offset; // including summertime adjustment
       
   712         TDateTime dateTime = time.DateTime(); // cache
       
   713         TBool isToday( dateTime.Day() == currentDay
       
   714              && dateTime.Month() == currentMonth
       
   715              && dateTime.Year() == currentYear );
       
   716         if ( isToday )
       
   717             {
       
   718             minutesInToday = dateTime.Hour() * 60 + dateTime.Minute();
       
   719             }
       
   720         aBuf.SetLength(0);
       
   721         TInt textOffset(0);
       
   722         switch (iListingStyle)
       
   723             {
       
   724             case ENotepadListingStyleNP: // list of memos
       
   725                 time.FormatL( aBuf, isToday ? *iTimeFormat : *iDateFormat );
       
   726                 aBuf.Append(KColumnListSeparator);
       
   727                 textOffset = aBuf.Length();
       
   728                 // through into next case
       
   729             case ENotepadListingStyleFetch: // fetch a memo
       
   730                 AppendContentAsLabelL(aBuf, iDbView);
       
   731                 break;
       
   732             default:
       
   733                 break;
       
   734             }
       
   735 
       
   736         TPtrC thisText = 
       
   737             aBuf.Mid(textOffset).Left(KNotepadMaxCharactersForSort);
       
   738         if ( (iItemArray->Count() == 0 && iFixedFirstNote == NULL) || (iItemArray->Count() == 1 && iFixedFirstNote != NULL) || 
       
   739              dateTime.Day() != prevDateTime.Day() ||
       
   740              dateTime.Month() != prevDateTime.Month() ||
       
   741              dateTime.Year() != prevDateTime.Year() )
       
   742             {
       
   743             // first entry or date of the item has changed
       
   744             firstIndexOfTheDay = iItemArray->Count();
       
   745 
       
   746             textArrayOfTheDay.Reset();
       
   747             if ( isToday )
       
   748                 {
       
   749                 User::LeaveIfError(minutesArrayOfToday.Append(minutesInToday));
       
   750                 }
       
   751             // INSERT POINT
       
   752             AknTextUtils::LanguageSpecificNumberConversion(aBuf);
       
   753             iItemArray->AppendL(aBuf);
       
   754             User::LeaveIfError( textArrayOfTheDay.Append(
       
   755                 (*iItemArray)[firstIndexOfTheDay].Mid(textOffset).Left(
       
   756                     KNotepadMaxCharactersForSort) ) );
       
   757             User::LeaveIfError(iKeyArray.Append(thisKey));
       
   758             }
       
   759         else
       
   760             {
       
   761             // calculate an insertion point
       
   762             TInt low(0); // this will be result insertion point
       
   763             TInt high( textArrayOfTheDay.Count() - 1 );
       
   764             TInt mid(0);
       
   765             while ( high >= low )
       
   766                 {
       
   767                 mid = (high + low) / 2;
       
   768                 if ( isToday ? ( minutesInToday < minutesArrayOfToday[mid] ||
       
   769                     ( minutesInToday == minutesArrayOfToday[mid] &&
       
   770                         thisText.CompareC(textArrayOfTheDay[mid]) > 0 ) ) :
       
   771                     thisText.CompareC(textArrayOfTheDay[mid]) > 0 )
       
   772                     {
       
   773                     low = mid + 1;
       
   774                     }
       
   775                 else
       
   776                     {
       
   777                     high = mid - 1;
       
   778                     }
       
   779                 }
       
   780             // low is result
       
   781             if ( isToday )
       
   782                 {
       
   783                 User::LeaveIfError(minutesArrayOfToday.Insert(
       
   784                     minutesInToday, low ) );
       
   785                 }
       
   786             // INSERT POINT
       
   787             AknTextUtils::LanguageSpecificNumberConversion(aBuf);
       
   788             iItemArray->InsertL(firstIndexOfTheDay + low, aBuf);
       
   789             User::LeaveIfError( textArrayOfTheDay.Insert(
       
   790                 (*iItemArray)[firstIndexOfTheDay + low].Mid(textOffset).Left(
       
   791                     KNotepadMaxCharactersForSort), 
       
   792                 low ) );
       
   793             User::LeaveIfError(
       
   794                 iKeyArray.Insert(thisKey, firstIndexOfTheDay + low) );
       
   795             }
       
   796         if ( iModelObserver && 
       
   797             iItemArray->Count() == KNotepadBuildItemArrayProgressCount )
       
   798             {
       
   799             iModelObserver->HandleNotepadModelEventL(
       
   800                 MNotepadModelObserver::EProgressItemArrayChange );
       
   801             }
       
   802         prevDateTime = dateTime;
       
   803         iDbView.NextL();
       
   804         }
       
   805     CleanupStack::PopAndDestroy(2); // minutesArrayOfToday, textArrayOfTheDay
       
   806     }
       
   807 
       
   808 // -----------------------------------------------------------------------------
       
   809 // CNotepadModel::DoBuildTemplateItemArrayL
       
   810 // -----------------------------------------------------------------------------
       
   811 //
       
   812 void CNotepadModel::DoBuildTemplateItemArrayL(
       
   813     TPtr& aBuf)
       
   814     {
       
   815     iDbView.FirstL();
       
   816     while (iDbView.AtRow())
       
   817         {
       
   818         iDbView.GetL();
       
   819         TInt thisKey(iDbView.ColInt(ENotepadKey));
       
   820         aBuf.SetLength(0);
       
   821         switch (iListingStyle)
       
   822             {
       
   823             case ENotepadListingStyleMC:
       
   824                 aBuf.Append(KNotepadMceFirstColumnData);
       
   825                 aBuf.Append(KColumnListSeparator);
       
   826                 // pass through into next case
       
   827             case ENotepadListingStyleFetchMC: // fetch template
       
   828                 AppendContentAsLabelL(aBuf, iDbView);
       
   829                 break;
       
   830             default:
       
   831                 break;
       
   832             }
       
   833         // INSERT POINT
       
   834         iItemArray->AppendL(aBuf);
       
   835         User::LeaveIfError(iKeyArray.Append(thisKey));
       
   836         if ( iModelObserver && 
       
   837             iItemArray->Count() == KNotepadBuildItemArrayProgressCount )
       
   838             {
       
   839             iModelObserver->HandleNotepadModelEventL(
       
   840                 MNotepadModelObserver::EProgressItemArrayChange );
       
   841             }
       
   842         iDbView.NextL();
       
   843         }
       
   844     }
       
   845 
       
   846 // -----------------------------------------------------------------------------
       
   847 // CNotepadModel::CNotepadModel_Reserved
       
   848 // -----------------------------------------------------------------------------
       
   849 //
       
   850 EXPORT_C void CNotepadModel::CNotepadModel_Reserved()
       
   851     {
       
   852     }
       
   853 
       
   854 // -----------------------------------------------------------------------------
       
   855 // CNotepadModel::SetItemArrayFlags
       
   856 // -----------------------------------------------------------------------------
       
   857 //
       
   858 void CNotepadModel::SetItemArrayFlags()
       
   859 	{
       
   860 	if(iFlag&ENotepadItemArrayUpdateOnly)
       
   861 		{
       
   862 
       
   863 		iFlag |= ENotepadRequireDbViewUpdate;
       
   864 		iFlag |= ENotepadRequireItemArrayUpdate;
       
   865 		}
       
   866 	}
       
   867 
       
   868 // -----------------------------------------------------------------------------
       
   869 // CNotepadModel::ItemArrayFlags
       
   870 // -----------------------------------------------------------------------------
       
   871 //
       
   872 TUint CNotepadModel::ItemArrayFlags()
       
   873 	{
       
   874 	return iFlag;
       
   875 	}
       
   876 
       
   877 // -----------------------------------------------------------------------------
       
   878 // CNotepadModel::CDatabaseChangeNotifier::NewL
       
   879 // -----------------------------------------------------------------------------
       
   880 //
       
   881 CNotepadModel::CDatabaseChangeNotifier* 
       
   882     CNotepadModel::CDatabaseChangeNotifier::NewL(
       
   883     RDbDatabase& aDatabase,
       
   884     CNotepadModel& aModel )
       
   885     {
       
   886     CDatabaseChangeNotifier* self = 
       
   887         new(ELeave) CDatabaseChangeNotifier(aModel);
       
   888     CleanupStack::PushL(self);
       
   889     self->ConstructL(aDatabase);
       
   890     CleanupStack::Pop(); // self
       
   891     return self; 
       
   892     }
       
   893 
       
   894 // -----------------------------------------------------------------------------
       
   895 // CNotepadModel::CDatabaseChangeNotifier::~CDatabaseChangeNotifier
       
   896 // -----------------------------------------------------------------------------
       
   897 //
       
   898 CNotepadModel::CDatabaseChangeNotifier::~CDatabaseChangeNotifier()
       
   899     {
       
   900     Cancel();
       
   901     iDbNotifier.Close(); 
       
   902     }
       
   903 
       
   904 // -----------------------------------------------------------------------------
       
   905 // CNotepadModel::CDatabaseChangeNotifier::CDatabaseChangeNotifier
       
   906 // -----------------------------------------------------------------------------
       
   907 //
       
   908 CNotepadModel::CDatabaseChangeNotifier::CDatabaseChangeNotifier(
       
   909     CNotepadModel& aModel )
       
   910     :CActive(CActive::EPriorityLow), iModel(aModel)
       
   911     {
       
   912     CActiveScheduler::Add(this);
       
   913     }
       
   914 
       
   915 // -----------------------------------------------------------------------------
       
   916 // CNotepadModel::CDatabaseChangeNotifier::ConstructL
       
   917 // -----------------------------------------------------------------------------
       
   918 //
       
   919 void CNotepadModel::CDatabaseChangeNotifier::ConstructL(
       
   920     RDbDatabase& aDatabase ) 
       
   921     { 
       
   922     User::LeaveIfError(iDbNotifier.Open(aDatabase)); 
       
   923     iDbNotifier.NotifyChange(iStatus);
       
   924     SetActive();
       
   925     }
       
   926 
       
   927 // -----------------------------------------------------------------------------
       
   928 // CNotepadModel::CDatabaseChangeNotifier::DoCancel
       
   929 // -----------------------------------------------------------------------------
       
   930 //
       
   931 void CNotepadModel::CDatabaseChangeNotifier::DoCancel()
       
   932     { 
       
   933     iDbNotifier.Cancel(); 
       
   934     }
       
   935 
       
   936 // -----------------------------------------------------------------------------
       
   937 // CNotepadModel::CDatabaseChangeNotifier::RunL
       
   938 // -----------------------------------------------------------------------------
       
   939 //
       
   940 void CNotepadModel::CDatabaseChangeNotifier::RunL()
       
   941     {
       
   942     // enum TEvent {EClose,EUnlock,ECommit,ERollback,ERecover};
       
   943     TInt status(iStatus.Int());
       
   944     TInt err(KErrNone);
       
   945     if (status == RDbNotifier::ECommit)
       
   946         {
       
   947         TRAP(err, iModel.HandleDatabaseChangedL(status););
       
   948         }
       
   949     // Restart this even if err != KErrNone
       
   950     iDbNotifier.NotifyChange(iStatus);
       
   951     SetActive();
       
   952     User::LeaveIfError(err);
       
   953     }
       
   954 
       
   955 // End of File