calendarui/controller/src/calendbchangenotifier.cpp
changeset 0 f979ecb2b13e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/calendarui/controller/src/calendbchangenotifier.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,287 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Notifies observers of external changes to the calendar database
+*
+*/
+
+
+
+//debug
+#include "calendarui_debug.h"
+
+// INCLUDE FILES
+#include "calendbchangenotifier.h"    // CCalenDbChangeNotifier
+#include "calenglobaldata.h"            // Calendar global data
+#include <calsession.h>                 // CalSession
+
+// -----------------------------------------------------------------------------
+// KTimerResolution limits the number of notifications sent to registered
+// MCalenDBChangeObserver instances.  Notifications may come from 
+// MCalChangeCallBack2 at a very high rate which could impact performance, 
+// for example by causing constant view refreshes.
+// CCalenDbChangeNotifier notifies observers when KTimerResolution has elapsed
+// since the last notification was received from MCalChangeCallBack2
+// -----------------------------------------------------------------------------
+const TInt KTimerResolution = 1000000;  // 1 Second
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::CCalenDbChangeNotifier
+// C++ default constructor can NOT contain any code, that might leave.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+CCalenDbChangeNotifier::CCalenDbChangeNotifier( CCalenGlobalData& aGlobalData ) 
+    : CActive( EPriorityNormal ),
+      iGlobalData( aGlobalData )
+    {
+    TRACE_ENTRY_POINT;
+
+    iRestartTimer = EFalse;
+
+    TRACE_EXIT_POINT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::NewL
+// Two-phased constructor.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+CCalenDbChangeNotifier* CCalenDbChangeNotifier::NewL( CCalenGlobalData& aGlobalData )
+    {
+    TRACE_ENTRY_POINT;
+
+    CCalenDbChangeNotifier* self = new( ELeave ) CCalenDbChangeNotifier( aGlobalData );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    TRACE_EXIT_POINT;
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::ConstructL
+// Symbian 2nd phase constructor can leave.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+void CCalenDbChangeNotifier::ConstructL()
+    {
+    TRACE_ENTRY_POINT;
+
+    // We want to receive notifications for the full agenda date range
+    TCalTime start, end;
+    start.SetTimeUtcL( TCalTime::MinTime() );
+    end.SetTimeUtcL( TCalTime::MaxTime() );
+    CalCommon::TCalTimeRange range( start, end ); 
+
+    // Create a notification filter
+    iCalChangeFilter = CCalChangeNotificationFilter::NewL(
+                                                        MCalChangeCallBack2::EChangeEntryAll, 
+                                                        ETrue, 
+                                                        range );
+
+    // Enable database change notifications on current global data session
+    iGlobalData.CalSessionL().StartChangeNotification( *this, *iCalChangeFilter );
+
+    // Create a timer to limit the number of notifications broadcast
+    iNotificationTimer.CreateLocal();
+
+    // Active object, add to active scheduler
+    CActiveScheduler::Add( this );
+
+    TRACE_EXIT_POINT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::~CCalenDbChangeNotifier
+// Destructor
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+CCalenDbChangeNotifier::~CCalenDbChangeNotifier()
+    {
+    TRACE_ENTRY_POINT;
+
+    Cancel();
+    // Reset the observer array.  Array contents are NOT owned by this class
+    iDBObservers.Reset();
+
+    iNotificationTimer.Close();
+
+    // Disable database change notifications on current global data session   
+    PIM_TRAPD_HANDLE( iGlobalData.CalSessionL().StopChangeNotification() );
+
+    // Destroy the notification filter
+    delete iCalChangeFilter;
+    
+    TRACE_EXIT_POINT;    
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::LastDBModificationTime
+// Returns the time of the last database change notification.  This may not be
+// the time of the last notification sent to MCalenDBChangeObservers.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+TTime CCalenDbChangeNotifier::LastDBModificationTime() const
+    {
+    TRACE_ENTRY_POINT;
+
+    TRACE_EXIT_POINT;
+    return iLastDbChangeNotification;
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::CalChangeNotification
+// Called when a change to the agenda database occurs from a different session
+// to the one we are currently using.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+void CCalenDbChangeNotifier::CalChangeNotification( RArray<TCalChangeEntry>& /*aChangeItems*/ )
+    {
+    TRACE_ENTRY_POINT;
+
+    // Always update the last notification time, even if we don't notify 
+    // our observers
+    iLastDbChangeNotification.UniversalTime();
+    if( !IsActive() )
+        {
+        iNotificationTimer.After( iStatus, KTimerResolution );
+        SetActive();
+        }
+    else
+        {
+        iRestartTimer = ETrue;
+        iNotificationTimer.Cancel();
+        }
+
+    TRACE_EXIT_POINT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::RegisterObserverL
+// Adds the passed observer to the observer array.  All observers in the array 
+// will be notified of changes to the agenda database.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------    
+ void CCalenDbChangeNotifier::RegisterObserverL( MCalenDBChangeObserver& aDBObserver )
+    {
+    TRACE_ENTRY_POINT;
+
+    iDBObservers.Append( &aDBObserver );
+
+    TRACE_EXIT_POINT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCalenDbChangeNotifier::DeRegisterObserverL
+// Removes the passed observer to the observer array.  All observers in the array 
+// will be notified of changes to the agenda database.
+// -----------------------------------------------------------------------------       
+void CCalenDbChangeNotifier::DeRegisterObserverL( MCalenDBChangeObserver& aDBObserver )
+    {
+    TRACE_ENTRY_POINT;
+
+    for( TInt x = 0; x < iDBObservers.Count(); ++x )
+        {
+        if( iDBObservers[x] == &aDBObserver )
+            {
+            iDBObservers.Remove( x );
+            return;
+            }
+        }
+    User::Leave( KErrNotFound );
+
+    TRACE_EXIT_POINT;
+    }
+
+// -----------------------------------------------------------------------------       
+// CCalenDbChangeNotifier::RunL
+// From CActive::RunL
+// Called when notification timer expires
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------       
+void CCalenDbChangeNotifier::RunL()
+    {
+    TRACE_ENTRY_POINT;
+
+    switch( iStatus.Int() )
+        {
+        case KErrCancel:
+            {
+            // The normal reason for the timer being cancelled is another
+            // database change.  Restart the timer.
+            if( iRestartTimer )
+                {
+                iRestartTimer = EFalse;
+                iNotificationTimer.After( iStatus, KTimerResolution );
+                SetActive();
+                }        
+            }
+        break;
+
+        case KErrNone:
+            {
+            //Timer completion, notify observers
+            for( TInt x = 0; x < iDBObservers.Count(); ++x )
+                {
+                iDBObservers[x]->HandleDBChangeL();
+                }
+            }
+        break;
+
+        default:
+            {
+            User::Leave( KErrArgument );
+            }
+        break;
+        }
+
+    TRACE_EXIT_POINT;
+    }
+
+// -----------------------------------------------------------------------------       
+// CCalenDbChangeNotifier::RunError
+// From CActive::RunError
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+TInt CCalenDbChangeNotifier::RunError( TInt aError )
+    {
+    TRACE_ENTRY_POINT;
+
+    //RunL leaving means that the view could not be refreshed.
+    //Theres not much we can do except be ready for the next database event.
+    iRestartTimer = EFalse;
+
+    TRACE_EXIT_POINT;
+    return aError;
+    }
+
+// -----------------------------------------------------------------------------       
+// CCalenDbChangeNotifier::DoCancel
+// From CActive::DoCancel
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+void CCalenDbChangeNotifier::DoCancel()
+    {
+    TRACE_ENTRY_POINT;
+
+    // Stop the notification timer
+    iRestartTimer = EFalse;
+    iNotificationTimer.Cancel();
+
+    TRACE_EXIT_POINT;
+    }
+
+// End of File