meetingrequest/mrgui/src/cesmrfieldeventqueue.cpp
branchRCL_3
changeset 25 3533d4323edc
--- /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 ) );
+        }
+    }
+