phonebookui/Phonebook/View/src/CPbkGroupsListFetchDlgPage.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002 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: 
       
    15 *       Provides methods for Phonebook fetch dialog page: Groups List.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 
       
    22 #include "CPbkGroupsListFetchDlgPage.h"
       
    23 #include <cntitem.h>
       
    24 #include <calslbs.h>
       
    25 #include <aknlayout.cdl.h>
       
    26 
       
    27 // PbkView classes
       
    28 #include <PbkView.hrh>
       
    29 #include "MPbkFetchDlg.h"
       
    30 #include <CPbkContactViewListControl.h>
       
    31 
       
    32 // PbkEng classes
       
    33 #include <CPbkContactEngine.h>
       
    34 #include <CPbkContactIdSet.h>
       
    35 #include <CPbkContactSubView.h>
       
    36 #include <TPbkContactViewIterator.h>
       
    37 
       
    38 
       
    39 namespace {
       
    40 
       
    41 // LOCAL CONSTANTS AND MACROS
       
    42 
       
    43 const TInt KPbkSelectionCountNotUsed(-1);
       
    44 enum TPanicCode
       
    45     {
       
    46     EPanicPostCond_Constructor = 1,
       
    47     EPanicPreCond_HandleContactViewListControlEventL
       
    48     };
       
    49 
       
    50 enum TStateFlags
       
    51     {
       
    52     EContactViewReady = 0x0001,
       
    53     EAllGroupsViewReady = 0x0002,
       
    54     EAllViewsReady = EContactViewReady|EAllGroupsViewReady,
       
    55     EInitializing = 0x0004
       
    56     };
       
    57 
       
    58 
       
    59 // ==================== LOCAL FUNCTIONS ====================
       
    60 
       
    61 #ifdef _DEBUG
       
    62 void Panic(TPanicCode aReason)
       
    63     {
       
    64     _LIT(KPanicText, "CPbkGroupsListFetchDlgPage");
       
    65     User::Panic(KPanicText, aReason);
       
    66     }
       
    67 #endif
       
    68 
       
    69 /**
       
    70  * Returns ETrue if all the bits set in aBits are set in aFlags.
       
    71  */
       
    72 inline TBool AllBitsSet(TUint aFlags, TUint aBits)
       
    73     {
       
    74     return ((aFlags & aBits)==aBits);
       
    75     }
       
    76 
       
    77 /**
       
    78  * Returns ETrue if at least one member of group aGroup is in aView.
       
    79  */
       
    80 TBool IsAnyGroupMemberInViewL
       
    81         (const CContactGroup& aGroup, const CContactViewBase& aView)
       
    82     {
       
    83     const CContactIdArray* groupMembers = aGroup.ItemsContained();
       
    84     const TInt memberCount = groupMembers ? groupMembers->Count() : 0;
       
    85     for (TInt i=0; i < memberCount; ++i)
       
    86         {
       
    87         if (aView.FindL((*groupMembers)[i]) >= 0)
       
    88             {
       
    89             return ETrue;
       
    90             }
       
    91         }
       
    92     return EFalse;
       
    93     }
       
    94 
       
    95 /**
       
    96  * Returns ETrue if at least one member of group aGroupId is in aView.
       
    97  */
       
    98 TBool IsAnyGroupMemberInViewL
       
    99         (CPbkContactEngine& aEngine,
       
   100         TContactItemId aGroupId,
       
   101         const CContactViewBase& aView)
       
   102     {
       
   103     CContactGroup* group = aEngine.ReadContactGroupL(aGroupId);
       
   104     CleanupStack::PushL(group);
       
   105     const TBool result = IsAnyGroupMemberInViewL(*group, aView);
       
   106     CleanupStack::PopAndDestroy(group);
       
   107     return result;
       
   108     }
       
   109 
       
   110 
       
   111 }  //namespace
       
   112 
       
   113 
       
   114 // ================= MEMBER FUNCTIONS =======================
       
   115 
       
   116 inline CPbkGroupsListFetchDlgPage::CPbkGroupsListFetchDlgPage
       
   117         (MPbkFetchDlg& aParentDlg) :
       
   118     iParentDlg(aParentDlg),
       
   119     iContactView(aParentDlg.FetchDlgNamesView()),
       
   120     iStateFlags(EInitializing)
       
   121     {
       
   122     __ASSERT_DEBUG(!iAllGroupsView && !iGroupSubView &&
       
   123         iStateFlags==EInitializing && !iGroupsToInclude,
       
   124         Panic(EPanicPostCond_Constructor));
       
   125     }
       
   126 
       
   127 inline void CPbkGroupsListFetchDlgPage::ConstructL()
       
   128     {
       
   129     CPbkContactEngine& engine = iParentDlg.PbkEngine();
       
   130 
       
   131     iContactView.OpenL(*this);
       
   132     iAllGroupsView = &engine.AllGroupsViewL();
       
   133     iGroupSubView = CPbkContactSubView::NewL(
       
   134         *this, engine.Database(), *iAllGroupsView, *this);
       
   135     iGroupSubView->AddBaseViewPreEventHandlerL(*this);
       
   136 
       
   137     iControl = static_cast<CPbkContactViewListControl*>
       
   138         (iParentDlg.FetchDlgControl(ECtrlFetchGroupsList));
       
   139         
       
   140     iControl->EnableMSKObserver(EFalse); 
       
   141      
       
   142     LayoutContents();
       
   143     }
       
   144 
       
   145 CPbkGroupsListFetchDlgPage* CPbkGroupsListFetchDlgPage::NewL
       
   146         (MPbkFetchDlg& aParentDlg)
       
   147     {
       
   148     CPbkGroupsListFetchDlgPage* self =
       
   149         new(ELeave) CPbkGroupsListFetchDlgPage(aParentDlg);
       
   150     CleanupStack::PushL(self);
       
   151     self->ConstructL();
       
   152     CleanupStack::Pop(self);
       
   153     return self;
       
   154     }
       
   155 
       
   156 CPbkGroupsListFetchDlgPage::~CPbkGroupsListFetchDlgPage()
       
   157     {
       
   158     if (iGroupSubView)
       
   159         {
       
   160         iGroupSubView->Close(*this);
       
   161         }
       
   162     delete iGroupsToInclude;
       
   163     iContactView.Close(*this);
       
   164     }
       
   165 
       
   166 TInt CPbkGroupsListFetchDlgPage::FetchDlgPageId() const
       
   167     {
       
   168     return ECtrlFetchGroupsList;
       
   169     }
       
   170 
       
   171 TBool CPbkGroupsListFetchDlgPage::DlgPageReady() const
       
   172     {
       
   173     return (iControl->IsReady());
       
   174     }
       
   175 
       
   176 void CPbkGroupsListFetchDlgPage::ActivateFetchDlgPageL()
       
   177     {
       
   178     iControl->DisableRedrawEnablePushL();
       
   179     iControl->ClearMarks();
       
   180 
       
   181     const TInt groupCount = iGroupsToInclude ? iGroupsToInclude->Count() : 0;
       
   182     CPbkContactEngine& engine = iParentDlg.PbkEngine();
       
   183     const CPbkContactIdSet& selectionSet = iParentDlg.FetchDlgSelection();
       
   184     for (TInt i=0; i < groupCount; ++i)
       
   185         {
       
   186         // If all group's members which are found iContactView are marked the
       
   187         // group should be marked too
       
   188         const TContactItemId groupId = (*iGroupsToInclude)[i];
       
   189         CContactGroup* group = engine.ReadContactGroupL(groupId);
       
   190         CleanupStack::PushL(group);
       
   191         const CContactIdArray* groupMembers = group->ItemsContained();
       
   192         const TInt memberCount = groupMembers ? groupMembers->Count() : 0;
       
   193         TBool markGroup = ETrue;
       
   194         for (TInt i = 0; i < memberCount; ++i)
       
   195             {
       
   196             const TContactItemId groupMemberId = (*groupMembers)[i];
       
   197             if (iContactView.FindL(groupMemberId)!=KErrNotFound &&
       
   198                 !selectionSet.Find(groupMemberId))
       
   199                 {
       
   200                 markGroup = EFalse;
       
   201                 break;
       
   202                 }
       
   203             }
       
   204         CleanupStack::PopAndDestroy(group);
       
   205         iControl->MarkItemL(groupId, markGroup);
       
   206         }
       
   207     CleanupStack::PopAndDestroy();  // DisableRedrawEnablePushL()
       
   208 
       
   209     if (iControl->ItemsMarked())
       
   210         {
       
   211         iControl->DrawDeferred();
       
   212         }
       
   213     }
       
   214 
       
   215 void CPbkGroupsListFetchDlgPage::DeactivateFetchDlgPage()
       
   216     {
       
   217     }
       
   218 
       
   219 TContactItemId CPbkGroupsListFetchDlgPage::FocusedContactIdL() const
       
   220     {
       
   221     return iControl->FocusedContactIdL();
       
   222     }
       
   223 
       
   224 TBool CPbkGroupsListFetchDlgPage::IsFetchDlgPageEmpty() const
       
   225     {
       
   226     return (iControl->NumberOfItems() == 0);
       
   227     }
       
   228 
       
   229 void CPbkGroupsListFetchDlgPage::SetMPbkFetchDlgSelection
       
   230 		(MPbkFetchDlgSelection* aAccepter)
       
   231 	{
       
   232 	iFetchSelection = aAccepter;
       
   233 	iControl->SetSelectionAccepter(this);
       
   234 	}
       
   235 
       
   236 
       
   237 TBool CPbkGroupsListFetchDlgPage::ItemsMarked() const
       
   238     {
       
   239     return iControl->ItemsMarked();
       
   240     }
       
   241 
       
   242 
       
   243 TBool CPbkGroupsListFetchDlgPage::ContactSelectionAcceptedL
       
   244 		(TContactItemId aGroupId, TInt /*aCurrentSelectedCount*/) const
       
   245 	{
       
   246 	// For each member in group that is not already selected, call the
       
   247 	// accept-callback for it. If callback returns EFalse for ANY member,
       
   248 	// then we must return EFalse.
       
   249 	TBool selectionAccepted = ETrue;
       
   250 	if (iFetchSelection)
       
   251 		{
       
   252 	    CContactGroup* group =
       
   253 	    	iParentDlg.PbkEngine().ReadContactGroupL(aGroupId);
       
   254 	    CleanupStack::PushL(group);
       
   255 	    const CContactIdArray* groupMembers = group->ItemsContained();
       
   256 	    if (groupMembers)
       
   257 	        {
       
   258 	        CPbkContactIdSet& selection = iParentDlg.FetchDlgSelection();
       
   259 	        const TInt currentSelectedCount = 	selection.Count();
       
   260 	        const TInt memberCount = groupMembers->Count();
       
   261 	        TInt newMemberCount = 0;
       
   262 	        // Go throug all members of the group
       
   263 	        for (TInt i=0; i < memberCount; ++i)
       
   264 	            {
       
   265 	            const TContactItemId contactId = (*groupMembers)[i];
       
   266 	            if (!selection.Find(contactId))
       
   267 		            {
       
   268 		            // This group member is not yet selected. Check if the
       
   269 		            // member can be selected
       
   270 		            if (!iFetchSelection->ContactSelectionAcceptedL
       
   271 		            		(contactId,
       
   272 		            		 currentSelectedCount + newMemberCount))
       
   273 			            {
       
   274 			 			// If any member is rejected from being selected,
       
   275 			 			// the group can't be selected
       
   276 			            selectionAccepted = EFalse;
       
   277 			            break;
       
   278 			            }
       
   279 			        else
       
   280 				        {
       
   281 				        // Note: We are actually not yet adding any members
       
   282 				        // to the set of selected ids. Adding occurs only
       
   283 				        // if this method returns ETrue
       
   284 				        newMemberCount++;
       
   285 				        }
       
   286 		            }
       
   287 	            }
       
   288 	        }
       
   289 	    CleanupStack::PopAndDestroy(group);
       
   290 		}
       
   291 	else
       
   292 		{
       
   293 		selectionAccepted = ETrue;
       
   294 		}
       
   295     return selectionAccepted;
       
   296 	}
       
   297 	
       
   298 TBool CPbkGroupsListFetchDlgPage::ProcessSoftkeyMarkCommandL(TInt aCommandId)
       
   299     {
       
   300     TBool selectionAccepted(ETrue);
       
   301     
       
   302     if ( aCommandId == EAknSoftkeyMark )
       
   303         {
       
   304         selectionAccepted = ContactSelectionAcceptedL( iControl->ContactIdAtL( 
       
   305                 iControl->CurrentItemIndex()), KPbkSelectionCountNotUsed);
       
   306         }
       
   307     
       
   308     if ( aCommandId == EAknSoftkeyUnmark || selectionAccepted )
       
   309         {    
       
   310         // Send event
       
   311     	TPbkContactViewListControlEvent event( TPbkContactViewListControlEvent::EContactSelected );
       
   312         event.iInt = iControl->CurrentItemIndex();
       
   313         event.iContactId = iControl->ContactIdAtL( event.iInt );    
       
   314         
       
   315         switch( aCommandId )
       
   316         	{
       
   317         	case EAknSoftkeyMark:
       
   318         		{
       
   319     			// Send event about changed state
       
   320     	        HandleContactViewListControlEventL( *iControl, event );    		        	    	        
       
   321         		break;
       
   322         		}
       
   323         		
       
   324         	case EAknSoftkeyUnmark:
       
   325         		{
       
   326     			// Send event about changed state
       
   327     			event.iEventType = TPbkContactViewListControlEvent::EContactUnselected;
       
   328     	        HandleContactViewListControlEventL( *iControl, event );    		    	        
       
   329         		break;
       
   330         		}
       
   331         		
       
   332         	default:;
       
   333             	}            
       
   334             	
       
   335             return ETrue;
       
   336             }
       
   337         
       
   338     return EFalse;
       
   339     }
       
   340     
       
   341 CPbkContactViewListControl& CPbkGroupsListFetchDlgPage::Control()
       
   342     {
       
   343     return *iControl;
       
   344     }
       
   345 
       
   346 
       
   347 void CPbkGroupsListFetchDlgPage::HandleContactViewListControlEventL
       
   348         (CPbkContactViewListControl& aControl,
       
   349         const TPbkContactViewListControlEvent& aEvent)
       
   350     {
       
   351     __ASSERT_DEBUG(&aControl==iControl,
       
   352         Panic(EPanicPreCond_HandleContactViewListControlEventL));
       
   353 
       
   354 	// Suppress the unused parameter warning
       
   355 	(void) aControl;
       
   356 
       
   357     switch (aEvent.iEventType)
       
   358         {
       
   359         case TPbkContactViewListControlEvent::EContactSelected:
       
   360             {
       
   361             HandleGroupSelectionL(aEvent.iContactId, ETrue);
       
   362             break;
       
   363             }
       
   364 
       
   365         case TPbkContactViewListControlEvent::EContactUnselected:
       
   366             {
       
   367             HandleGroupSelectionL(aEvent.iContactId, EFalse);
       
   368             break;
       
   369             }
       
   370         case TPbkContactViewListControlEvent::EContactSetChanged: // FALLTHROUGH
       
   371         default:
       
   372             {
       
   373             // Notify parent dialog that this page has changed
       
   374             iParentDlg.FetchDlgPageChangedL(*this);
       
   375             break;
       
   376             }
       
   377         }
       
   378     }
       
   379 
       
   380 void CPbkGroupsListFetchDlgPage::HandleContactViewEvent
       
   381         (const CContactViewBase& aView,const TContactViewEvent& aEvent)
       
   382     {
       
   383     TRAPD(err, HandleContactViewEventL(aView,aEvent));
       
   384     if (err != KErrNone)
       
   385         {
       
   386         iParentDlg.FetchDlgHandleError(err);
       
   387         }
       
   388     }
       
   389 
       
   390 TBool CPbkGroupsListFetchDlgPage::IsContactIncluded(TContactItemId aId)
       
   391     {
       
   392     return (iGroupsToInclude && iGroupsToInclude->Find(aId));
       
   393     }
       
   394 
       
   395 void CPbkGroupsListFetchDlgPage::SetupControlL()
       
   396     {
       
   397     if (AllBitsSet(iStateFlags,EAllViewsReady|EInitializing))
       
   398         {
       
   399         iStateFlags &= ~EInitializing;
       
   400         CPbkContactEngine& engine = iParentDlg.PbkEngine();
       
   401         for (TInt i=0; i < iAllGroupsView->CountL(); ++i)
       
   402             {
       
   403             const TContactItemId groupId = iAllGroupsView->AtL(i);
       
   404             if (IsAnyGroupMemberInViewL(engine,groupId,iContactView))
       
   405                 {
       
   406                 // Add all groups which have at least one member in iContactView
       
   407                 if (!iGroupsToInclude)
       
   408                     {
       
   409                     iGroupsToInclude = CPbkContactIdSet::NewL();
       
   410                     }
       
   411                 iGroupsToInclude->AddL(groupId);
       
   412                 }
       
   413             }
       
   414         iGroupSubView->Refresh();
       
   415         iControl->ConstructL(engine, *iGroupSubView);
       
   416         iControl->AddObserverL(*this);
       
   417         }
       
   418     }
       
   419 
       
   420 void CPbkGroupsListFetchDlgPage::HandleGroupSelectionL
       
   421         (TContactItemId aGroupId, TBool aSelected)
       
   422     {
       
   423     CContactGroup* group = iParentDlg.PbkEngine().ReadContactGroupL(aGroupId);
       
   424     CleanupStack::PushL(group);
       
   425     const CContactIdArray* groupMembers = group->ItemsContained();
       
   426     if (groupMembers)
       
   427         {
       
   428         if (aSelected)
       
   429             {
       
   430             // Add those group members which are present in iContactView
       
   431             const TInt memberCount = groupMembers->Count();
       
   432             for (TInt i=0; i < memberCount; ++i)
       
   433                 {
       
   434                 const TContactItemId contactId = (*groupMembers)[i];
       
   435                 if (iContactView.FindL(contactId) != KErrNotFound)
       
   436                     {
       
   437                     iParentDlg.FetchDlgSelection().AddL(contactId);
       
   438                     }
       
   439                 }
       
   440             }
       
   441         else
       
   442             {
       
   443             // Remove all group members from current selection
       
   444             iParentDlg.FetchDlgSelection().Remove(*groupMembers);
       
   445             }
       
   446         }
       
   447     CleanupStack::PopAndDestroy(group);
       
   448     }
       
   449 
       
   450 void CPbkGroupsListFetchDlgPage::HandleContactViewEventL
       
   451         (const CContactViewBase& aView,const TContactViewEvent& aEvent)
       
   452     {
       
   453     if (&aView == &iContactView)
       
   454         {
       
   455         HandleContactViewEventL(aEvent);
       
   456         }
       
   457     else if (&aView == iAllGroupsView)
       
   458         {
       
   459         HandleGroupsViewEventL(aEvent);
       
   460         }
       
   461     }
       
   462 
       
   463 void CPbkGroupsListFetchDlgPage::HandleContactViewEventL
       
   464         (const TContactViewEvent& aEvent)
       
   465     {
       
   466     switch (aEvent.iEventType)
       
   467         {
       
   468         case TContactViewEvent::EReady:
       
   469             {
       
   470             iStateFlags |= EContactViewReady;
       
   471             SetupControlL();
       
   472             break;
       
   473             }
       
   474 
       
   475         default:
       
   476             {
       
   477             break;
       
   478             }
       
   479         }
       
   480     }
       
   481 
       
   482 void CPbkGroupsListFetchDlgPage::HandleGroupsViewEventL
       
   483         (const TContactViewEvent& aEvent)
       
   484     {
       
   485     switch (aEvent.iEventType)
       
   486         {
       
   487         case TContactViewEvent::EReady:
       
   488             {
       
   489             iStateFlags |= EAllGroupsViewReady;
       
   490             SetupControlL();
       
   491             break;
       
   492             }
       
   493 
       
   494         case TContactViewEvent::EItemAdded:
       
   495             {
       
   496             CPbkContactEngine& engine = iParentDlg.PbkEngine();
       
   497             if ((iStateFlags & EContactViewReady) &&
       
   498                 IsAnyGroupMemberInViewL(engine, aEvent.iContactId, iContactView))
       
   499                 {
       
   500                 if (!iGroupsToInclude)
       
   501                     {
       
   502                     iGroupsToInclude = CPbkContactIdSet::NewL();
       
   503                     }
       
   504                 iGroupsToInclude->AddL(aEvent.iContactId);
       
   505                 }
       
   506             break;
       
   507             }
       
   508 
       
   509         case TContactViewEvent::EItemRemoved:
       
   510             {
       
   511             if (iGroupsToInclude)
       
   512                 {
       
   513                 iGroupsToInclude->Remove(aEvent.iContactId);
       
   514                 }
       
   515             break;
       
   516             }
       
   517 
       
   518         default:
       
   519             break;
       
   520         }
       
   521     }
       
   522 
       
   523 void CPbkGroupsListFetchDlgPage::LayoutContents()
       
   524     {
       
   525     AknLayoutUtils::LayoutControl(
       
   526         iControl,
       
   527         iParentDlg.FetchDlgClientRect(),
       
   528         AknLayout::list_gen_pane(0));
       
   529     }
       
   530 
       
   531 const CContactIdArray& CPbkGroupsListFetchDlgPage::MarkedItemsL() const
       
   532     {
       
   533     return iControl->MarkedItemsL();
       
   534     }
       
   535 
       
   536 // End of File