phonebookui/Phonebook/View/src/CPbkContactEditorFieldArray.cpp
changeset 0 e686773b3f54
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/View/src/CPbkContactEditorFieldArray.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,435 @@
+/*
+* 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: 
+*           Methods for Phonebook Contact editor field array.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkContactEditorFieldArray.h"  // this class
+
+#include "MPbkContactEditorUiBuilder.h"
+#include <MPbkContactEditorField.h>
+#include "PbkContactEditorFieldFactory.h"
+#include "PbkFieldFormatterFactory.h"
+#include "CPbkContactItem.h"
+#include "MPbkPhoneNumberFormat.h"
+#include "PbkIconInfo.h"
+#include "CPbkFieldInfo.h"
+#include "CPbkReadingEditorBinderVisitor.h"
+#include <PbkView.rsg>
+
+#include <CPbkExtGlobals.h>
+#include <MPbkExtensionFactory.h>
+
+#include <PbkDebug.h>
+
+/// Unnamed namespace for local definitons
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+
+const TInt KArrayGranularity = 5;
+
+#ifdef _DEBUG
+/// Panic codes for CPbkContactEditorFieldArray
+enum TPanicCode
+    {
+	EPanicPostCond_ConstructL,
+	EPanicInvariant_FieldNotFound,
+	EPanicInvariant_MembersNotCreated,
+	EPanicPreCond_CreateFieldsFromContactL,
+	EPanicPreCond_DoAddFieldL,
+	EPanicInvariant_CountMismatch
+    };
+#endif  // _DEBUG
+
+// ==================== LOCAL FUNCTIONS ====================
+
+#ifdef _DEBUG
+void Panic(TPanicCode aReason)
+    {
+    _LIT(KPanicText, "CPbkContactEditorFieldArray");
+    User::Panic(KPanicText, aReason);
+    }
+#endif  // _DEBUG
+
+}  // namespace
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+inline CPbkContactEditorFieldArray::CPbkContactEditorFieldArray
+        (CPbkContactItem& aContactItem, 
+        MPbkContactEditorUiBuilder& aUiBuilder) :
+    iContactItem(aContactItem),
+    iUiBuilder(aUiBuilder),
+    iFieldArray(KArrayGranularity)
+    {
+    }
+
+inline void CPbkContactEditorFieldArray::ConstructL()
+    {
+    iIconInfoContainer = CPbkIconInfoContainer::NewL(R_PBK_ICON_INFO_ARRAY);
+
+    // Get extension factory for setting extension icons
+    CPbkExtGlobals* extGlobal = CPbkExtGlobals::InstanceL();
+    extGlobal->PushL();
+    MPbkExtensionFactory& factory = extGlobal->FactoryL();    
+    factory.AddPbkFieldIconsL(iIconInfoContainer);
+    CleanupStack::PopAndDestroy(extGlobal);
+
+    // Construct the reading field binder (visitor pattern)
+    iReadingFieldBinder = CPbkReadingEditorBinderVisitor::NewL();
+
+    __TEST_INVARIANT;
+
+    //PostCond:
+    __ASSERT_DEBUG(iIconInfoContainer, 
+            Panic(EPanicPostCond_ConstructL));
+    }
+
+CPbkContactEditorFieldArray* CPbkContactEditorFieldArray::NewL
+        (CPbkContactItem& aContactItem, 
+        MPbkContactEditorUiBuilder& aUiBuilder)
+    {
+	CPbkContactEditorFieldArray* dlg = new(ELeave) CPbkContactEditorFieldArray(aContactItem, aUiBuilder);
+    CleanupStack::PushL(dlg);
+    dlg->ConstructL();
+    CleanupStack::Pop();  // dlg
+    return dlg;
+    }
+
+CPbkContactEditorFieldArray::~CPbkContactEditorFieldArray()
+    {
+	__TEST_INVARIANT;
+
+    PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactEditorFieldArray::~CPbkContactEditorFieldArray"));
+
+    // delete member data
+    delete iReadingFieldBinder;
+    delete iIconInfoContainer;
+
+    iFieldArray.ResetAndDestroy();
+    }
+
+void CPbkContactEditorFieldArray::CreateFieldsFromContactL()
+    {
+	__ASSERT_DEBUG(iFieldArray.Count() == 0, Panic(EPanicPreCond_CreateFieldsFromContactL));
+
+	__TEST_INVARIANT;
+
+    CPbkFieldArray& fieldSet = iContactItem.CardFields();
+    const TInt fieldCount = fieldSet.Count();
+    for (TInt i=0; i < fieldCount; ++i)
+        {
+        TPbkContactItemField& contactItemField = fieldSet[i];
+        if (contactItemField.FieldInfo().IsEditable())
+            {
+	        MPbkContactEditorField* field = PbkContactEditorFieldFactory::CreateFieldL(
+                    contactItemField, iUiBuilder, *iIconInfoContainer);
+            iFieldArray.InsertL(iFieldArray.Count(), field);
+            }
+        }
+
+    AcceptL(*iReadingFieldBinder);
+
+	__TEST_INVARIANT;
+    }
+
+void CPbkContactEditorFieldArray::AcceptL(MPbkFieldEditorVisitor& aVisitor)
+    {
+    const TInt count = iFieldArray.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        iFieldArray[i]->AcceptL(aVisitor);
+        }
+    }
+
+TBool CPbkContactEditorFieldArray::AreAllFieldsEmpty() const
+    {
+	__TEST_INVARIANT;
+
+	TBool result = ETrue;
+    const CPbkFieldArray& fields = iContactItem.CardFields();
+    const TInt fieldCount = fields.Count();
+    for (TInt i=0; i < fieldCount; ++i)
+        {
+        const TPbkContactItemField& contactItemField = fields[i];
+        if ( !contactItemField.IsEmptyOrAllSpaces() &&
+                // The Synchronization field does not count here
+                contactItemField.FieldInfo().FieldId()
+                != EPbkFieldIdSyncronization )
+            {
+			result = EFalse;
+			break;
+            }
+        }
+
+	__TEST_INVARIANT;
+
+    return result;
+    }
+
+void CPbkContactEditorFieldArray::AddFieldL
+        (TPbkContactItemField& aField)
+    {
+	__TEST_INVARIANT;
+
+	DoAddFieldL(aField, iFieldArray.Count());
+
+	__TEST_INVARIANT;
+    }
+
+void CPbkContactEditorFieldArray::RemoveField
+        (MPbkContactEditorField& aField)
+    {
+	__TEST_INVARIANT;
+
+	const TInt count = iFieldArray.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        MPbkContactEditorField* field = iFieldArray[i];
+        if (field == &aField)
+            {
+            iReadingFieldBinder->NotifyEditorDeletion( field->FieldId() );
+            iUiBuilder.DeleteControl(field->ControlId());     
+            iFieldArray.Delete(i);
+			iContactItem.RemoveField(
+				iContactItem.FindFieldIndex(aField.ContactItemField()));
+			delete field;
+			break;
+            }
+        }
+
+	__TEST_INVARIANT;
+    }
+
+TInt CPbkContactEditorFieldArray::ContactItemFieldCount() const
+    {
+	__TEST_INVARIANT;
+
+    return iContactItem.CardFields().Count();
+    }
+
+TInt CPbkContactEditorFieldArray::EditorCount() const
+    {
+	__TEST_INVARIANT;
+
+    return iFieldArray.Count();
+    }
+
+const MPbkContactEditorField& CPbkContactEditorFieldArray::FieldAt
+		(TInt aFieldIndex)
+	{
+	__TEST_INVARIANT;
+
+	return *iFieldArray[aFieldIndex];
+	}
+
+MPbkContactEditorField* CPbkContactEditorFieldArray::Find
+        (const TPbkContactItemField& aField) const
+    {
+	__TEST_INVARIANT;
+
+    MPbkContactEditorField* result = NULL;
+	const TInt count = iFieldArray.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldArray[i]->ContactItemField().IsSame(aField))
+            {
+            result = iFieldArray[i];
+            break;
+            }
+        }
+
+	__TEST_INVARIANT;
+    return result;
+    }
+
+MPbkContactEditorField* CPbkContactEditorFieldArray::Find
+        (TInt aControlId) const
+    {
+	__TEST_INVARIANT;
+
+    MPbkContactEditorField* field = NULL;
+	const TInt count = iFieldArray.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldArray[i]->ControlId() == aControlId)
+            {
+            field = iFieldArray[i];
+            break;
+            }
+        }
+
+	__TEST_INVARIANT;
+    return field;
+    }
+
+TInt CPbkContactEditorFieldArray::FindContactItemFieldIndex
+        (const TPbkContactItemField& aField) const
+    {
+	__TEST_INVARIANT;
+
+    return iContactItem.FindFieldIndex(aField);
+    }
+
+void CPbkContactEditorFieldArray::SaveFieldsL()
+    {
+	__TEST_INVARIANT;
+
+    for (TInt i = 0; i < iFieldArray.Count(); ++i)
+        {
+        iFieldArray[i]->SaveFieldL();
+        }
+
+	__TEST_INVARIANT;
+	}
+
+TBool CPbkContactEditorFieldArray::FieldsChanged() const
+    {
+	__TEST_INVARIANT;
+
+	TBool result = EFalse;
+    for (TInt i = 0; i < iFieldArray.Count(); ++i)
+        {
+        if (iFieldArray[i]->FieldDataChanged())
+			{
+			result = ETrue;
+			}
+        // can break because at least one field has changed
+        if (result)
+            {
+            break;
+            }
+        }
+
+	__TEST_INVARIANT;
+    return result;
+    }
+
+void CPbkContactEditorFieldArray::SetFocusToIndex
+		(TInt aFocusIndex)
+	{
+	__TEST_INVARIANT;
+
+	MPbkContactEditorField* field = Find(iContactItem.CardFields()[aFocusIndex]);
+	TInt err = KErrNotFound;
+	if (field)
+		{
+		TRAP(err, iUiBuilder.TryChangeFocusL(field->ControlId()));
+		}
+
+	for (TInt i = 0; i < iFieldArray.Count() && err!=KErrNone; ++i)
+		{
+		if (iUiBuilder.Control(iFieldArray[i]->ControlId()))
+			{
+			TRAP(err,iUiBuilder.TryChangeFocusL(iFieldArray[i]->ControlId()));
+			}
+		}
+
+	__TEST_INVARIANT;
+	}
+
+MPbkContactEditorField& CPbkContactEditorFieldArray::CreateFieldL
+		(CPbkFieldInfo& aFieldInfo)
+	{
+	__TEST_INVARIANT;
+
+	TPbkContactItemField& newField = iContactItem.AddFieldL(aFieldInfo);
+	
+	// Find field from iContact item. 
+	// Its editable field index is the insertion position
+	TInt fieldIndex = 0;
+	for (TInt i = 0; i < iContactItem.CardFields().Count(); ++i)
+		{
+		const TPbkContactItemField& field = iContactItem.CardFields()[i];
+		const TBool match = field.IsSame(newField);
+		if(field.FieldInfo().IsEditable() && !match)
+			{
+			fieldIndex++;
+			}
+		if (match)
+			{
+			break;
+			}
+		}
+		
+	MPbkContactEditorField& addedField = DoAddFieldL(newField, fieldIndex);
+    addedField.AcceptL(*iReadingFieldBinder);
+    addedField.ActivateL();
+	
+	__TEST_INVARIANT;
+
+	return addedField;
+	}
+
+/**
+ * Not class invariant compliant.
+ */
+MPbkContactEditorField& CPbkContactEditorFieldArray::DoAddFieldL
+        (TPbkContactItemField& aField,
+		TInt aFieldInsertIndex)
+    {
+	__ASSERT_DEBUG(aFieldInsertIndex <= iFieldArray.Count(), 
+		Panic(EPanicPreCond_DoAddFieldL));
+
+    // create same order in UI
+	if (aFieldInsertIndex > 0)
+		{
+		// Focus must be set to the field preceeding the insertion point.
+		// Please note that this means it is not possible to insert to the 
+		// first dialog position!
+		const TInt controlId = iFieldArray[aFieldInsertIndex-1]->ControlId();
+		iUiBuilder.TryChangeFocusL(controlId);
+		}
+
+	MPbkContactEditorField* field = PbkContactEditorFieldFactory::CreateFieldL(
+            aField, iUiBuilder, *iIconInfoContainer);
+    iFieldArray.InsertL(aFieldInsertIndex, field);
+	return *field;
+    }
+
+void CPbkContactEditorFieldArray::__DbgTestInvariant() const
+	{
+	#if defined(_DEBUG)
+
+	__ASSERT_DEBUG(iFieldArray.Count() <= iContactItem.CardFields().Count(), 
+			Panic(EPanicInvariant_CountMismatch));
+
+	const TInt count = iFieldArray.Count();
+	for (TInt i = 0; i < count; ++i)
+		{
+		TBool result = EFalse;
+		for (TInt j = 0; j < iContactItem.CardFields().Count() && !result; ++j)
+			{
+			TPbkContactItemField& field = iContactItem.CardFields()[j];
+			if (&field.ContactItemField() == &iFieldArray[j]->ContactItemField().ContactItemField() &&
+				field.FieldInfo().IsEditable())
+				{
+				result = ETrue;
+				}
+			}
+		__ASSERT_DEBUG(result, Panic(EPanicInvariant_FieldNotFound));
+		}
+
+    __ASSERT_DEBUG(iIconInfoContainer, 
+            Panic(EPanicInvariant_MembersNotCreated));
+
+	#endif
+	}
+
+// End of File