/*
* 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