phonebookui/Phonebook/View/src/CPbkGroupPopup.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/View/src/CPbkGroupPopup.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,378 @@
+/*
+* 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 UI control for Phonebook's "Add to group".
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkGroupPopup.h"  // This class
+#include <aknlists.h>   // AknListBoxUtils
+#include <aknPopup.h>   // CAknPopupList
+
+#include "CPbkInputAbsorber.h"
+#include "CPbkContactGroupListModel.h"
+
+#include <CPbkContactEngine.h>  // Phonebook engine
+#include <CPbkContactItem.h>    // CPbkContactItem
+
+/// Unnamed namespace for local defintions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+#ifdef _DEBUG
+enum TPanicCode
+    {
+    EPanicPostCond_Constructor = 1,
+    EPanicPreCond_ExecuteLD,
+    EPanicPreCond_RunPopupL,
+    EPanicLogic_RunPopupL,
+    EPanicPostCond_ExecuteLD,
+    EPanicPreCond_ResetWhenDestroyed
+    };
+
+void Panic(TPanicCode aReason)
+    {
+    _LIT(KPanicText, "CPbkGroupPopup");
+    User::Panic(KPanicText, aReason);
+    }
+#endif // _DEBUG
+
+} // namespace
+
+// MODULE DATA STRUCTURES
+
+NONSHARABLE_CLASS(CPbkGroupPopup::CPopupList) : 
+        public CAknPopupList
+    {
+    public:
+        /**
+         * Static constructor.
+         * @param aListbox the listbox to use in the list
+         * @param aCbaResource softkey resource
+         * @param aType popup layout type
+         * @return a new instance of this class
+         */
+	    static CPopupList* NewL(CEikListBox* aListBox, TInt aCbaResource,
+            AknPopupLayouts::TAknPopupLayouts aType=AknPopupLayouts::EMenuWindow);
+        /**
+         * Destructor.
+         */
+        ~CPopupList();
+        /**
+         * Resets the object pointer after destruction.
+         */
+        void ResetWhenDestroyed(CPopupList** aSelf);
+
+    protected:
+        /**
+         * Constructor.
+         */
+        CPopupList();
+
+    private:  // Data
+        /// Ref: self pointer
+        CPopupList** iSelfPtr;
+    };
+
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// CPbkGroupPopup::CPopupList
+inline CPbkGroupPopup::CPopupList::CPopupList()
+    {
+    }
+
+CPbkGroupPopup::CPopupList* CPbkGroupPopup::CPopupList::NewL
+        (CEikListBox* aListBox, 
+        TInt aCbaResource, 
+        AknPopupLayouts::TAknPopupLayouts aType)
+    {
+    CPopupList* self = new(ELeave) CPopupList;
+    CleanupStack::PushL(self);
+    self->CAknPopupList::ConstructL(aListBox, aCbaResource, aType);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CPbkGroupPopup::CPopupList::~CPopupList()
+    {
+    if (iSelfPtr)
+        {
+        *iSelfPtr = NULL;
+        }
+    }
+
+void CPbkGroupPopup::CPopupList::ResetWhenDestroyed(CPopupList** aSelf)
+    {
+    __ASSERT_DEBUG(!aSelf || *aSelf==this, Panic(EPanicPreCond_ResetWhenDestroyed));
+    iSelfPtr = aSelf;
+    }
+
+
+// CPbkGroupPopup::TParams
+CPbkGroupPopup::TParams::TParams
+        (CContactViewBase& aGroupView, 
+        TInt aInitialSoftkeyResId,
+        TInt aSoftKeyResId) :
+    iGroupView(&aGroupView),
+    iInitialSoftkeyResId(aInitialSoftkeyResId),
+    iSoftkeyResId(aSoftKeyResId),
+    iPrompt(NULL),
+    iEmptyText(NULL),
+    iListBoxFlags(0),
+    iSelectedGroupId(KNullContactId)
+    {
+    }
+
+
+// CPbkGroupPopup
+inline CPbkGroupPopup::CPbkGroupPopup(TParams& aParams) :
+    iParams(aParams)
+    {
+    __ASSERT_DEBUG
+        (!iInputAbsorber && !iListBox && !iPopupList && !iDestroyedPtr,
+        Panic(EPanicPostCond_Constructor));
+    }
+
+inline void CPbkGroupPopup::ConstructL()
+    {
+    }
+
+CPbkGroupPopup* CPbkGroupPopup::NewL(TParams& aParams)
+    {
+    CPbkGroupPopup* self = new(ELeave) CPbkGroupPopup(aParams);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CPbkGroupPopup::~CPbkGroupPopup()
+    {
+    if (iDestroyedPtr) 
+        {
+        *iDestroyedPtr = ETrue;
+        }
+    if (iSelfPtr)
+        {
+        *iSelfPtr = NULL;
+        }
+    if (iPopupList)
+        {
+        iPopupList->CancelPopup();
+        }
+    iParams.iGroupView->Close(*this);
+    delete iListBox;
+    delete iInputAbsorber;
+    }
+
+TInt CPbkGroupPopup::ExecuteLD()
+    {
+    __ASSERT_DEBUG(!iListBox && !iPopupList, Panic(EPanicPreCond_ExecuteLD));
+
+    TBool thisDestroyed = EFalse;
+    iDestroyedPtr = &thisDestroyed;
+    CleanupStack::PushL(this);
+
+    iInputAbsorber = CPbkInputAbsorber::NewL(iParams.iInitialSoftkeyResId);
+    iInputAbsorber->SetCommandObserver(this);
+
+    // Register to receive view events
+    iParams.iGroupView->OpenL(*this);
+
+    // Use CPbkInputAbsorber to provide modal behaviour until we get the popup list up
+    iInputAbsorber->Wait();
+
+    TInt result = 0;
+    if (thisDestroyed)
+        {
+        CleanupStack::Pop(this);
+        }
+    else
+        {
+        result = iResult;
+        if (result)
+            {
+            const TInt index = iListBox->CurrentItemIndex();
+            iParams.iSelectedGroupId = iParams.iGroupView->AtL(index);
+            }
+        __ASSERT_DEBUG(!result || iParams.iSelectedGroupId!=KNullContactId,
+            Panic(EPanicPostCond_ExecuteLD));
+        CleanupStack::PopAndDestroy(this);
+        }
+    return result;
+    }
+
+void CPbkGroupPopup::ResetWhenDestroyed(CPbkGroupPopup** aSelfPtr)
+    {
+    __ASSERT_DEBUG(!aSelfPtr || *aSelfPtr==this, 
+        Panic(EPanicPreCond_ResetWhenDestroyed));
+    iSelfPtr = aSelfPtr;
+    }
+
+void CPbkGroupPopup::HandleContactViewEvent
+        (const CContactViewBase& /*aView*/,
+        const TContactViewEvent& aEvent)
+    {
+    TRAPD(err, DoHandleContactViewEventL(aEvent));
+    if (err != KErrNone)
+        {
+        CCoeEnv::Static()->HandleError(err);
+        Close();
+        }
+    }
+
+void CPbkGroupPopup::ProcessCommandL(TInt aCommandId)
+    {
+    switch (aCommandId)
+        {
+        case EAknSoftkeyCancel: // FALLTHROUGH
+        case EAknSoftkeyBack:   // FALLTHROUGH
+        case EAknSoftkeyNo:     // FALLTHROUGH
+        case EAknSoftkeyClose:  // FALLTHROUGH
+        case EAknSoftkeyExit:   
+            {
+            Close();
+            break;
+            }
+
+        default:
+            break;
+        }
+    }
+
+void CPbkGroupPopup::RunPopupL()
+    {
+    __ASSERT_DEBUG(iInputAbsorber->IsWaiting(), Panic(EPanicPreCond_RunPopupL));
+
+    // Create a list box
+    iListBox = static_cast<CEikColumnListBox*>
+        (EikControlFactory::CreateByTypeL(EAknCtSinglePopupMenuListBox).iControl);
+
+    // Create a popup list
+    iPopupList = CPopupList::NewL(iListBox, iParams.iSoftkeyResId);
+    iPopupList->ResetWhenDestroyed(&iPopupList);
+
+    // Init list box
+    iListBox->ConstructL(iPopupList, iParams.iListBoxFlags | CEikListBox::ELeftDownInViewRect);
+    CPbkContactGroupListModel* listBoxModel = CPbkContactGroupListModel::NewL
+        (*iParams.iGroupView);
+    iListBox->Model()->SetOwnershipType(ELbmOwnsItemArray);
+    iListBox->Model()->SetItemTextArray(listBoxModel);
+	iListBox->CreateScrollBarFrameL(ETrue);
+	iListBox->ScrollBarFrame()->SetScrollBarVisibilityL
+        (CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
+    
+    // Set empty text for the listbox
+    if (iParams.iEmptyText)
+        {
+        iListBox->View()->SetListEmptyTextL(*iParams.iEmptyText);
+        }
+
+    // set title of popuplist
+    if (iParams.iPrompt && iParams.iPrompt->Length() > 0)
+        {
+        iPopupList->SetTitleL(*iParams.iPrompt);
+        }
+
+    iResult = iPopupList->ExecuteLD();
+    __ASSERT_DEBUG(!iPopupList, Panic(EPanicLogic_RunPopupL));
+
+    // Wait is started in ExecuteLD()
+    iInputAbsorber->StopWait();
+    }
+
+void CPbkGroupPopup::Close()
+    {
+    // Wait is started in ExecuteLD()
+    iInputAbsorber->StopWait();
+    delete this;
+    }
+
+void CPbkGroupPopup::DoHandleContactViewEventL
+        (const TContactViewEvent& aEvent)
+    {
+    switch (aEvent.iEventType)
+        {
+        case TContactViewEvent::EReady:
+            {
+            // Run the popup list query
+            RunPopupL();
+            break;
+            }
+
+        case TContactViewEvent::ESortOrderChanged:
+            {
+            if (iListBox)
+                {
+                iListBox->Reset();
+                iListBox->DrawNow();
+                }
+            break;
+            }
+
+        case TContactViewEvent::EItemAdded:
+            {
+            if (iListBox)
+                {
+                const TInt focusIndex = iListBox->CurrentItemIndex();
+                if (focusIndex >= aEvent.iInt)
+                    {
+                    iListBox->SetCurrentItemIndex(focusIndex + 1);
+                    }
+                iListBox->HandleItemAdditionL();
+                }
+            break;
+            }
+
+        case TContactViewEvent::EItemRemoved:
+            {
+            if (iListBox)
+                {
+                const TInt focusIndex = iListBox->CurrentItemIndex();
+                AknListBoxUtils::HandleItemRemovalAndPositionHighlightL
+                    (iListBox, focusIndex, focusIndex==aEvent.iInt);
+                }
+            break;
+            }
+
+        case TContactViewEvent::EUnavailable:
+            {
+            Close();
+            break;
+            }
+
+        case TContactViewEvent::ESortError:     // FALLTHROUGH
+        case TContactViewEvent::EServerError:   // FALLTHROUGH
+        case TContactViewEvent::EIndexingError:
+            {
+            CCoeEnv::Static()->HandleError(aEvent.iInt);
+            Close();
+            break;
+            }
+
+        default:
+            {
+            Close();
+            break;
+            }
+        }
+    }
+
+
+//  End of File