phonebookengines/VirtualPhonebook/VPbkLdapStore/src/ContactView.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkLdapStore/src/ContactView.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,641 @@
+/*
+* Copyright (c) 2005-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:  CContactView implementation
+*
+*/
+
+
+// INCLUDE FILES
+#include "contactview.h"
+#include "contactlink.h"
+#include "contactstore.h"
+#include "storebookmark.h"
+#include "viewcontact.h"
+
+#include <cvpbksortorder.h>
+#include <vpbkcontactview.hrh>
+#include <mvpbkcontactviewobserver.h>
+#include <mvpbkcontactbookmark.h>
+
+// CONSTANTS
+static const TInt KObserverArrayGranularity = 8;
+
+// -----------------------------------------------------------------------------
+// LDAPNotifyObservers
+// Contact view state notifier callback
+// -----------------------------------------------------------------------------
+//
+static TInt LDAPNotifyObservers(TAny* aThis)
+    {
+    if (aThis)
+        {
+        return static_cast<LDAPStore::CContactView*>(aThis)->NotifyObservers();
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// LDAP Store namespace
+// -----------------------------------------------------------------------------
+namespace LDAPStore {
+
+/**
+*  TContactViewObserver - contact view observer class.
+*  
+*/
+class TContactViewObserver
+    {
+    public:     // TContactViewObserver public constructor
+        /**
+        @function   TContactViewObserver
+        @discussion TContactViewObserver contructor
+        @param      aObserver View observer
+        */
+        inline TContactViewObserver(MVPbkContactViewObserver& aObserver)
+            : iNotifiedState(ENotReady), iObserver(aObserver)
+            {
+            };
+    public:     // TContactViewObserver public members
+
+        /**
+        @function   NotifiedState
+        @discussion Returns notified state
+        @return     Notified view state
+        */
+        inline TViewState NotifiedState() const {
+            return iNotifiedState;
+        }
+        /**
+        @function   SetNotifiedState
+        @discussion Returns notified state
+        @parame     aState Notified view state
+        */
+        inline void SetNotifiedState(TViewState aState) {
+            iNotifiedState = aState;
+        }
+
+        /**
+        @function   Observer
+        @discussion Returns observer
+        @return     Observer
+        */
+        inline MVPbkContactViewObserver& Observer() const {
+            return iObserver;
+        }
+
+    private:    // TContactViewObserver private members
+
+        // Notified state
+        TViewState iNotifiedState;
+
+        // Observer
+        MVPbkContactViewObserver& iObserver;
+    };
+
+// -----------------------------------------------------------------------------
+// CContactView::CContactView
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CContactView::CContactView(CContactStore& aStore,TVPbkContactViewType aType)
+:   iStore(aStore), iType(aType), iViewState(ENotReady)
+    {
+    // No implementation required
+    }
+// -----------------------------------------------------------------------------
+// CContactView::ConstructL
+// CContactView constructor for performing 2nd stage construction
+// -----------------------------------------------------------------------------
+//
+void CContactView::ConstructL(const MVPbkFieldTypeList& aSortOrder)
+    {
+    // Observers
+    iObservers = new (ELeave)
+        CArrayPtrFlat<TContactViewObserver>(KObserverArrayGranularity);
+
+    // Copy the sort order
+    iSortOrder = CVPbkSortOrder::NewL(aSortOrder);
+
+    // Create contact
+    iContact = CViewContact::NewL(*this,*iSortOrder);
+
+    // Create view state notify handler
+    iIdle = CIdle::NewL(CActive::EPriorityIdle);
+
+    // Store initialized and folding view
+    if (iStore.IsInitialized() && iType == EVPbkFoldingView)
+        {
+        // View is ready when store is
+        iViewState = EReady;
+        }
+    else
+        {
+        // Add store observer
+        iStore.AddObserverL(*this);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::NewLC
+// CContactView two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CContactView* CContactView::NewLC(
+    MVPbkContactViewObserver& aObserver,
+    CContactStore&               aStore,
+    const MVPbkFieldTypeList& aSortOrder,
+    TVPbkContactViewType           aType
+)
+    {
+    CContactView* self = new (ELeave)CContactView(aStore,aType);
+    CleanupStack::PushL(self);
+    self->ConstructL(aSortOrder);
+    self->AddObserverL(aObserver);
+    return self;
+    }
+// -----------------------------------------------------------------------------
+// CContactView::NewL
+// CContactView two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CContactView* CContactView::NewL(
+    MVPbkContactViewObserver& aObserver,
+    CContactStore&               aStore,
+    const MVPbkFieldTypeList& aSortOrder,
+    TVPbkContactViewType           aType
+)
+    {
+    CContactView* self = CContactView::NewLC(aObserver,aStore,aSortOrder,aType);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::~CContactView
+// CContactView Destructor
+// -----------------------------------------------------------------------------
+//
+CContactView::~CContactView()
+    {
+    // Callback
+    if (iIdle)
+        {
+        // Always cancel pending operations
+        iIdle->Cancel();
+        // Delete
+        delete iIdle;
+        iIdle = NULL;
+        }
+    // Store contact
+    if (iContact)
+        {
+        delete iContact;
+        iContact = NULL;
+        }
+    // Sort order
+    if (iSortOrder)
+        {
+        delete iSortOrder;
+        iSortOrder = NULL;
+        }
+    // Observers
+    if (iObservers)
+        {
+        iObservers->ResetAndDestroy();
+        delete iObservers;
+        iObservers = NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//                      CContactView public methods
+// -----------------------------------------------------------------------------
+// CContactView::NotifyObservers
+// Notifies observers about view state changes
+// -----------------------------------------------------------------------------
+//
+TInt CContactView::NotifyObservers()
+    {
+    TInt status = ETrue;
+
+    // Observers
+    const TInt count = (iObservers) ? iObservers->Count() : 0;
+
+    // View state
+    TViewState state = State();
+    if (state != EReady)
+        {
+        // Store has contacts - view ready
+        if (iStore.ContactCount() > 0 &&
+            iStore.State() == CContactStore::ERetrieved)
+            {
+            // Set ready
+            iViewState = EReady; state = EReady;
+            }
+        }
+
+    // Notify all
+    for (TInt loop = iObservers->Count() - 1; loop >= 0;loop--)
+        {
+        // This observer
+        TContactViewObserver* op = iObservers->At(loop);
+        if (op && op->NotifiedState() != state)
+            {
+            // View ready
+            if (state == EReady)
+                {
+                op->Observer().ContactViewReady(*this);
+                }
+            else
+            // Not available
+            if (state == ENotAvailable)
+                {
+                op->Observer().ContactViewUnavailable(*this);
+                }
+            // Set state
+            op->SetNotifiedState(state);            
+            }
+        }
+
+    // Observers
+    if (count == 0)
+        {
+        status = EFalse;
+        }
+    // True to continue notification or false when break
+    return status;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::State
+// Returns view state
+// -----------------------------------------------------------------------------
+//
+TViewState CContactView::State() const
+    {
+    return iViewState;
+    }
+// -----------------------------------------------------------------------------
+// CContactView::State
+// Returns view store
+// -----------------------------------------------------------------------------
+//
+CContactStore& CContactView::Store()
+    {
+    return iStore;
+    }
+
+// -----------------------------------------------------------------------------
+//                  MVPbkContactViewBase implementation
+// -----------------------------------------------------------------------------
+// CContactView::Type
+// Returns type of this contact view.
+// -----------------------------------------------------------------------------
+//
+TVPbkContactViewType CContactView::Type() const
+    {
+    return iType;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::ChangeSortOrderL
+// Changes sort order of the view. 
+// -----------------------------------------------------------------------------
+//
+void CContactView::ChangeSortOrderL(const MVPbkFieldTypeList& aSortOrder)
+    {
+    // This is store view sort order does not apply, but
+    CVPbkSortOrder* sp = CVPbkSortOrder::NewL(aSortOrder);
+    delete iSortOrder;
+    iSortOrder = sp;
+    }
+// -----------------------------------------------------------------------------
+// CContactView::SortOrder
+// Returns the current sort order of the view.
+// -----------------------------------------------------------------------------
+//
+const MVPbkFieldTypeList& CContactView::SortOrder() const
+    {
+    return *iSortOrder;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::RefreshL
+// Refreshes the view contents.
+// -----------------------------------------------------------------------------
+//
+void CContactView::RefreshL()
+    {
+    // Rebuild view
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::ContactCountL
+// Returns the number of contacts in this view
+// -----------------------------------------------------------------------------
+//
+TInt CContactView::ContactCountL() const
+    {
+    // Contact count
+    TInt count = 0;
+    // Contacts view
+    if (iType == EVPbkContactsView)
+        {
+        // Get from store
+        count = iStore.ContactCount();
+        }
+    else
+    // Folding view, one store
+    if (iType == EVPbkFoldingView)
+        {
+        count = 1;
+        }
+    return count;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::ContactAtL
+// Returns a contact in this view.
+// -----------------------------------------------------------------------------
+//
+const MVPbkViewContact& CContactView::ContactAtL(TInt aIndex) const
+    {
+    // Contacts view
+    if (iType == EVPbkContactsView)
+        {
+        // Set contact
+        iContact->SetContactViewContact(iStore.ContactAt(aIndex));
+        }
+    else
+    // Folding view
+    if (iType == EVPbkFoldingView)
+        {
+        // Store name as contact
+        iContact->SetFoldingViewContact(iStore.Name());
+        }
+    return *iContact; 
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::CreateLinkLC
+// Returns a contact link at index
+// -----------------------------------------------------------------------------
+//
+MVPbkContactLink* CContactView::CreateLinkLC(TInt aIndex) const
+    {
+    // Create link to contact or store
+    return CContactLink::NewLC(iStore,aIndex);
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::IndexOfLinkL
+// -----------------------------------------------------------------------------
+//
+TInt CContactView::IndexOfLinkL(const MVPbkContactLink& aContactLink) const
+    {
+    TInt index = KErrNotFound;
+    // Same store
+    if (&aContactLink.ContactStore() == &iStore)
+        {
+        // Contacts view
+        if (iType == EVPbkContactsView)
+            {
+            // Get from link
+            index = static_cast<const CContactLink&>(aContactLink).Index();
+            }
+        else
+        // Folding view, one store
+        if (iType == EVPbkFoldingView)
+            {
+            index = 0;
+            }
+        }
+    return index;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::AddObserverL
+// -----------------------------------------------------------------------------
+//
+void CContactView::AddObserverL(MVPbkContactViewObserver& aObserver)
+    {
+    TInt index = FindObserver(aObserver);
+    if (index == KErrNotFound && iObservers)
+        {
+        // New view observer
+        TContactViewObserver* op = new (ELeave) TContactViewObserver(aObserver);
+        CleanupStack::PushL(op);
+        iObservers->AppendL(op);
+        CleanupStack::Pop(op);
+        }
+    // Callback handler has not been started
+    if (! iIdle->IsActive())
+        {
+        // Notify observer callback
+        TCallBack callback(LDAPNotifyObservers,this);
+        // Start callback
+        iIdle->Start(callback);
+        }
+    }
+// -----------------------------------------------------------------------------
+// CContactView::RemoveObserver
+// -----------------------------------------------------------------------------
+//
+void CContactView::RemoveObserver(MVPbkContactViewObserver& aObserver)
+    {
+    TInt index = FindObserver(aObserver);
+    if (index != KErrNotFound)
+        {
+        // Observer
+        TContactViewObserver* op = iObservers->At(index);
+        // Remove from observers
+        iObservers->Delete(index);
+        // Delete observer
+        if (op) delete op;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::MatchContactStore
+// -----------------------------------------------------------------------------
+//
+TBool CContactView::MatchContactStore(const TDesC& aContactStoreUri) const
+    {
+    return iStore.MatchContactStore(aContactStoreUri);
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::MatchContactStoreDomain
+// -----------------------------------------------------------------------------
+//
+TBool CContactView::MatchContactStoreDomain(const TDesC& aContactStoreDomain) const
+    {
+    return iStore.MatchContactStoreDomain(aContactStoreDomain);
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::CreateBookmarkLC
+// -----------------------------------------------------------------------------
+//
+MVPbkContactBookmark* CContactView::CreateBookmarkLC(TInt aIndex) const
+    {
+    MVPbkContactBookmark* bp = NULL;
+    // Contacts view
+    if (iType == EVPbkContactsView)
+        {
+        // Index in range
+        if (aIndex >= 0 && aIndex < iStore.ContactCount())
+            {
+            // Bookmark contact in store
+            bp = CStoreBookmark::NewLC(iStore,aIndex);
+            }
+        else
+            {
+            // Bookmark store
+            bp = CStoreBookmark::NewLC(iStore);
+            }
+        }
+    else
+    // Folding view, one store
+    if (iType == EVPbkFoldingView)
+        {
+        // Bookmark store
+        bp = CStoreBookmark::NewLC(iStore);
+        }
+    return bp;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::IndexOfBookmarkL
+// -----------------------------------------------------------------------------
+//
+TInt CContactView::IndexOfBookmarkL(const MVPbkContactBookmark& aBookmark) const
+    {
+    TInt index = KErrNotFound;
+    // Contacts view
+    if (iType == EVPbkContactsView)
+        {
+        // Cast to bookmark
+        const CStoreBookmark* bp = dynamic_cast<const CStoreBookmark*>(&aBookmark);
+        if ( bp && &bp->Store == &iStore )
+            {
+            // Bookmarked index
+            TInt bookmark = (bp) ? bp->Index() : 0;
+            if (bookmark >= 0 && bookmark < iStore.ContactCount())
+                {
+                index = bookmark;
+                }            
+            }
+        }
+    else
+    // Folding view, one store
+    if (iType == EVPbkFoldingView)
+        {
+        // Store bookmark index is zero
+        index = 0;
+        }
+    return index;
+    }
+
+// -----------------------------------------------------------------------------
+// CContactView::ViewFiltering
+// -----------------------------------------------------------------------------
+//
+MVPbkContactViewFiltering* CContactView::ViewFiltering()
+    {
+    // TODO
+    return NULL;
+    }
+    
+// -----------------------------------------------------------------------------
+//                  MVPbkObjectHierarchy implementation
+// -----------------------------------------------------------------------------
+// CContactView::ParentObject
+// Returns the parent object of this view, contact store
+// -----------------------------------------------------------------------------
+//
+MVPbkObjectHierarchy& CContactView::ParentObject() const
+    {
+    return iStore;
+    }
+
+// -----------------------------------------------------------------------------
+//                  MVPbkContactStoreObserver implementation
+// -----------------------------------------------------------------------------
+// CViewContact::StoreReady
+// -----------------------------------------------------------------------------
+//
+void CContactView::StoreReady(MVPbkContactStore& /* aContactStore */)
+    {
+    // Contacts view
+    if (iType == EVPbkContactsView)
+        {
+        iViewState = EReady;
+        }
+    else
+    // Folding view, one store
+    if (iType == EVPbkFoldingView)
+        {
+        iViewState = EReady;
+        }
+    }
+// -----------------------------------------------------------------------------
+// CContactView::StoreUnavailable
+// -----------------------------------------------------------------------------
+//
+void CContactView::StoreUnavailable(MVPbkContactStore& /* aContactStore */,
+                                                        TInt /* aReason */)
+    {
+    iViewState = ENotAvailable;
+    }
+// -----------------------------------------------------------------------------
+// CContactView::HandleStoreEventL
+// -----------------------------------------------------------------------------
+//
+void CContactView::HandleStoreEventL(MVPbkContactStore&   /* aContactStore */,
+                                     TVPbkContactStoreEvent /* aStoreEvent */)
+    {
+    // No need to handle this here, events are received from the view
+    }
+
+// -----------------------------------------------------------------------------
+//                      CContactView private methods
+// -----------------------------------------------------------------------------
+// CContactView::FindObserver
+// Find observer
+// -----------------------------------------------------------------------------
+//
+TInt CContactView::FindObserver(MVPbkContactViewObserver& aObserver)
+    {
+    TInt found = KErrNotFound;
+    // Number of observers
+    const TInt count = (iObservers) ? iObservers->Count() : 0;
+    // Find one
+    for (TInt loop = 0; loop < count;loop++)
+        {
+        // This observer
+        TContactViewObserver* op = iObservers->At(loop);
+        if (op && &op->Observer() == &aObserver)
+            {
+            found = loop;
+            break;
+            }
+        }
+    return found;
+    }
+
+}  // End of namespace LDAPStore
+// -----------------------------------------------------------------------------
+//  End of File
+// -----------------------------------------------------------------------------