--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/src/cesmrfieldeventqueue.cpp Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,271 @@
+/*
+* Copyright (c) 2009 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: Field event queue implementation
+*
+*/
+
+
+#include "emailtrace.h"
+#include "cesmrfieldeventqueue.h"
+
+#include <eikenv.h> // for CEikonEnv::HandleError
+
+#include "mesmrfieldevent.h"
+#include "mesmrfieldeventobserver.h"
+#include "mesmrfieldeventnotifier.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::CESMRFieldEventQueue
+// ---------------------------------------------------------------------------
+//
+CESMRFieldEventQueue::CESMRFieldEventQueue()
+ {
+ FUNC_LOG;
+ // Do nothing
+ }
+
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::ConstructL()
+ {
+ FUNC_LOG;
+ iIdle = CIdle::NewL( CActive::EPriorityStandard );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::NewL
+// ---------------------------------------------------------------------------
+//
+CESMRFieldEventQueue* CESMRFieldEventQueue::NewL()
+ {
+ FUNC_LOG;
+ CESMRFieldEventQueue* self = CESMRFieldEventQueue::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::NewLC
+// ---------------------------------------------------------------------------
+//
+CESMRFieldEventQueue* CESMRFieldEventQueue::NewLC()
+ {
+ FUNC_LOG;
+ CESMRFieldEventQueue* self = new( ELeave ) CESMRFieldEventQueue;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::~CESMRFieldEventQueue
+// ---------------------------------------------------------------------------
+//
+CESMRFieldEventQueue::~CESMRFieldEventQueue()
+ {
+ FUNC_LOG;
+ if ( iIdle )
+ {
+ iIdle->Cancel();
+ delete iIdle;
+ }
+ iObservers.Reset();
+ iEventQueue.ResetAndDestroy();
+ }
+
+
+// ---------------------------------------------------------------------------
+// From class MESMRFieldEventQueue
+// CESMRFieldEventQueue::AddObserverL
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::AddObserverL( MESMRFieldEventObserver* aObserver )
+ {
+ FUNC_LOG;
+ TInt error = iObservers.InsertInAddressOrder( aObserver );
+ if ( error && error != KErrAlreadyExists )
+ {
+ User::Leave( error );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MESMRFieldEventQueue
+// CESMRFieldEventQueue::RemoveObserver
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::RemoveObserver( MESMRFieldEventObserver* aObserver )
+ {
+ FUNC_LOG;
+ TInt index = iObservers.FindInAddressOrder( aObserver );
+ if ( index > KErrNotFound )
+ {
+ iObservers.Remove( index );
+ if ( index < iNotifyIndex )
+ {
+ // Notifying is on going.
+ // aObserver has been already notified, so indexes after it will
+ // decrease by one. Decrease iNotifyIndex also by one.
+ iNotifyIndex = Max( 0, --iNotifyIndex );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MESMRFieldEventQueue
+// CESMRFieldEventQueue::NotifyEventL
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::NotifyEventL( const MESMRFieldEvent& aEvent )
+ {
+ FUNC_LOG;
+ // Reset observer index
+ iNotifyIndex = 0;
+
+ // Get event sender
+ MESMRFieldEventObserver* sender = NULL;
+ if ( aEvent.Source() )
+ {
+ sender = aEvent.Source()->EventObserver();
+ }
+
+ while ( iNotifyIndex < iObservers.Count() )
+ {
+ MESMRFieldEventObserver* observer = iObservers[ iNotifyIndex++ ];
+ if ( observer && observer != sender )
+ {
+ // Notify event to other observers but the sender
+ observer->HandleFieldEventL( aEvent );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MESMRFieldEventQueue
+// CESMRFieldEventQueue::NotifyEventAsyncL
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::NotifyEventAsyncL( MESMRFieldEvent* aEvent )
+ {
+ FUNC_LOG;
+ // Append event to queue
+ iEventQueue.AppendL( aEvent );
+
+ // Start queue
+ Start();
+ }
+
+// ---------------------------------------------------------------------------
+// From class MESMRFieldEventQueue
+// CESMRFieldEventQueue::CancelEvent
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::CancelEvent( MESMRFieldEvent* aEvent )
+ {
+ FUNC_LOG;
+ // Find event from queue
+ TInt index = iEventQueue.Find( aEvent );
+ if ( index > KErrNotFound )
+ {
+ // Remove and delete event
+ iEventQueue.Remove( index );
+ delete aEvent;
+
+ // Stop queue if it is empty.
+ if ( iEventQueue.Count() == 0 )
+ {
+ iIdle->Cancel();
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::NotifyCallback
+// CIdle callback function
+// ---------------------------------------------------------------------------
+//
+TInt CESMRFieldEventQueue::NotifyCallBack( TAny* aPtr )
+ {
+ FUNC_LOG;
+ TBool ret = EFalse;
+ CESMRFieldEventQueue* self = static_cast< CESMRFieldEventQueue* >( aPtr );
+ if ( self )
+ {
+ TRAPD( error, self->DoNotifyEventAsyncL() )
+ if ( error != KErrNone &&
+ error != KErrCancel &&
+ error != KErrArgument )
+ {
+ // Show error note
+ CEikonEnv::Static()->HandleError( error ); // codescanner::eikonenvstatic
+ }
+ ret = self->HasEvents();
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::DoNotifyEventAsyncL
+// Removes event from the queue and notifies it to the observers.
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::DoNotifyEventAsyncL()
+ {
+ FUNC_LOG;
+ // Remove first event from queue
+ MESMRFieldEvent* event = iEventQueue[ 0 ];
+ iEventQueue.Remove( 0 );
+
+ // Push the event into CleanupStack for NotifyEventL
+ CleanupDeletePushL( event );
+
+ // Notify event to observers synchronously.
+ NotifyEventL( *event );
+ CleanupStack::PopAndDestroy( event );
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::HasEvents
+// Checks if event queue has events.
+// ---------------------------------------------------------------------------
+//
+TBool CESMRFieldEventQueue::HasEvents() const
+ {
+ FUNC_LOG;
+ return ( iEventQueue.Count() > 0 );
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRFieldEventQueue::Start
+// Starts event queue
+// ---------------------------------------------------------------------------
+//
+void CESMRFieldEventQueue::Start()
+ {
+ FUNC_LOG;
+ if ( !iIdle->IsActive() && iEventQueue.Count() > 0 )
+ {
+ iIdle->Start( TCallBack( NotifyCallBack, this ) );
+ }
+ }
+