calendarui/organizerplugin/aiagendapluginengine/src/AIAgendaPluginEngineImpl.cpp
changeset 0 f979ecb2b13e
child 13 1984aceb8774
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     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:  
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 //debug
       
    20 #include "calendarui_debug.h"
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include "AIAgendaPluginEngine.h"
       
    24 #include "AIAgendaPluginEngineImpl.h"
       
    25 
       
    26 #include "PluginDataChangeObserver.h"
       
    27 #include "EventExpirationTimer.h"
       
    28 
       
    29 #include <calsession.h>
       
    30 #include <calentry.h>
       
    31 #include <calinstance.h>
       
    32 #include <calrrule.h>
       
    33 #include <calnotification.h>
       
    34 
       
    35 #include <coemain.h>
       
    36 #include <bacntf.h>
       
    37 
       
    38 // =============================================================================
       
    39 // =============================================================================
       
    40 
       
    41 
       
    42 // ============================ MEMBER FUNCTIONS ===============================
       
    43 // (CAIAgendaPluginEngineImpl)
       
    44 
       
    45 // ---------------------------------------------------------
       
    46 // CAIAgendaPluginEngineImpl::ConstructL
       
    47 // Symbian 2nd phase constructor can leave.
       
    48 // ---------------------------------------------------------
       
    49 //
       
    50 void CAIAgendaPluginEngineImpl::ConstructL(void)
       
    51 {
       
    52     TRACE_ENTRY_POINT;
       
    53     
       
    54     iSession.ConnectL();
       
    55 
       
    56     if( iObserverType == ECalendarObserver || iObserverType == ECalendarAndTodoObserver )
       
    57     {
       
    58         TCallBack environmentChangeCallBack( EnvironmentChangeCallBack, this );
       
    59 
       
    60         // Create a notifier for system time and locale changes and midnight crossover
       
    61         iEnvironmentChangeNotifier = CEnvironmentChangeNotifier::NewL( EActivePriorityLogonA,
       
    62                                                                        environmentChangeCallBack );
       
    63         iEnvironmentChangeNotifier->Start();
       
    64 
       
    65         iEventChangeObserver = CPropertyObserver::NewL( *this, KCalPubSubCategory, ECalPubSubEventNotification, ETrue);
       
    66     }
       
    67 
       
    68     if( iObserverType == EToDoObserver || iObserverType == ECalendarAndTodoObserver )
       
    69     {
       
    70         iTodoChangeObserver = CPropertyObserver::NewL( *this, KCalPubSubCategory, ECalPubSubTodoNotification, ETrue );
       
    71     }
       
    72 
       
    73     TCallBack expirationCallBack( EventExpiredCallBack, this );
       
    74     iExpirationTimer = CEventExpirationTimer::NewL( expirationCallBack );
       
    75 
       
    76     TCallBack refreshCallBack( RefreshTimerCallBack, this );
       
    77     iRefreshTimer = CEventExpirationTimer::NewL( refreshCallBack );
       
    78 
       
    79     StateMachine();
       
    80     
       
    81     iCalendarSession = CCalSession::NewL();
       
    82     iCalendarSession->StartFileChangeNotificationL(*this);
       
    83     
       
    84     TRACE_EXIT_POINT;
       
    85 }
       
    86 
       
    87 // ---------------------------------------------------------
       
    88 // CAIAgendaPluginEngineImpl::NewL
       
    89 // Two-phased constructor.
       
    90 // Create instance of concrete ECOM interface implementation
       
    91 // ---------------------------------------------------------
       
    92 //
       
    93 CAIAgendaPluginEngineImpl* CAIAgendaPluginEngineImpl::NewL(MPluginDataChangeObserver& aDataChangeObserver, TObserverType aObserverType)
       
    94 {
       
    95     TRACE_ENTRY_POINT;
       
    96     
       
    97     CAIAgendaPluginEngineImpl* self = new( ELeave )CAIAgendaPluginEngineImpl( aDataChangeObserver, aObserverType );
       
    98     CleanupStack::PushL( self );
       
    99 
       
   100     self->ConstructL();
       
   101 
       
   102     CleanupStack::Pop( self );
       
   103     
       
   104     TRACE_EXIT_POINT;
       
   105     return self;
       
   106 }
       
   107 
       
   108 // ---------------------------------------------------------
       
   109 // CAIAgendaPluginEngineImpl::CAIAgendaPluginEngineImpl
       
   110 // ?implementation_description
       
   111 // (other items were commented in a header).
       
   112 // ---------------------------------------------------------
       
   113 //
       
   114 CAIAgendaPluginEngineImpl::CAIAgendaPluginEngineImpl(MPluginDataChangeObserver& aDataChangeObserver, TObserverType aObserverType)
       
   115  : iDataChangeObserver( aDataChangeObserver ),
       
   116    iObserverType( aObserverType ),
       
   117    iDBState( EDBOffline ),
       
   118    iNeedsUpdate( EFalse ),
       
   119    iHadEvents( EFalse )
       
   120     {
       
   121     TRACE_ENTRY_POINT;
       
   122     TRACE_EXIT_POINT;
       
   123     }
       
   124 
       
   125 // ---------------------------------------------------------
       
   126 // CAIAgendaPluginEngineImpl::~CAIAgendaPluginEngineImpl
       
   127 // ?implementation_description
       
   128 // (other items were commented in a header).
       
   129 // ---------------------------------------------------------
       
   130 //
       
   131 CAIAgendaPluginEngineImpl::~CAIAgendaPluginEngineImpl(void)
       
   132 {
       
   133     TRACE_ENTRY_POINT;
       
   134     
       
   135     iDBState = EDBOffline;
       
   136     
       
   137 	if(iCalendarSession)
       
   138 		{
       
   139 		iCalendarSession->StopFileChangeNotification();
       
   140 		delete iCalendarSession;
       
   141 		iCalendarSession = NULL;
       
   142 		}
       
   143     
       
   144     delete iExpirationTimer;
       
   145     delete iRefreshTimer;
       
   146     delete iEventChangeObserver;
       
   147     delete iTodoChangeObserver;
       
   148 
       
   149     if( iEnvironmentChangeNotifier )
       
   150     {
       
   151         iEnvironmentChangeNotifier->Cancel();
       
   152         delete iEnvironmentChangeNotifier;
       
   153     }
       
   154 
       
   155     delete iCalendarEngine;  // Close() called in destructor
       
   156 
       
   157     iInstanceArray.ResetAndDestroy();
       
   158     iInstanceArray.Close();
       
   159 
       
   160     iSession.Close();
       
   161     
       
   162     TRACE_EXIT_POINT;
       
   163 }
       
   164 
       
   165 // ---------------------------------------------------------
       
   166 // CAIAgendaPluginEngineImpl::StateMachine
       
   167 // ?implementation_description
       
   168 // (other items were commented in a header).
       
   169 // ---------------------------------------------------------
       
   170 //
       
   171 void CAIAgendaPluginEngineImpl::StateMachine(void)
       
   172 {
       
   173     TRACE_ENTRY_POINT;
       
   174     
       
   175     if( iObserverType == ECalendarObserver || iObserverType == ECalendarAndTodoObserver )
       
   176     {
       
   177         iExpirationTimer->Cancel();
       
   178     }
       
   179     iNeedsUpdate = EFalse;
       
   180 
       
   181     switch( iDBState )
       
   182     {
       
   183         case EDBOffline:
       
   184         {
       
   185             iDBState = EDBInitializing;
       
   186             iSession.Initialize( *this );
       
   187         }
       
   188         break;
       
   189 
       
   190         case EDBInitialized:
       
   191         {
       
   192             OpenDataBase();
       
   193             iDBState = EDBOpening;  // EDBInitialized -> EDBOpening
       
   194         }
       
   195         break;
       
   196 
       
   197         case EDBInitializing:
       
   198         case EDBOpening:
       
   199         {
       
   200             // needs update 
       
   201             // -> set the fetch state to normal and wait...
       
   202             iFetchState = EFetchNormal;
       
   203         }
       
   204         break;
       
   205 
       
   206         case EDBOpen:
       
   207         {
       
   208             if( iFetchState == EFetchNormal )
       
   209             {
       
   210                 GetTodayData();
       
   211             }
       
   212             else
       
   213             {
       
   214                 GetFutureData();
       
   215             }
       
   216             iFetchState = EFetchNormal;
       
   217             iDBState = EDBReading;  // EDBOpen -> EDBReading
       
   218         }
       
   219         break;
       
   220 
       
   221         case EDBReading:
       
   222         {
       
   223             // needs update
       
   224             // -> set the flag
       
   225             iNeedsUpdate = ETrue;  // the only place where we set this to ETrue!!!
       
   226 
       
   227             // then set the fetch state to normal and wait...
       
   228             iFetchState = EFetchNormal;
       
   229         }
       
   230         break;
       
   231 
       
   232         default:
       
   233             // fall through...
       
   234             break;
       
   235     }
       
   236     
       
   237     TRACE_EXIT_POINT;
       
   238 }
       
   239 
       
   240 // ---------------------------------------------------------
       
   241 // CAIAgendaPluginEngineImpl::OpenDataBase
       
   242 // ?implementation_description
       
   243 // (other items were commented in a header).
       
   244 // ---------------------------------------------------------
       
   245 //
       
   246 void CAIAgendaPluginEngineImpl::DoOpenDataBaseL(void)
       
   247 {
       
   248     TRACE_ENTRY_POINT;
       
   249     
       
   250     iCalendarEngine = CCalenEngine::NewL();  // TRAPPED!
       
   251     iCalendarEngine->OpenDatabaseL( *this );  // TRAPPED!
       
   252     
       
   253     TRACE_EXIT_POINT;
       
   254 }
       
   255 
       
   256 void CAIAgendaPluginEngineImpl::OpenDataBase(void)
       
   257     {
       
   258     TRACE_ENTRY_POINT;
       
   259     
       
   260     TRAPD(err, DoOpenDataBaseL());
       
   261     if(err != KErrNone)
       
   262         {
       
   263         CloseCalendarEngine();
       
   264         }
       
   265     
       
   266     TRACE_EXIT_POINT;    
       
   267     }
       
   268     
       
   269 // ---------------------------------------------------------
       
   270 // CAIAgendaPluginEngineImpl::OpenDatabaseCompleted
       
   271 // ?implementation_description
       
   272 // (other items were commented in a header).
       
   273 // ---------------------------------------------------------
       
   274 //
       
   275 void CAIAgendaPluginEngineImpl::OpenDatabaseCompleted(void)
       
   276 {
       
   277     TRACE_ENTRY_POINT;
       
   278     
       
   279     iDBState = EDBOpen;  // EDBOpening -> EDBOpen
       
   280     StateMachine();
       
   281     
       
   282     TRACE_EXIT_POINT;
       
   283 }
       
   284 
       
   285 void CAIAgendaPluginEngineImpl::GetTodayData(void)
       
   286    {
       
   287     TRACE_ENTRY_POINT;
       
   288     
       
   289     TRAPD(err, DoGetTodayDataL());
       
   290     if(err != KErrNone)
       
   291         {
       
   292         CloseCalendarEngine();
       
   293         }
       
   294     
       
   295     TRACE_EXIT_POINT;    
       
   296     }
       
   297 // ---------------------------------------------------------
       
   298 // CAIAgendaPluginEngineImpl::GetTodayData
       
   299 // ?implementation_description
       
   300 // (other items were commented in a header).
       
   301 // ---------------------------------------------------------
       
   302 //
       
   303 void CAIAgendaPluginEngineImpl::DoGetTodayDataL(void)
       
   304 {
       
   305     TRACE_ENTRY_POINT;
       
   306     
       
   307     TTime today;
       
   308     today.HomeTime();
       
   309 
       
   310     iInstanceArray.ResetAndDestroy();
       
   311 
       
   312     switch( iObserverType )
       
   313     {
       
   314         case ECalendarObserver:
       
   315             iCalendarEngine->GetEntriesForDayL( *this, today, iInstanceArray );  // TRAPPED!
       
   316             break;
       
   317 
       
   318         case EToDoObserver:
       
   319             iCalendarEngine->GetTodosL( *this, iInstanceArray );  // TRAPPED!
       
   320             break;
       
   321 
       
   322         case ECalendarAndTodoObserver:
       
   323             iCalendarEngine->GetCalendarDataL( *this, iInstanceArray, today, 8/* total number of days to search */ );  // TRAPPED
       
   324             break;
       
   325 
       
   326         default:
       
   327             ASSERT( EFalse );
       
   328     }
       
   329 
       
   330     TRACE_EXIT_POINT;
       
   331 }
       
   332 
       
   333 void CAIAgendaPluginEngineImpl::GetEntriesCompleted(void)
       
   334     {
       
   335     TRACE_ENTRY_POINT;
       
   336     
       
   337     TRAPD(err, DoGetEntriesCompletedL());
       
   338     if(err != KErrNone)
       
   339         {
       
   340         CloseCalendarEngine();
       
   341         }
       
   342     
       
   343     TRACE_EXIT_POINT;    
       
   344     }
       
   345 // ---------------------------------------------------------
       
   346 // CAIAgendaPluginEngineImpl::GetEntriesCompleted
       
   347 // ?implementation_description
       
   348 // (other items were commented in a header).
       
   349 // ---------------------------------------------------------
       
   350 //
       
   351 void CAIAgendaPluginEngineImpl::DoGetEntriesCompletedL(void)
       
   352 {
       
   353     TRACE_ENTRY_POINT;
       
   354     
       
   355     iDBState = EDBOpen;  // EDBReading -> EDBOpen
       
   356 
       
   357     if( !iNeedsUpdate )
       
   358     {
       
   359         RemoveExpiredEntries();
       
   360 
       
   361         if( HasEventsForTodayL() )
       
   362         {
       
   363             SetTimerForNextExpiringEventL();
       
   364             NotifyObserverAndCloseDB();
       
   365         }
       
   366         else
       
   367         {
       
   368             iFetchState = EFetchFuture;
       
   369             StateMachine();
       
   370         }
       
   371     }
       
   372     else
       
   373     {
       
   374         StateMachine();
       
   375     }
       
   376  
       
   377     TRACE_EXIT_POINT;
       
   378 }
       
   379 
       
   380 void CAIAgendaPluginEngineImpl::GetFutureData(void)
       
   381     {
       
   382     TRACE_ENTRY_POINT;
       
   383     
       
   384     TRAPD(err, DoGetFutureDataL());
       
   385     if(err != KErrNone)
       
   386         {
       
   387         CloseCalendarEngine();
       
   388         }
       
   389     
       
   390     TRACE_EXIT_POINT;    
       
   391     }
       
   392 // ---------------------------------------------------------
       
   393 // CAIAgendaPluginEngineImpl::GetFutureData
       
   394 // ?implementation_description
       
   395 // (other items were commented in a header).
       
   396 // ---------------------------------------------------------
       
   397 //
       
   398 void CAIAgendaPluginEngineImpl::DoGetFutureDataL(void)
       
   399 {
       
   400     TRACE_ENTRY_POINT;
       
   401     
       
   402     TTime tomorrow;
       
   403     tomorrow.HomeTime();
       
   404     tomorrow += TTimeIntervalDays( 1 );
       
   405     const TInt daysTosearch( 7 );
       
   406 
       
   407     iCalendarEngine->GetEventForNextSevenDaysL( *this, tomorrow, daysTosearch, iInstanceArray );  // TRAPPED!
       
   408  
       
   409     TRACE_EXIT_POINT;
       
   410 }
       
   411 
       
   412 // ---------------------------------------------------------
       
   413 // CAIAgendaPluginEngineImpl::GetEntriesCompleted
       
   414 // ?implementation_description
       
   415 // (other items were commented in a header).
       
   416 // ---------------------------------------------------------
       
   417 //
       
   418 void CAIAgendaPluginEngineImpl::GetFutureEventCompleted(void)
       
   419 {
       
   420     TRACE_ENTRY_POINT;
       
   421     
       
   422     iDBState = EDBOpen;  // EDBReading -> EDBOpen
       
   423 
       
   424     if( !iNeedsUpdate )
       
   425     {
       
   426         NotifyObserverAndCloseDB();
       
   427     }
       
   428     else
       
   429     {
       
   430         StateMachine();
       
   431     }
       
   432     
       
   433     TRACE_EXIT_POINT;
       
   434 }
       
   435 
       
   436 // ---------------------------------------------------------
       
   437 // CAIAgendaPluginEngineImpl::GetTodosCompleted
       
   438 // ?implementation_description
       
   439 // (other items were commented in a header).
       
   440 // ---------------------------------------------------------
       
   441 //
       
   442 void CAIAgendaPluginEngineImpl::GetTodosCompleted(void)
       
   443 {
       
   444     TRACE_ENTRY_POINT;
       
   445     
       
   446     iDBState = EDBOpen;  // EDBReading -> EDBOpen
       
   447 
       
   448     if( !iNeedsUpdate )
       
   449     {
       
   450         NotifyObserverAndCloseDB();
       
   451     }
       
   452     else
       
   453     {
       
   454         StateMachine();
       
   455     }
       
   456     
       
   457     TRACE_EXIT_POINT;
       
   458 }
       
   459 
       
   460 void CAIAgendaPluginEngineImpl::GetCalendarDataCompleted(void)
       
   461     {
       
   462     TRACE_ENTRY_POINT;
       
   463     
       
   464     TRAPD(err, DoGetCalendarDataCompletedL());
       
   465     if(err != KErrNone)
       
   466         {
       
   467         CloseCalendarEngine();
       
   468         }
       
   469     
       
   470     TRACE_EXIT_POINT;    
       
   471     }
       
   472     
       
   473 // ---------------------------------------------------------
       
   474 // CAIAgendaPluginEngineImpl::GetCalendarDataCompleted
       
   475 // ?implementation_description
       
   476 // (other items were commented in a header).
       
   477 // ---------------------------------------------------------
       
   478 //
       
   479 void CAIAgendaPluginEngineImpl::DoGetCalendarDataCompletedL(void)
       
   480 {
       
   481     TRACE_ENTRY_POINT;
       
   482     
       
   483     iDBState = EDBOpen;  // EDBReading -> EDBOpen
       
   484 
       
   485     if( !iNeedsUpdate )
       
   486     {
       
   487         RemoveExpiredEntries();
       
   488         SetTimerForNextExpiringEventL();
       
   489         NotifyObserverAndCloseDB();
       
   490     }
       
   491     else
       
   492     {
       
   493         StateMachine();
       
   494     }
       
   495     
       
   496     TRACE_EXIT_POINT;
       
   497 }
       
   498 
       
   499 // ---------------------------------------------------------
       
   500 // CAIAgendaPluginEngineImpl::HandleError
       
   501 // ?implementation_description
       
   502 // (other items were commented in a header).
       
   503 // ---------------------------------------------------------
       
   504 //
       
   505 void CAIAgendaPluginEngineImpl::HandleError(TInt aError)
       
   506 {
       
   507     TRACE_ENTRY_POINT;
       
   508     
       
   509     // ignore engine cancellation if we're already offline...
       
   510     if( aError != KErrCancel && iDBState != EDBOffline )
       
   511     {
       
   512         // reset the state machine (no notification to the client)
       
   513         CloseCalendarEngine();
       
   514         // Just to make sure the UI gets updated after an error
       
   515         iExpirationTimer->Cancel();
       
   516         iRefreshTimer->Cancel();
       
   517         iRefreshCounter = 0;
       
   518         const TTimeIntervalMicroSeconds32 oneMinute( 60 * 1000000 );
       
   519         iRefreshTimer->After( oneMinute );  // refresh after one minute
       
   520     }
       
   521     
       
   522     TRACE_EXIT_POINT;
       
   523 }
       
   524 
       
   525 // ---------------------------------------------------------
       
   526 // CAIAgendaPluginEngineImpl::NotifyObserverAndCloseDB
       
   527 // ?implementation_description
       
   528 // (other items were commented in a header).
       
   529 // ---------------------------------------------------------
       
   530 //
       
   531 void CAIAgendaPluginEngineImpl::NotifyObserverAndCloseDB(void)
       
   532 {
       
   533     TRACE_ENTRY_POINT;
       
   534     
       
   535     iDataChangeObserver.PluginDataChanged( iInstanceArray, iHadEvents );
       
   536     CloseCalendarEngine();
       
   537     
       
   538     TRACE_EXIT_POINT;
       
   539 }
       
   540 
       
   541 // ---------------------------------------------------------
       
   542 // CAIAgendaPluginEngineImpl::CloseCalendarEngine
       
   543 // ?implementation_description
       
   544 // (other items were commented in a header).
       
   545 // ---------------------------------------------------------
       
   546 //
       
   547 void CAIAgendaPluginEngineImpl::CloseCalendarEngine(void)
       
   548 {
       
   549     TRACE_ENTRY_POINT;
       
   550     
       
   551     iDBState = EDBOffline;  // EDBBOpen -> EDBOffline
       
   552 
       
   553     // We can't keep the entries w/o an open session!
       
   554     iInstanceArray.ResetAndDestroy();
       
   555 
       
   556     delete iCalendarEngine;
       
   557     iCalendarEngine = NULL;
       
   558 
       
   559     iSession.Uninitialize();
       
   560     
       
   561     TRACE_EXIT_POINT;
       
   562 }
       
   563 
       
   564 void CAIAgendaPluginEngineImpl::RemoveExpiredEntries(void)
       
   565     {
       
   566     TRACE_ENTRY_POINT;
       
   567     
       
   568     TRAPD(err, DoRemoveExpiredEntriesL());
       
   569     if(err != KErrNone)
       
   570         {
       
   571         CloseCalendarEngine();
       
   572         }
       
   573     
       
   574     TRACE_EXIT_POINT;    
       
   575     }
       
   576 
       
   577 // ---------------------------------------------------------
       
   578 // CAIAgendaPluginEngineImpl::RemoveExpiredEntries
       
   579 // ?implementation_description
       
   580 // (other items were commented in a header).
       
   581 // ---------------------------------------------------------
       
   582 //
       
   583 void CAIAgendaPluginEngineImpl::DoRemoveExpiredEntriesL(void)
       
   584 {
       
   585     TRACE_ENTRY_POINT;
       
   586     
       
   587     const TTimeIntervalMinutes thirtyMinutes( 30 );
       
   588     const TTimeIntervalMinutes oneMinute( 1 );
       
   589     TTime now;
       
   590     now.HomeTime();
       
   591     iHadEvents = EFalse;
       
   592 
       
   593     for( TInt i(0), count(iInstanceArray.Count()); i<count; i++ )
       
   594     {
       
   595         // for each timed entry (appointment)
       
   596         if( iInstanceArray[i]->Entry().EntryTypeL() == CCalEntry::EAppt )
       
   597         {
       
   598             TBool expired( EFalse );
       
   599 
       
   600             if( iObserverType == ECalendarAndTodoObserver )
       
   601             {
       
   602                 // end time already passed?
       
   603                 if( now >= iInstanceArray[i]->EndTimeL().TimeLocalL() +oneMinute )
       
   604                 {
       
   605                     expired = ETrue;
       
   606                 }
       
   607             }
       
   608             else
       
   609             {
       
   610                 const TTime startTime = iInstanceArray[i]->StartTimeL().TimeLocalL();
       
   611 
       
   612                 TTimeIntervalMinutes currentEventAge( 0 );
       
   613                 now.MinutesFrom( startTime, currentEventAge );
       
   614 
       
   615                 TTimeIntervalMinutes diffToNextItem( 0 );
       
   616                 DiffToNextEventL( i, diffToNextItem );
       
   617 
       
   618                 // remove if start time more than 30 minutes ago
       
   619                 // OR
       
   620                 // start time passed AND next event starting in 30 minutes
       
   621                 if( currentEventAge >= thirtyMinutes ||
       
   622                     ( currentEventAge >= oneMinute && ( diffToNextItem >= oneMinute && diffToNextItem <= thirtyMinutes ) ) )
       
   623                 // NOTE! if you change the comparison values above remember to check the SetTimerForNextExpiringEventL
       
   624                 // implementation to prevent timer expiration loop!
       
   625 
       
   626                 {
       
   627                     expired = ETrue;
       
   628                 }
       
   629             }
       
   630 
       
   631             if( expired )
       
   632             {
       
   633                 delete iInstanceArray[i];
       
   634                 iInstanceArray.Remove( i );
       
   635                 count--;
       
   636                 i--;
       
   637                 iHadEvents = ETrue;
       
   638             }
       
   639         }
       
   640     }
       
   641     iInstanceArray.Compress();
       
   642 
       
   643     TRACE_EXIT_POINT;
       
   644 }
       
   645 
       
   646 // ---------------------------------------------------------
       
   647 // CAIAgendaPluginEngineImpl::HasEventsForTodayL
       
   648 // ?implementation_description
       
   649 // (other items were commented in a header).
       
   650 // ---------------------------------------------------------
       
   651 //
       
   652 TBool CAIAgendaPluginEngineImpl::HasEventsForTodayL(void)
       
   653 {
       
   654     TRACE_ENTRY_POINT;
       
   655     
       
   656     for( TInt i(0), count(iInstanceArray.Count()); i<count; i++ )
       
   657     {
       
   658         if( iInstanceArray[i]->Entry().EntryTypeL() == CCalEntry::EAppt )
       
   659         {
       
   660             TRACE_EXIT_POINT;
       
   661             return ETrue;
       
   662         }
       
   663     }
       
   664     TRACE_EXIT_POINT;
       
   665     return EFalse;
       
   666 }
       
   667 
       
   668 // ---------------------------------------------------------
       
   669 // CAIAgendaPluginEngineImpl::SetTimerForNextExpiringEventL
       
   670 // ?implementation_description
       
   671 // (other items were commented in a header).
       
   672 // ---------------------------------------------------------
       
   673 //
       
   674 void CAIAgendaPluginEngineImpl::SetTimerForNextExpiringEventL(void)
       
   675 {
       
   676     TRACE_ENTRY_POINT;
       
   677     
       
   678     const TTimeIntervalMinutes oneMinute( 1 );
       
   679     const TTimeIntervalMinutes thirtyMinutes( 30 );
       
   680 
       
   681     if( iObserverType == ECalendarAndTodoObserver )
       
   682     {
       
   683         TTime now;  now.HomeTime();
       
   684         TTime tomorrow( 0 );
       
   685         tomorrow += now.DaysFrom( tomorrow );
       
   686         tomorrow += TTimeIntervalDays( 1 );
       
   687 
       
   688         /**
       
   689         * Refresh is needed whenever an appointment passes its end time or becomes over 30 minutes old:
       
   690         * Loop through all EAppt items and find the nearest refresh/expiration time.
       
   691         **/
       
   692         TTime expiryTime( tomorrow ); // initial value (won't cause timer to be set)
       
   693 
       
   694         for( TInt i(0), count(iInstanceArray.Count()); i<count; i++ )
       
   695         {
       
   696             if( iInstanceArray[i]->Entry().EntryTypeL() == CCalEntry::EAppt )
       
   697             {
       
   698                 const TTime endTime( iInstanceArray[i]->EndTimeL().TimeLocalL() +oneMinute );
       
   699                 TTime ongoingTime( iInstanceArray[i]->StartTimeL().TimeLocalL() +thirtyMinutes +oneMinute );
       
   700 
       
   701                 // using already expired timer would cause a nasty refresh loop
       
   702                 if( ongoingTime < now  )
       
   703                 {
       
   704                     ongoingTime = endTime;
       
   705                 }
       
   706                 // select the nearest time
       
   707                 expiryTime = Min( expiryTime, Min( endTime, ongoingTime ) );
       
   708             }
       
   709         }
       
   710 
       
   711         // timer is set only for times between "now" and end of the day
       
   712         if( expiryTime > now && expiryTime < tomorrow  )
       
   713         {
       
   714             iExpirationTimer->At( expiryTime );
       
   715         }
       
   716     }
       
   717     else
       
   718     {
       
   719         for( TInt i(0), count(iInstanceArray.Count()); i<count; i++ )
       
   720         {
       
   721             if( iInstanceArray[i]->Entry().EntryTypeL() == CCalEntry::EAppt )
       
   722             {
       
   723                 const TTime startTime = iInstanceArray[i]->StartTimeL().TimeLocalL();
       
   724 
       
   725                 TTimeIntervalMinutes diffToNextItem( 0 );
       
   726                 DiffToNextEventL( i, diffToNextItem );
       
   727 
       
   728                 // if next event is starting from 1 to 30 minutes after the current one
       
   729                 if( diffToNextItem >= oneMinute && diffToNextItem <= thirtyMinutes )
       
   730                 {
       
   731                     iExpirationTimer->At( startTime + oneMinute );
       
   732                 }
       
   733                 else
       
   734                 {
       
   735                     iExpirationTimer->At( startTime  + thirtyMinutes );
       
   736                 }
       
   737                 break;  // only one timer... 
       
   738             }
       
   739         }
       
   740     }
       
   741     
       
   742     TRACE_EXIT_POINT;
       
   743 }
       
   744 
       
   745 // ---------------------------------------------------------
       
   746 // CAIAgendaPluginEngineImpl::DiffToNextEventL
       
   747 // ?implementation_description
       
   748 // (other items were commented in a header).
       
   749 // ---------------------------------------------------------
       
   750 //
       
   751 void CAIAgendaPluginEngineImpl::DiffToNextEventL(const TInt aIndex, TTimeIntervalMinutes& aDifference)
       
   752 {
       
   753     TRACE_ENTRY_POINT;
       
   754     
       
   755     const TInt count( iInstanceArray.Count() );
       
   756 
       
   757     if( aIndex+1 < count )
       
   758     {
       
   759         TInt index( aIndex );
       
   760         const TTime startTime = iInstanceArray[ index ]->StartTimeL().TimeLocalL();
       
   761 
       
   762         // find next item with different start time (if exist)
       
   763         while( ++index < count )
       
   764         {
       
   765             if( iInstanceArray[ index ]->Entry().EntryTypeL() == CCalEntry::EAppt )
       
   766             {
       
   767                 const TTime nextStartTime = iInstanceArray[ index ]->StartTimeL().TimeLocalL();
       
   768 
       
   769                 if( nextStartTime != startTime )
       
   770                 {
       
   771                     startTime.MinutesFrom( nextStartTime, aDifference );
       
   772                     aDifference = Abs( aDifference.Int() );
       
   773                     break;
       
   774                 }
       
   775             }
       
   776         }
       
   777     }
       
   778     
       
   779     TRACE_EXIT_POINT;
       
   780 }
       
   781 
       
   782 // ---------------------------------------------------------
       
   783 // CAIAgendaPluginEngineImpl::EventExpiredCallBack
       
   784 // ?implementation_description
       
   785 // (other items were commented in a header).
       
   786 // ---------------------------------------------------------
       
   787 //
       
   788 TInt CAIAgendaPluginEngineImpl::EventExpiredCallBack(TAny* aPtr)
       
   789 {
       
   790     TRACE_ENTRY_POINT;
       
   791     
       
   792     CAIAgendaPluginEngineImpl* thisPtr = static_cast<CAIAgendaPluginEngineImpl*>( aPtr );
       
   793     thisPtr->StateMachine();
       
   794     
       
   795     TRACE_EXIT_POINT;
       
   796     return 0; // ignored
       
   797 }
       
   798 
       
   799 // ---------------------------------------------------------
       
   800 // CAIAgendaPluginEngineImpl::RefreshTimerCallBack
       
   801 // ?implementation_description
       
   802 // (other items were commented in a header).
       
   803 // ---------------------------------------------------------
       
   804 //
       
   805 TInt CAIAgendaPluginEngineImpl::RefreshTimerCallBack(TAny* aPtr)
       
   806 {
       
   807     TRACE_ENTRY_POINT;
       
   808     
       
   809     CAIAgendaPluginEngineImpl* thisPtr = static_cast<CAIAgendaPluginEngineImpl*>( aPtr );
       
   810     const TUint count( thisPtr->iRefreshCounter );
       
   811     thisPtr->iRefreshCounter = 0;
       
   812 
       
   813     if( !count || count > 1 )
       
   814     {
       
   815         thisPtr->StateMachine();
       
   816     }
       
   817     
       
   818     TRACE_EXIT_POINT;
       
   819     return 0; // ignored
       
   820 }
       
   821 
       
   822 // ---------------------------------------------------------
       
   823 // CAIAgendaPluginEngineImpl::HandlePropertyChange
       
   824 // ?implementation_description
       
   825 // (other items were commented in a header).
       
   826 // ---------------------------------------------------------
       
   827 //
       
   828 void CAIAgendaPluginEngineImpl::HandlePropertyChange(const TUid& /*aCategory*/, const TUint& /*aKey*/, const TInt& /*aValue*/)
       
   829 {
       
   830     TRACE_ENTRY_POINT;
       
   831     
       
   832     SafeRefresh();
       
   833     
       
   834     TRACE_EXIT_POINT;
       
   835 }
       
   836 
       
   837 // ---------------------------------------------------------
       
   838 // CAIAgendaPluginEngineImpl::CalendarInfoChangeNotificationL
       
   839 // ?implementation_description
       
   840 // (other items were commented in a header).
       
   841 // ---------------------------------------------------------
       
   842 //
       
   843 void CAIAgendaPluginEngineImpl::CalendarInfoChangeNotificationL(
       
   844         RPointerArray<CCalFileChangeInfo>& aCalendarInfoChangeEntries)
       
   845     {
       
   846     TRACE_ENTRY_POINT
       
   847     TInt count = aCalendarInfoChangeEntries.Count();
       
   848     //if(count)
       
   849         {
       
   850         SafeRefresh();
       
   851         }
       
   852     TRACE_EXIT_POINT
       
   853     }
       
   854 // ---------------------------------------------------------
       
   855 // CAIAgendaPluginEngineImpl::SafeRefresh
       
   856 // ?implementation_description
       
   857 // (other items were commented in a header).
       
   858 // ---------------------------------------------------------
       
   859 //
       
   860 void CAIAgendaPluginEngineImpl::SafeRefresh(void)
       
   861 {
       
   862     TRACE_ENTRY_POINT;
       
   863     
       
   864     const TTimeIntervalMicroSeconds32 waitBeforeRefresh( 1500000 ); // 1.5 seconds
       
   865 
       
   866     // Let the first refresh call through...
       
   867     // iRefreshCounter is used to prevent double refresh and will reset in RefreshTimerCallBack.
       
   868     if( !iRefreshCounter )
       
   869     {
       
   870         StateMachine();
       
   871     }
       
   872     iRefreshCounter++;
       
   873 
       
   874     // Restart the timer for every request to prevent excessive refresh.
       
   875     // There will be only a single refresh call (RefreshTimerCallBack) when the timer expires.
       
   876     iRefreshTimer->Cancel();
       
   877     iRefreshTimer->After( waitBeforeRefresh );
       
   878     
       
   879     TRACE_EXIT_POINT;
       
   880 }
       
   881 
       
   882 // ---------------------------------------------------------
       
   883 // CAIAgendaPluginEngineImpl::CalendarServerInitialized
       
   884 // ?implementation_description
       
   885 // (other items were commented in a header).
       
   886 // ---------------------------------------------------------
       
   887 //
       
   888 void CAIAgendaPluginEngineImpl::CalendarServerInitialized(void)
       
   889 {
       
   890     TRACE_ENTRY_POINT;
       
   891     
       
   892     iDBState = EDBInitialized;  // EDBInitializing -> EDBInitialized
       
   893     StateMachine();
       
   894     
       
   895     TRACE_EXIT_POINT;
       
   896 }
       
   897 
       
   898 // ---------------------------------------------------------
       
   899 // CAIAgendaPluginEngineImpl::EnvironmentChangeCallBack
       
   900 // ?implementation_description
       
   901 // (other items were commented in a header).
       
   902 // ---------------------------------------------------------
       
   903 //
       
   904 TInt CAIAgendaPluginEngineImpl::EnvironmentChangeCallBack(TAny* aPtr)
       
   905 {
       
   906     TRACE_ENTRY_POINT;
       
   907     
       
   908     CAIAgendaPluginEngineImpl* thisPtr = static_cast<CAIAgendaPluginEngineImpl*>( aPtr );
       
   909     const TInt changes( thisPtr->iEnvironmentChangeNotifier->Change() );
       
   910 
       
   911     // IF  iObserverType is ECalendarObserver or ECalendarAndTodoObserver
       
   912     //     AND system time/day has changed
       
   913     // OR
       
   914     // a locale change
       
   915     if( ( (thisPtr->iObserverType == ECalendarObserver || 
       
   916            thisPtr->iObserverType == ECalendarAndTodoObserver)
       
   917           && 
       
   918           (changes & EChangesMidnightCrossover ||
       
   919            changes & EChangesSystemTime) )
       
   920         ||
       
   921         changes & EChangesLocale )
       
   922         {
       
   923             thisPtr->SafeRefresh();
       
   924         }
       
   925     
       
   926     TRACE_EXIT_POINT;
       
   927     return EFalse;
       
   928 }
       
   929 
       
   930 // End of File