phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkFoldingContactView.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  A class for folding view that can be expanded to its subview
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CVPbkFoldingContactView.h"
       
    20 #include <MVPbkContactStore.h>
       
    21 #include <CVPbkSortOrder.h>
       
    22 #include <MVPbkContactViewObserver.h>
       
    23 #include <CVPbkAsyncCallback.h>
       
    24 #include <MVPbkContactStoreProperties.h>
       
    25 #include <CVPbkContactViewDefinition.h>
       
    26 #include <CVPbkContactManager.h>
       
    27 #include <TVPbkContactStoreUriPtr.h>
       
    28 #include <VPbkError.h>
       
    29 
       
    30 #include "TVPbkFoldingContactBookmark.h"
       
    31 #include "CVPbkFoldingViewContact.h"
       
    32 
       
    33 namespace {
       
    34 
       
    35 #ifdef _DEBUG
       
    36     enum TPanic
       
    37         {
       
    38         EPreCond_ConstructL
       
    39         };
       
    40         
       
    41     void Panic( TPanic aPanic )
       
    42         {
       
    43         _LIT(KPanicCat, "CVPbkFoldingContactView");
       
    44         User::Panic( KPanicCat, aPanic );
       
    45         }
       
    46 #endif // _DEBUG
       
    47 
       
    48 // CONSTANTS
       
    49 const TInt KObserverArrayGranularity = 4;
       
    50 
       
    51 // Event sending functions for different amount of parameters
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // SendEventToObservers
       
    55 // For observer functions that take MVPbkContactViewBase as a parameter
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 template <class NotifyFunc>
       
    59 void SendEventToObservers(MVPbkContactViewBase& aView, 
       
    60                           RPointerArray<MVPbkContactViewObserver>& iObservers, 
       
    61                           NotifyFunc aNotifyFunc)
       
    62     {
       
    63     const TInt count = iObservers.Count();
       
    64     for (TInt i = 0; i < count; ++i)
       
    65         {
       
    66         MVPbkContactViewObserver* observer = iObservers[i];
       
    67         (observer->*aNotifyFunc)(aView);
       
    68         }
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // SendEventToObservers
       
    73 // For observer functions that take MVPbkContactViewBase, and two other 
       
    74 // parameters
       
    75 // ---------------------------------------------------------------------------
       
    76 //
       
    77 template <class NotifyFunc, class ParamType1, class ParamType2>
       
    78 void SendEventToObservers(MVPbkContactViewBase& aView, 
       
    79                           RPointerArray<MVPbkContactViewObserver>& iObservers, 
       
    80                           NotifyFunc aNotifyFunc,
       
    81                           ParamType1 aParam1,
       
    82                           ParamType2 aParam2)
       
    83     {
       
    84     const TInt count = iObservers.Count();
       
    85     for (TInt i = 0; i < count; ++i)
       
    86         {
       
    87         MVPbkContactViewObserver* observer = iObservers[i];
       
    88         (observer->*aNotifyFunc)(aView, aParam1, aParam2);
       
    89         }
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // DoMatchContactStore
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 TBool DoMatchContactStore(CVPbkContactViewDefinition& aViewDef,
       
    97         TVPbkContactStoreUriPtr::TVPbkContactStoreUriComponent aUriComponent, 
       
    98         const TDesC& aStoreUriComponentDes)
       
    99     {
       
   100     // Match store URI to the first view definition that is found starting
       
   101     // from the aViewDef. If not found then check subviews from left to right
       
   102     TBool result = EFalse;
       
   103     TVPbkContactStoreUriPtr uriPtr(aViewDef.Uri());
       
   104     if (uriPtr.Compare(aStoreUriComponentDes, aUriComponent) == 0)
       
   105         {
       
   106         result = ETrue;
       
   107         }
       
   108     else
       
   109         {
       
   110         const TInt count = aViewDef.SubViewCount();
       
   111         for (TInt i = 0; i < count && !result; ++i)
       
   112             {
       
   113             result = DoMatchContactStore(aViewDef.SubViewAt(i), aUriComponent, 
       
   114                 aStoreUriComponentDes);
       
   115             }
       
   116         }
       
   117     return result;
       
   118     }
       
   119 }
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 // CVPbkFoldingContactView::CVPbkFoldingContactView
       
   123 // ---------------------------------------------------------------------------
       
   124 //
       
   125 CVPbkFoldingContactView::CVPbkFoldingContactView(
       
   126         const CVPbkContactManager& aContactManager) :
       
   127     iContactManager(aContactManager),
       
   128     iObservers( KObserverArrayGranularity )
       
   129     {
       
   130     }
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // CVPbkFoldingContactView::ConstructL
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 inline void CVPbkFoldingContactView::ConstructL(
       
   137         const CVPbkContactViewDefinition& aViewDefinition,
       
   138         const MVPbkFieldTypeList& aSortOrder)
       
   139     {
       
   140     /// Folding view must have 1 sub view definition if it's used for
       
   141     /// expanding. If there is no sub view then this folding can not be
       
   142     /// exapanded and it's only used to show a named item.
       
   143     __ASSERT_DEBUG( aViewDefinition.SubViewCount() <= 1,
       
   144         Panic( EPreCond_ConstructL ) );
       
   145     
       
   146     /// Save the one and only subview definition for later usage
       
   147     iViewDefinition = CVPbkContactViewDefinition::NewL( aViewDefinition );
       
   148     /// Create the view contact
       
   149     iFoldingContact = CVPbkFoldingViewContact::NewL(*this);
       
   150     iSortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // CVPbkFoldingContactView::NewLC
       
   155 // ---------------------------------------------------------------------------
       
   156 //  
       
   157 CVPbkFoldingContactView* CVPbkFoldingContactView::NewLC(
       
   158         MVPbkContactViewObserver& aObserver,
       
   159         const CVPbkContactViewDefinition& aViewDefinition, 
       
   160         const CVPbkContactManager& aContactManager,
       
   161         const MVPbkFieldTypeList& aSortOrder)
       
   162     {
       
   163     CVPbkFoldingContactView* self = new(ELeave) CVPbkFoldingContactView(aContactManager);
       
   164     CleanupStack::PushL(self);
       
   165     self->ConstructL(aViewDefinition, aSortOrder);
       
   166     self->AddObserverL(aObserver);
       
   167     return self;
       
   168     }
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // CVPbkFoldingContactView::~CVPbkFoldingContactView
       
   172 // ---------------------------------------------------------------------------
       
   173 //  
       
   174 CVPbkFoldingContactView::~CVPbkFoldingContactView()
       
   175     {
       
   176     delete iViewDefinition;
       
   177     delete iSortOrder;
       
   178     delete iFoldingContact;
       
   179     iObservers.Close();
       
   180     }
       
   181 
       
   182 // ---------------------------------------------------------------------------
       
   183 // CVPbkFoldingContactView::Name
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 const TDesC& CVPbkFoldingContactView::Name() const
       
   187     {
       
   188     return iViewDefinition->Name();
       
   189     }
       
   190 
       
   191 // ---------------------------------------------------------------------------
       
   192 // CVPbkFoldingContactView::Type
       
   193 // ---------------------------------------------------------------------------
       
   194 //
       
   195 TVPbkContactViewType CVPbkFoldingContactView::Type() const
       
   196     {
       
   197     return EVPbkFoldingView;
       
   198     }
       
   199 
       
   200 // ---------------------------------------------------------------------------
       
   201 // CVPbkFoldingContactView::ChangeSortOrderL
       
   202 // ---------------------------------------------------------------------------
       
   203 //
       
   204 void CVPbkFoldingContactView::ChangeSortOrderL(const MVPbkFieldTypeList& aSortOrder)
       
   205     {
       
   206     if (iObservers.Count() > 0)
       
   207         {
       
   208         CVPbkSortOrder* newSortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
   209         delete iSortOrder;
       
   210         iSortOrder = newSortOrder;
       
   211         
       
   212         SendAsyncUnavailableAndReadyEventL();
       
   213         }    
       
   214     }
       
   215 
       
   216 // ---------------------------------------------------------------------------
       
   217 // CVPbkFoldingContactView::SortOrder
       
   218 // ---------------------------------------------------------------------------
       
   219 //
       
   220 const MVPbkFieldTypeList& CVPbkFoldingContactView::SortOrder() const
       
   221     {
       
   222     return *iSortOrder;
       
   223     }
       
   224 
       
   225 // ---------------------------------------------------------------------------
       
   226 // CVPbkFoldingContactView::RefreshL
       
   227 // ---------------------------------------------------------------------------
       
   228 //
       
   229 void CVPbkFoldingContactView::RefreshL()
       
   230     {
       
   231     SendAsyncUnavailableAndReadyEventL();
       
   232     }
       
   233 
       
   234 // ---------------------------------------------------------------------------
       
   235 // CVPbkFoldingContactView::ContactCountL
       
   236 // ---------------------------------------------------------------------------
       
   237 //
       
   238 TInt CVPbkFoldingContactView::ContactCountL() const
       
   239     {
       
   240     // This is folding view => only this view is visible as a contact
       
   241     return 1;
       
   242     }
       
   243 
       
   244 // ---------------------------------------------------------------------------
       
   245 // CVPbkFoldingContactView::ContactAtL
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 const MVPbkViewContact& CVPbkFoldingContactView::ContactAtL(TInt aIndex) const
       
   249     {
       
   250     __ASSERT_ALWAYS( aIndex >= 0,
       
   251         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   252     if ( aIndex >= ContactCountL() )
       
   253         {
       
   254         User::Leave( KErrArgument );
       
   255         }
       
   256 
       
   257     return *iFoldingContact;
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // CVPbkFoldingContactView::CreateLinkLC
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 MVPbkContactLink* CVPbkFoldingContactView::CreateLinkLC(TInt aIndex) const
       
   265     {
       
   266     __ASSERT_ALWAYS( aIndex >= 0,
       
   267         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   268     if ( aIndex >= ContactCountL() )
       
   269         {
       
   270         User::Leave( KErrArgument );
       
   271         }
       
   272 
       
   273     return iFoldingContact->CreateLinkLC();
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------------------------
       
   277 // CVPbkFoldingContactView::IndexOfLinkL
       
   278 // ---------------------------------------------------------------------------
       
   279 //
       
   280 TInt CVPbkFoldingContactView::IndexOfLinkL(
       
   281         const MVPbkContactLink& /*aContactLink*/) const
       
   282     {
       
   283     return KErrNotFound;
       
   284     }
       
   285 
       
   286 // ---------------------------------------------------------------------------
       
   287 // CVPbkFoldingContactView::AddObserverL
       
   288 // ---------------------------------------------------------------------------
       
   289 //
       
   290 void CVPbkFoldingContactView::AddObserverL(
       
   291         MVPbkContactViewObserver& aObserver)
       
   292     {
       
   293     VPbkEngUtils::MAsyncCallback* notifyObserver =
       
   294         VPbkEngUtils::CreateAsyncCallbackLC(
       
   295             *this, 
       
   296             &CVPbkFoldingContactView::DoAddObserverL, 
       
   297             &CVPbkFoldingContactView::AddObserverError, 
       
   298             aObserver);
       
   299     iAsyncOperation.CallbackL(notifyObserver);
       
   300     CleanupStack::Pop(notifyObserver);
       
   301     }
       
   302 
       
   303 // ---------------------------------------------------------------------------
       
   304 // CVPbkFoldingContactView::DoAddObserverL
       
   305 // ---------------------------------------------------------------------------
       
   306 //
       
   307 void CVPbkFoldingContactView::DoAddObserverL(
       
   308         MVPbkContactViewObserver& aObserver)
       
   309     {
       
   310     TInt err( iObservers.InsertInAddressOrder( &aObserver ) );
       
   311     if ( err != KErrNone && err != KErrAlreadyExists )
       
   312         {
       
   313         User::Leave( err );
       
   314         }
       
   315         
       
   316     // this view is always ready
       
   317     aObserver.ContactViewReady(*this);
       
   318     }
       
   319 
       
   320 // ---------------------------------------------------------------------------
       
   321 // CVPbkFoldingContactView::AddObserverError
       
   322 // ---------------------------------------------------------------------------
       
   323 //
       
   324 void CVPbkFoldingContactView::AddObserverError(
       
   325         MVPbkContactViewObserver& aObserver, TInt aError)
       
   326     {
       
   327     aObserver.ContactViewError(*this, aError, EFalse);
       
   328     }
       
   329 
       
   330 // ---------------------------------------------------------------------------
       
   331 // CVPbkFoldingContactView::SendAsyncUnavailableAndReadyEventL
       
   332 // ---------------------------------------------------------------------------
       
   333 //
       
   334 void CVPbkFoldingContactView::SendAsyncUnavailableAndReadyEventL()
       
   335     {
       
   336     // Send first unvavailable event...
       
   337     VPbkEngUtils::MAsyncCallback* notifyObserver = 
       
   338         VPbkEngUtils::CreateAsyncCallbackLC(
       
   339             *this, 
       
   340             &CVPbkFoldingContactView::DoSignalObserversViewUnavailable,
       
   341             &CVPbkFoldingContactView::DoSignalObserversViewError,
       
   342             *iObservers[0]);//Observer is actually not used by DoSignal*
       
   343     iAsyncOperation.CallbackL(notifyObserver);
       
   344     CleanupStack::Pop(notifyObserver);
       
   345     
       
   346     // ...then ready event. This is how views must behave.
       
   347     notifyObserver = VPbkEngUtils::CreateAsyncCallbackLC(
       
   348         *this,
       
   349         &CVPbkFoldingContactView::DoSignalObserversViewReady, 
       
   350         &CVPbkFoldingContactView::DoSignalObserversViewError,
       
   351         *iObservers[0]);//Observer is actually not used by DoSignal*
       
   352     iAsyncOperation.CallbackL( notifyObserver );
       
   353     CleanupStack::Pop( notifyObserver );
       
   354     }
       
   355     
       
   356 // ---------------------------------------------------------------------------
       
   357 // CVPbkFoldingContactView::DoSignalObserversViewReady
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 void CVPbkFoldingContactView::DoSignalObserversViewReady(
       
   361         MVPbkContactViewObserver& /*aObserver*/)
       
   362     {
       
   363     SendEventToObservers(*this, iObservers, 
       
   364         &MVPbkContactViewObserver::ContactViewReady);
       
   365     }
       
   366 
       
   367 // ---------------------------------------------------------------------------
       
   368 // CVPbkFoldingContactView::DoSignalObserversViewUnavailable
       
   369 // ---------------------------------------------------------------------------
       
   370 //
       
   371 void CVPbkFoldingContactView::DoSignalObserversViewUnavailable(
       
   372         MVPbkContactViewObserver& /*aObserver*/)
       
   373     {
       
   374     SendEventToObservers( *this, iObservers, 
       
   375         &MVPbkContactViewObserver::ContactViewUnavailable );
       
   376     }
       
   377     
       
   378 // ---------------------------------------------------------------------------
       
   379 // CVPbkFoldingContactView::DoSignalObserversViewError
       
   380 // ---------------------------------------------------------------------------
       
   381 //
       
   382 void CVPbkFoldingContactView::DoSignalObserversViewError(
       
   383         MVPbkContactViewObserver& /* aObserver */, 
       
   384         TInt aError )
       
   385     {
       
   386     SendEventToObservers(*this, iObservers, 
       
   387         &MVPbkContactViewObserver::ContactViewError, aError, EFalse );
       
   388     }
       
   389 
       
   390 // ---------------------------------------------------------------------------
       
   391 // CVPbkFoldingContactView::RemoveObserver
       
   392 // ---------------------------------------------------------------------------
       
   393 //
       
   394 void CVPbkFoldingContactView::RemoveObserver(
       
   395         MVPbkContactViewObserver& aObserver)
       
   396     {
       
   397     TInt index( iObservers.FindInAddressOrder( &aObserver ) );
       
   398     if (index != KErrNotFound)
       
   399         {
       
   400         iObservers.Remove(index);
       
   401         }
       
   402     }
       
   403 
       
   404 // ---------------------------------------------------------------------------
       
   405 // CVPbkFoldingContactView::MatchContactStore
       
   406 // ---------------------------------------------------------------------------
       
   407 //
       
   408 TBool CVPbkFoldingContactView::MatchContactStore(
       
   409         const TDesC& aContactStoreUri) const
       
   410     {
       
   411     return DoMatchContactStore(*iViewDefinition, 
       
   412         TVPbkContactStoreUriPtr::EContactStoreUriAllComponents,
       
   413         aContactStoreUri);
       
   414     }
       
   415 
       
   416 // ---------------------------------------------------------------------------
       
   417 // CVPbkFoldingContactView::MatchContactStoreDomain
       
   418 // ---------------------------------------------------------------------------
       
   419 //
       
   420 TBool CVPbkFoldingContactView::MatchContactStoreDomain(
       
   421         const TDesC& aContactStoreDomain) const
       
   422     {
       
   423     return DoMatchContactStore(*iViewDefinition, 
       
   424         TVPbkContactStoreUriPtr::EContactStoreUriStoreType,
       
   425         aContactStoreDomain);
       
   426     }
       
   427 
       
   428 // ---------------------------------------------------------------------------
       
   429 // CVPbkFoldingContactView::CreateBookmarkLC
       
   430 // ---------------------------------------------------------------------------
       
   431 //
       
   432 MVPbkContactBookmark* CVPbkFoldingContactView::CreateBookmarkLC(
       
   433         TInt aIndex ) const
       
   434     {
       
   435     __ASSERT_ALWAYS( aIndex >= 0, 
       
   436         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   437 
       
   438     return iFoldingContact->CreateBookmarkLC();
       
   439     }
       
   440 
       
   441 // ---------------------------------------------------------------------------
       
   442 // CVPbkFoldingContactView::IndexOfBookmarkL
       
   443 // ---------------------------------------------------------------------------
       
   444 //
       
   445 TInt CVPbkFoldingContactView::IndexOfBookmarkL(
       
   446         const MVPbkContactBookmark& aContactBookmark) const
       
   447     {
       
   448     const TVPbkFoldingContactBookmark* bookmark = 
       
   449         dynamic_cast<const TVPbkFoldingContactBookmark*>(&aContactBookmark);
       
   450     if (bookmark && iFoldingContact == &bookmark->Contact())
       
   451         {
       
   452         // Folding view has always only one contact in index 0
       
   453         return 0;
       
   454         }
       
   455     return KErrNotFound;
       
   456     }
       
   457 
       
   458 // ---------------------------------------------------------------------------
       
   459 // CVPbkFoldingContactView::ViewFiltering
       
   460 // ---------------------------------------------------------------------------
       
   461 //
       
   462 MVPbkContactViewFiltering* CVPbkFoldingContactView::ViewFiltering()
       
   463     {
       
   464     // Folding view doesn't support filtering yet.
       
   465     return NULL;
       
   466     }
       
   467     
       
   468 // ---------------------------------------------------------------------------
       
   469 // CVPbkFoldingContactView::ExpandLC
       
   470 // ---------------------------------------------------------------------------
       
   471 //
       
   472 MVPbkContactViewBase* CVPbkFoldingContactView::ExpandLC(
       
   473         MVPbkContactViewObserver& aObserver,
       
   474         const MVPbkFieldTypeList& aSortOrder) const
       
   475     {
       
   476     /// Folding view can be expanded if it has one sub view definition. 
       
   477     /// If it has more than one then the rest of subview definitions are 
       
   478     /// ignored.
       
   479     if ( iViewDefinition->SubViewCount() >= 1 )
       
   480         {
       
   481         // Create a view according to first subview definition.
       
   482         return iContactManager.CreateContactViewLC(
       
   483             aObserver, iViewDefinition->SubViewAt( 0 ), aSortOrder );
       
   484         }
       
   485     return NULL;
       
   486     }
       
   487 
       
   488 //End of file