--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2AddItemToContactDlg.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,443 @@
+/*
+* 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