diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook/View/src/CPbkGroupsListFetchDlgPage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook/View/src/CPbkGroupsListFetchDlgPage.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,536 @@ +/* +* Copyright (c) 2002 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: +* Provides methods for Phonebook fetch dialog page: Groups List. +* +*/ + + +// INCLUDE FILES + +#include "CPbkGroupsListFetchDlgPage.h" +#include +#include +#include + +// PbkView classes +#include +#include "MPbkFetchDlg.h" +#include + +// PbkEng classes +#include +#include +#include +#include + + +namespace { + +// LOCAL CONSTANTS AND MACROS + +const TInt KPbkSelectionCountNotUsed(-1); +enum TPanicCode + { + EPanicPostCond_Constructor = 1, + EPanicPreCond_HandleContactViewListControlEventL + }; + +enum TStateFlags + { + EContactViewReady = 0x0001, + EAllGroupsViewReady = 0x0002, + EAllViewsReady = EContactViewReady|EAllGroupsViewReady, + EInitializing = 0x0004 + }; + + +// ==================== LOCAL FUNCTIONS ==================== + +#ifdef _DEBUG +void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CPbkGroupsListFetchDlgPage"); + User::Panic(KPanicText, aReason); + } +#endif + +/** + * Returns ETrue if all the bits set in aBits are set in aFlags. + */ +inline TBool AllBitsSet(TUint aFlags, TUint aBits) + { + return ((aFlags & aBits)==aBits); + } + +/** + * Returns ETrue if at least one member of group aGroup is in aView. + */ +TBool IsAnyGroupMemberInViewL + (const CContactGroup& aGroup, const CContactViewBase& aView) + { + const CContactIdArray* groupMembers = aGroup.ItemsContained(); + const TInt memberCount = groupMembers ? groupMembers->Count() : 0; + for (TInt i=0; i < memberCount; ++i) + { + if (aView.FindL((*groupMembers)[i]) >= 0) + { + return ETrue; + } + } + return EFalse; + } + +/** + * Returns ETrue if at least one member of group aGroupId is in aView. + */ +TBool IsAnyGroupMemberInViewL + (CPbkContactEngine& aEngine, + TContactItemId aGroupId, + const CContactViewBase& aView) + { + CContactGroup* group = aEngine.ReadContactGroupL(aGroupId); + CleanupStack::PushL(group); + const TBool result = IsAnyGroupMemberInViewL(*group, aView); + CleanupStack::PopAndDestroy(group); + return result; + } + + +} //namespace + + +// ================= MEMBER FUNCTIONS ======================= + +inline CPbkGroupsListFetchDlgPage::CPbkGroupsListFetchDlgPage + (MPbkFetchDlg& aParentDlg) : + iParentDlg(aParentDlg), + iContactView(aParentDlg.FetchDlgNamesView()), + iStateFlags(EInitializing) + { + __ASSERT_DEBUG(!iAllGroupsView && !iGroupSubView && + iStateFlags==EInitializing && !iGroupsToInclude, + Panic(EPanicPostCond_Constructor)); + } + +inline void CPbkGroupsListFetchDlgPage::ConstructL() + { + CPbkContactEngine& engine = iParentDlg.PbkEngine(); + + iContactView.OpenL(*this); + iAllGroupsView = &engine.AllGroupsViewL(); + iGroupSubView = CPbkContactSubView::NewL( + *this, engine.Database(), *iAllGroupsView, *this); + iGroupSubView->AddBaseViewPreEventHandlerL(*this); + + iControl = static_cast + (iParentDlg.FetchDlgControl(ECtrlFetchGroupsList)); + + iControl->EnableMSKObserver(EFalse); + + LayoutContents(); + } + +CPbkGroupsListFetchDlgPage* CPbkGroupsListFetchDlgPage::NewL + (MPbkFetchDlg& aParentDlg) + { + CPbkGroupsListFetchDlgPage* self = + new(ELeave) CPbkGroupsListFetchDlgPage(aParentDlg); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CPbkGroupsListFetchDlgPage::~CPbkGroupsListFetchDlgPage() + { + if (iGroupSubView) + { + iGroupSubView->Close(*this); + } + delete iGroupsToInclude; + iContactView.Close(*this); + } + +TInt CPbkGroupsListFetchDlgPage::FetchDlgPageId() const + { + return ECtrlFetchGroupsList; + } + +TBool CPbkGroupsListFetchDlgPage::DlgPageReady() const + { + return (iControl->IsReady()); + } + +void CPbkGroupsListFetchDlgPage::ActivateFetchDlgPageL() + { + iControl->DisableRedrawEnablePushL(); + iControl->ClearMarks(); + + const TInt groupCount = iGroupsToInclude ? iGroupsToInclude->Count() : 0; + CPbkContactEngine& engine = iParentDlg.PbkEngine(); + const CPbkContactIdSet& selectionSet = iParentDlg.FetchDlgSelection(); + for (TInt i=0; i < groupCount; ++i) + { + // If all group's members which are found iContactView are marked the + // group should be marked too + const TContactItemId groupId = (*iGroupsToInclude)[i]; + CContactGroup* group = engine.ReadContactGroupL(groupId); + CleanupStack::PushL(group); + const CContactIdArray* groupMembers = group->ItemsContained(); + const TInt memberCount = groupMembers ? groupMembers->Count() : 0; + TBool markGroup = ETrue; + for (TInt i = 0; i < memberCount; ++i) + { + const TContactItemId groupMemberId = (*groupMembers)[i]; + if (iContactView.FindL(groupMemberId)!=KErrNotFound && + !selectionSet.Find(groupMemberId)) + { + markGroup = EFalse; + break; + } + } + CleanupStack::PopAndDestroy(group); + iControl->MarkItemL(groupId, markGroup); + } + CleanupStack::PopAndDestroy(); // DisableRedrawEnablePushL() + + if (iControl->ItemsMarked()) + { + iControl->DrawDeferred(); + } + } + +void CPbkGroupsListFetchDlgPage::DeactivateFetchDlgPage() + { + } + +TContactItemId CPbkGroupsListFetchDlgPage::FocusedContactIdL() const + { + return iControl->FocusedContactIdL(); + } + +TBool CPbkGroupsListFetchDlgPage::IsFetchDlgPageEmpty() const + { + return (iControl->NumberOfItems() == 0); + } + +void CPbkGroupsListFetchDlgPage::SetMPbkFetchDlgSelection + (MPbkFetchDlgSelection* aAccepter) + { + iFetchSelection = aAccepter; + iControl->SetSelectionAccepter(this); + } + + +TBool CPbkGroupsListFetchDlgPage::ItemsMarked() const + { + return iControl->ItemsMarked(); + } + + +TBool CPbkGroupsListFetchDlgPage::ContactSelectionAcceptedL + (TContactItemId aGroupId, TInt /*aCurrentSelectedCount*/) const + { + // For each member in group that is not already selected, call the + // accept-callback for it. If callback returns EFalse for ANY member, + // then we must return EFalse. + TBool selectionAccepted = ETrue; + if (iFetchSelection) + { + CContactGroup* group = + iParentDlg.PbkEngine().ReadContactGroupL(aGroupId); + CleanupStack::PushL(group); + const CContactIdArray* groupMembers = group->ItemsContained(); + if (groupMembers) + { + CPbkContactIdSet& selection = iParentDlg.FetchDlgSelection(); + const TInt currentSelectedCount = selection.Count(); + const TInt memberCount = groupMembers->Count(); + TInt newMemberCount = 0; + // Go throug all members of the group + for (TInt i=0; i < memberCount; ++i) + { + const TContactItemId contactId = (*groupMembers)[i]; + if (!selection.Find(contactId)) + { + // This group member is not yet selected. Check if the + // member can be selected + if (!iFetchSelection->ContactSelectionAcceptedL + (contactId, + currentSelectedCount + newMemberCount)) + { + // If any member is rejected from being selected, + // the group can't be selected + selectionAccepted = EFalse; + break; + } + else + { + // Note: We are actually not yet adding any members + // to the set of selected ids. Adding occurs only + // if this method returns ETrue + newMemberCount++; + } + } + } + } + CleanupStack::PopAndDestroy(group); + } + else + { + selectionAccepted = ETrue; + } + return selectionAccepted; + } + +TBool CPbkGroupsListFetchDlgPage::ProcessSoftkeyMarkCommandL(TInt aCommandId) + { + TBool selectionAccepted(ETrue); + + if ( aCommandId == EAknSoftkeyMark ) + { + selectionAccepted = ContactSelectionAcceptedL( iControl->ContactIdAtL( + iControl->CurrentItemIndex()), KPbkSelectionCountNotUsed); + } + + if ( aCommandId == EAknSoftkeyUnmark || selectionAccepted ) + { + // Send event + TPbkContactViewListControlEvent event( TPbkContactViewListControlEvent::EContactSelected ); + event.iInt = iControl->CurrentItemIndex(); + event.iContactId = iControl->ContactIdAtL( event.iInt ); + + switch( aCommandId ) + { + case EAknSoftkeyMark: + { + // Send event about changed state + HandleContactViewListControlEventL( *iControl, event ); + break; + } + + case EAknSoftkeyUnmark: + { + // Send event about changed state + event.iEventType = TPbkContactViewListControlEvent::EContactUnselected; + HandleContactViewListControlEventL( *iControl, event ); + break; + } + + default:; + } + + return ETrue; + } + + return EFalse; + } + +CPbkContactViewListControl& CPbkGroupsListFetchDlgPage::Control() + { + return *iControl; + } + + +void CPbkGroupsListFetchDlgPage::HandleContactViewListControlEventL + (CPbkContactViewListControl& aControl, + const TPbkContactViewListControlEvent& aEvent) + { + __ASSERT_DEBUG(&aControl==iControl, + Panic(EPanicPreCond_HandleContactViewListControlEventL)); + + // Suppress the unused parameter warning + (void) aControl; + + switch (aEvent.iEventType) + { + case TPbkContactViewListControlEvent::EContactSelected: + { + HandleGroupSelectionL(aEvent.iContactId, ETrue); + break; + } + + case TPbkContactViewListControlEvent::EContactUnselected: + { + HandleGroupSelectionL(aEvent.iContactId, EFalse); + break; + } + case TPbkContactViewListControlEvent::EContactSetChanged: // FALLTHROUGH + default: + { + // Notify parent dialog that this page has changed + iParentDlg.FetchDlgPageChangedL(*this); + break; + } + } + } + +void CPbkGroupsListFetchDlgPage::HandleContactViewEvent + (const CContactViewBase& aView,const TContactViewEvent& aEvent) + { + TRAPD(err, HandleContactViewEventL(aView,aEvent)); + if (err != KErrNone) + { + iParentDlg.FetchDlgHandleError(err); + } + } + +TBool CPbkGroupsListFetchDlgPage::IsContactIncluded(TContactItemId aId) + { + return (iGroupsToInclude && iGroupsToInclude->Find(aId)); + } + +void CPbkGroupsListFetchDlgPage::SetupControlL() + { + if (AllBitsSet(iStateFlags,EAllViewsReady|EInitializing)) + { + iStateFlags &= ~EInitializing; + CPbkContactEngine& engine = iParentDlg.PbkEngine(); + for (TInt i=0; i < iAllGroupsView->CountL(); ++i) + { + const TContactItemId groupId = iAllGroupsView->AtL(i); + if (IsAnyGroupMemberInViewL(engine,groupId,iContactView)) + { + // Add all groups which have at least one member in iContactView + if (!iGroupsToInclude) + { + iGroupsToInclude = CPbkContactIdSet::NewL(); + } + iGroupsToInclude->AddL(groupId); + } + } + iGroupSubView->Refresh(); + iControl->ConstructL(engine, *iGroupSubView); + iControl->AddObserverL(*this); + } + } + +void CPbkGroupsListFetchDlgPage::HandleGroupSelectionL + (TContactItemId aGroupId, TBool aSelected) + { + CContactGroup* group = iParentDlg.PbkEngine().ReadContactGroupL(aGroupId); + CleanupStack::PushL(group); + const CContactIdArray* groupMembers = group->ItemsContained(); + if (groupMembers) + { + if (aSelected) + { + // Add those group members which are present in iContactView + const TInt memberCount = groupMembers->Count(); + for (TInt i=0; i < memberCount; ++i) + { + const TContactItemId contactId = (*groupMembers)[i]; + if (iContactView.FindL(contactId) != KErrNotFound) + { + iParentDlg.FetchDlgSelection().AddL(contactId); + } + } + } + else + { + // Remove all group members from current selection + iParentDlg.FetchDlgSelection().Remove(*groupMembers); + } + } + CleanupStack::PopAndDestroy(group); + } + +void CPbkGroupsListFetchDlgPage::HandleContactViewEventL + (const CContactViewBase& aView,const TContactViewEvent& aEvent) + { + if (&aView == &iContactView) + { + HandleContactViewEventL(aEvent); + } + else if (&aView == iAllGroupsView) + { + HandleGroupsViewEventL(aEvent); + } + } + +void CPbkGroupsListFetchDlgPage::HandleContactViewEventL + (const TContactViewEvent& aEvent) + { + switch (aEvent.iEventType) + { + case TContactViewEvent::EReady: + { + iStateFlags |= EContactViewReady; + SetupControlL(); + break; + } + + default: + { + break; + } + } + } + +void CPbkGroupsListFetchDlgPage::HandleGroupsViewEventL + (const TContactViewEvent& aEvent) + { + switch (aEvent.iEventType) + { + case TContactViewEvent::EReady: + { + iStateFlags |= EAllGroupsViewReady; + SetupControlL(); + break; + } + + case TContactViewEvent::EItemAdded: + { + CPbkContactEngine& engine = iParentDlg.PbkEngine(); + if ((iStateFlags & EContactViewReady) && + IsAnyGroupMemberInViewL(engine, aEvent.iContactId, iContactView)) + { + if (!iGroupsToInclude) + { + iGroupsToInclude = CPbkContactIdSet::NewL(); + } + iGroupsToInclude->AddL(aEvent.iContactId); + } + break; + } + + case TContactViewEvent::EItemRemoved: + { + if (iGroupsToInclude) + { + iGroupsToInclude->Remove(aEvent.iContactId); + } + break; + } + + default: + break; + } + } + +void CPbkGroupsListFetchDlgPage::LayoutContents() + { + AknLayoutUtils::LayoutControl( + iControl, + iParentDlg.FetchDlgClientRect(), + AknLayout::list_gen_pane(0)); + } + +const CContactIdArray& CPbkGroupsListFetchDlgPage::MarkedItemsL() const + { + return iControl->MarkedItemsL(); + } + +// End of File