--- /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 <cntitem.h>
+#include <calslbs.h>
+#include <aknlayout.cdl.h>
+
+// PbkView classes
+#include <PbkView.hrh>
+#include "MPbkFetchDlg.h"
+#include <CPbkContactViewListControl.h>
+
+// PbkEng classes
+#include <CPbkContactEngine.h>
+#include <CPbkContactIdSet.h>
+#include <CPbkContactSubView.h>
+#include <TPbkContactViewIterator.h>
+
+
+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<CPbkContactViewListControl*>
+ (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