phonebookui/Phonebook2/UIControls/src/CPbk2AddItemToContactDlg.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2AddItemToContactDlg.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,444 @@
+/*
+* Copyright (c) 2005-2007 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:  Phonebook 2 add new contact field to a contact dialog.
+*
+*/
+
+
+#include <CPbk2AddItemToContactDlg.h>
+
+// Phonebook 2
+#include <TPbk2AddItemDialogParams.h>
+#include <TPbk2AddItemWrapper.h>
+#include <Pbk2UIControls.rsg>
+#include <CPbk2IconArray.h>
+#include <TPbk2AppIconId.h>
+#include <CPbk2UIExtensionManager.h>
+#include <MPbk2UIExtensionIconSupport.h>
+#include <MPbk2AppUi.h>
+#include <CPbk2ServiceManager.h>
+#include <MPbk2ApplicationServices.h>
+#include <MPbk2ApplicationServices2.h>
+#include "CPbk2IconInfo.h"
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <MPbk2ApplicationServices.h>
+
+// System includes
+#include <aknPopup.h>
+#include <aknlists.h>
+#include <barsread.h>
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+const TInt KMaxListBoxBufferSize = 128;
+_LIT(KListBoxIconFormat, "%d\t");
+
+#ifdef _DEBUG
+
+enum TPanicCode
+    {
+    EPanicPreCond_ResetWhenDestroyed = 1
+    };
+
+void Panic( TInt aReason )
+    {
+    _LIT( KPanicText, "CPbk2AddItemToContactDlg" );
+    User::Panic( KPanicText, aReason );
+    }
+
+#endif // _DEBUG
+
+
+/**
+ * Phonebook 2 list box model for add item wrappers.
+ */
+NONSHARABLE_CLASS(CModel) : public CBase,
+                            public MDesCArray
+    {
+    public: // Construction
+
+        /**
+         * Constructor.
+         *
+         * @param aArray        An array of wrappers.
+         * @param aIconArray    Icon array.
+         * @return  A new instance of this class.
+         */
+        CModel(
+                RArray<TPbk2AddItemWrapper>& aArray,
+                CPbk2IconArray& aIconArray );
+
+    public: // From MDesCArray
+        TInt MdcaCount() const;
+        TPtrC16 MdcaPoint(
+                TInt aIndex ) const;
+
+    private: // Implementation
+        static TInt Compare(
+                const TPbk2AddItemWrapper& aLhs,
+                const TPbk2AddItemWrapper& aRhs );
+
+    private: // Data
+        /// Ref: Array of TPbk2AddItemWrapper objects to show
+        RArray<TPbk2AddItemWrapper>& iArray;
+        /// Own: Buffer for formatting a list box row text
+        mutable TBuf16<KMaxListBoxBufferSize> iBuffer;
+        /// Ref: Icons for field types
+        CPbk2IconArray& iIconArray;
+    };
+
+// --------------------------------------------------------------------------
+// CModel::CModel
+// --------------------------------------------------------------------------
+//
+CModel::CModel(RArray<TPbk2AddItemWrapper>& aArray,
+    CPbk2IconArray& aIconArray) :
+        iArray(aArray),
+        iIconArray(aIconArray)
+    {
+    iArray.Sort(TLinearOrder<TPbk2AddItemWrapper>(CModel::Compare));
+    }
+
+// --------------------------------------------------------------------------
+// CModel::MdcaCount
+// --------------------------------------------------------------------------
+//
+TInt CModel::MdcaCount() const
+    {
+    return iArray.Count();
+    }
+
+// --------------------------------------------------------------------------
+// CModel::MdcaPoint
+// --------------------------------------------------------------------------
+//
+TPtrC16 CModel::MdcaPoint( TInt aIndex ) const
+    {
+    // Insert icon index
+    TInt iconIndex = iIconArray.FindIcon(iArray[aIndex].IconId());
+    if (iconIndex < 0)
+        {
+        // If icon is not found by Id fall back to empty icon
+        iconIndex = iIconArray.FindIcon(
+            TPbk2AppIconId(EPbk2qgn_prop_nrtyp_empty));
+        }
+
+    iBuffer.Format(KListBoxIconFormat, iconIndex);
+    const TDesC& fieldName = iArray[aIndex].Label();
+    const TInt chars = Min(iBuffer.MaxLength() - iBuffer.Length(),
+        fieldName.Length());
+    iBuffer.Append(fieldName.Left(chars));
+    return iBuffer;
+    }
+
+// --------------------------------------------------------------------------
+// CModel::Compare
+// --------------------------------------------------------------------------
+//
+TInt CModel::Compare(   const TPbk2AddItemWrapper& aLhs,
+        const TPbk2AddItemWrapper& aRhs )
+    {
+    return aLhs.AddItemOrdering() - aRhs.AddItemOrdering();
+    }
+
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::CPbk2AddItemToContactDlg
+// --------------------------------------------------------------------------
+//
+inline CPbk2AddItemToContactDlg::CPbk2AddItemToContactDlg( MPbk2ApplicationServices* aAppServices ) :
+	iAppServices( aAppServices )
+    {
+    // Do nothing
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::~CPbk2AddItemToContactDlg
+// --------------------------------------------------------------------------
+//
+CPbk2AddItemToContactDlg::~CPbk2AddItemToContactDlg()
+    {
+    // Tells ExecuteLD this object has been destroyed
+    if (iDestroyedPtr)
+        {
+        *iDestroyedPtr = ETrue;
+        }
+
+    if ( iSelfPtr )
+        {
+        *iSelfPtr = NULL;
+        }
+
+    if ( iPopup )
+        {
+        iPopup->CancelPopup();
+        }
+
+    delete iListBox;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::NewL
+// --------------------------------------------------------------------------
+//
+EXPORT_C CPbk2AddItemToContactDlg* CPbk2AddItemToContactDlg::NewL()
+    {
+    CPbk2AddItemToContactDlg* self = new(ELeave) CPbk2AddItemToContactDlg();
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::NewL
+// --------------------------------------------------------------------------
+//
+EXPORT_C CPbk2AddItemToContactDlg* CPbk2AddItemToContactDlg::NewL(
+	MPbk2ApplicationServices* aAppServices )
+    {
+    CPbk2AddItemToContactDlg* self = new(ELeave) CPbk2AddItemToContactDlg( aAppServices );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::ExecuteLD
+// --------------------------------------------------------------------------
+//
+EXPORT_C TInt CPbk2AddItemToContactDlg::ExecuteLD
+        ( RArray<TPbk2AddItemWrapper>& aAddItems,
+          const TPbk2AddItemDialogParams* aParams /*= NULL*/ )
+    {
+    CleanupStack::PushL( this );
+
+    TBool thisDestroyed = EFalse;
+    iDestroyedPtr = &thisDestroyed;
+
+    PreparePopupL( aAddItems, aParams );
+    TInt result = ExecutePopupL( aParams );
+
+    if ( thisDestroyed )
+        {
+        // This object has been destroyed
+        CleanupStack::Pop( this );
+        }
+    else
+        {
+        CleanupStack::PopAndDestroy( this );
+        }
+
+    return result;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::RequestExitL
+// --------------------------------------------------------------------------
+//
+void CPbk2AddItemToContactDlg::RequestExitL( TInt /*aCommandId*/ )
+    {
+    if ( iPopup )
+        {
+        iPopup->CancelPopup();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::ForceExit
+// --------------------------------------------------------------------------
+//
+void CPbk2AddItemToContactDlg::ForceExit()
+    {
+    delete this;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::ResetWhenDestroyed
+// --------------------------------------------------------------------------
+//
+void CPbk2AddItemToContactDlg::ResetWhenDestroyed
+        ( MPbk2DialogEliminator** aSelfPtr )
+    {
+    __ASSERT_DEBUG(!aSelfPtr || *aSelfPtr == this,
+        Panic( EPanicPreCond_ResetWhenDestroyed ) );
+
+    iSelfPtr = aSelfPtr;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::PreparePopupL
+// --------------------------------------------------------------------------
+//
+void CPbk2AddItemToContactDlg::PreparePopupL
+        ( RArray<TPbk2AddItemWrapper>& aAddItems,
+          const TPbk2AddItemDialogParams* aParams )
+    {
+    // Create a list box
+    delete iListBox;
+    iListBox = NULL;
+    iListBox = static_cast<CEikFormattedCellListBox*>
+        ( EikControlFactory::CreateByTypeL
+                ( EAknCtSingleGraphicPopupMenuListBox ).iControl );
+
+    TInt cbaResource = R_AVKON_SOFTKEYS_OK_CANCEL__OK;
+    if (aParams && aParams->iCbaResource)
+        {
+        cbaResource = aParams->iCbaResource;
+        }
+
+    // Create a popup list
+    if ( iPopup )
+        {
+        iPopup->CancelPopup();
+        iPopup = NULL;
+        }
+    iPopup = CAknPopupList::NewL( iListBox,
+        cbaResource, AknPopupLayouts::EMenuGraphicWindow );
+
+    if ( aParams && aParams->iTitle && aParams->iTitle->Length() > 0 )
+        {
+        iPopup->SetTitleL( *aParams->iTitle );
+        }
+
+    // Init list box
+    iListBox->ConstructL( iPopup, CEikListBox::ELeftDownInViewRect );
+    iListBox->CreateScrollBarFrameL( ETrue );
+    iListBox->ScrollBarFrame()->SetScrollBarVisibilityL
+        ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
+
+    // Create icon array
+    TResourceReader reader;
+    CCoeEnv::Static()->CreateResourceReaderLC
+        ( reader, R_PBK2_FIELDTYPE_ICONS );
+    CPbk2IconArray* iconArray = CPbk2IconArray::NewL(reader);
+    CleanupStack::PopAndDestroy(); // reader
+    CleanupStack::PushL( iconArray );
+    
+    //Calculate preferred size for xsp service icons 
+    TRect mainPane;
+    AknLayoutUtils::LayoutMetricsRect(
+        AknLayoutUtils::EMainPane, mainPane );
+    TAknLayoutRect listLayoutRect;
+    listLayoutRect.LayoutRect(
+        mainPane,
+        AknLayoutScalable_Avkon::list_single_graphic_pane_g2(0).LayoutLine() );
+    TSize size(listLayoutRect.Rect().Size());
+    
+    MPbk2ApplicationServices2* servicesExtension = NULL ;
+    
+    /*
+	 * Use iAppServices if provided. This is to enable editor use outside from pbk2 context
+	 */
+	if( iAppServices )
+		{
+		servicesExtension = reinterpret_cast<MPbk2ApplicationServices2*>
+			( iAppServices->MPbk2ApplicationServicesExtension( KMPbk2ApplicationServicesExtension2Uid ) );
+		}
+	else
+		{
+		// Add xsp service icons
+		servicesExtension =
+			reinterpret_cast<MPbk2ApplicationServices2*>
+				( Phonebook2::Pbk2AppUi()->ApplicationServices().
+					MPbk2ApplicationServicesExtension(
+						KMPbk2ApplicationServicesExtension2Uid ) );               
+		}
+	
+    CPbk2ServiceManager& servMan = servicesExtension->ServiceManager();
+    const CPbk2ServiceManager::RServicesArray& services = servMan.Services();
+    TUid uid;
+    uid.iUid = KPbk2ServManId;
+    for ( TInt i = 0; i < services.Count(); i++ )
+        {
+        const CPbk2ServiceManager::TService& service = services[i];
+        if ( service.iBitmapId && service.iBitmap )
+            {
+        	AknIconUtils::SetSize(
+        	           service.iBitmap,
+        	           size );
+        	AknIconUtils::SetSize(
+        	           service.iMask,
+        	           size );            
+            TPbk2IconId id = TPbk2IconId( uid, services[i].iBitmapId );
+            CPbk2IconInfo* info = CPbk2IconInfo::NewLC(
+            	id, services[i].iBitmap, services[i].iMask, size );
+            iconArray->AppendIconL(info);
+            CleanupStack::Pop(info);
+            }
+        }
+
+    // Add icons from UI extensions
+    CPbk2UIExtensionManager* extManager =
+        CPbk2UIExtensionManager::InstanceL();
+    extManager->PushL();
+    extManager->IconSupportL().AppendExtensionIconsL( *iconArray );
+    CleanupStack::PopAndDestroy(); // extManager
+    CleanupStack::Pop( iconArray );
+
+    // Set icon array
+    iListBox->ItemDrawer()->ColumnData()->SetIconArray( iconArray );
+
+    // Create listbox model
+    CModel* listBoxModel = new(ELeave) CModel( aAddItems, *iconArray );
+    iListBox->Model()->SetItemTextArray(listBoxModel);
+    iListBox->Model()->SetOwnershipType(ELbmOwnsItemArray);
+    
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2AddItemToContactDlg::ExecutePopupL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2AddItemToContactDlg::ExecutePopupL
+        ( const TPbk2AddItemDialogParams* aParams )
+    {
+    TInt result = KErrCancel;
+
+    if ( aParams && aParams->iSelectionIndex >= 0 )
+        {
+        // Silent mode, the selection has already been made
+        // Result is the same index as was given in parameters,
+        // the aAddItems array got sorted when creating the list box model
+        // so the returned index value is valid now
+        result = aParams->iSelectionIndex;
+        }
+    else
+        {
+        // iDestroyedPtr points to ExecuteLD's thisDestroyed local variable,
+        // and we need another destruction check here. We cannot copy the
+        // solution from ExecuteLD since making iDestroyedPtr point to a
+        // local variable defined in this function rather than the
+        // variable of ExecuteLD causes the destructor change the value of
+        // a variable that is out of scope and it will lead to a crash
+        // eventually. So thisDestroyed now points to the
+        // ExecuteLD::thisDestroyed and it is still in scope in destructor.
+        TBool* thisDestroyed = iDestroyedPtr;
+
+        TBool popupAccepted = iPopup->ExecuteLD();
+        iPopup = NULL;
+
+        if ( popupAccepted && *thisDestroyed == EFalse )
+            {
+            // Retrieve and return selection
+            TInt index = iListBox->CurrentItemIndex();
+            if ( index >= KErrNone )
+                {
+                result = index;
+                }
+            }
+        }
+
+    return result;
+    }
+
+// End of File