TizenRefApp-7395 Implement ability to create only one Birthday event 81/93881/1
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Wed, 26 Oct 2016 07:26:11 +0000 (10:26 +0300)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Wed, 26 Oct 2016 07:27:29 +0000 (10:27 +0300)
[Implementation] Implemented support of exclusive types.
Implemented setting next available type for each added field.

Change-Id: I753aa009030dcde4e950582627a7b252abe52b1a
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
13 files changed:
lib-contacts/inc/Contacts/Input/ContactTypedFieldControl.h
lib-contacts/inc/Contacts/Input/ContactTypedFieldItem.h
lib-contacts/inc/Contacts/Model/ContactArray.h
lib-contacts/inc/Contacts/Model/ContactEnumField.h
lib-contacts/inc/Contacts/Model/ContactFieldMetadata.h
lib-contacts/inc/Contacts/Model/ContactTypedArray.h [new file with mode: 0644]
lib-contacts/src/Contacts/Input/ContactTypedFieldControl.cpp
lib-contacts/src/Contacts/Input/ContactTypedFieldItem.cpp
lib-contacts/src/Contacts/Model/ContactArray.cpp
lib-contacts/src/Contacts/Model/ContactEnumField.cpp
lib-contacts/src/Contacts/Model/ContactFieldFactory.cpp
lib-contacts/src/Contacts/Model/ContactFieldMetadata.cpp
lib-contacts/src/Contacts/Model/ContactTypedArray.cpp [new file with mode: 0644]

index da162dd..827f0da 100644 (file)
@@ -18,8 +18,7 @@
 #ifndef CONTACTS_INPUT_CONTACT_TYPED_FIELD_CONTROL_H
 #define CONTACTS_INPUT_CONTACT_TYPED_FIELD_CONTROL_H
 
-#include "Contacts/Model/ContactEnumField.h"
-#include "Contacts/Model/ContactTextField.h"
+#include "Contacts/Model/ContactTypedObject.h"
 #include "Ui/Hoversel.h"
 
 namespace Contacts
@@ -35,17 +34,19 @@ namespace Contacts
                {
                public:
                        /**
-                        * @brief Create type control
-                        * @param[in]   typeField   Object's "type" field
-                        * @param[in]   labelField  Object's custom type label field
+                        * @brief Create type control.
+                        * @param[in]   object  Typed object
                         */
-                       ContactTypedFieldControl(Model::ContactEnumField &typeField,
-                                       Model::ContactTextField &labelField);
+                       ContactTypedFieldControl(Model::ContactTypedObject &object);
 
                private:
+                       const char *getValueName(int value) const;
+
                        virtual void onCreated() override;
+                       void onClicked(Evas_Object *hoversel, void *eventInfo);
                        bool onSelected(void *data);
 
+                       Model::ContactTypedObject &m_Object;
                        Model::ContactEnumField &m_TypeField;
                        Model::ContactTextField &m_LabelField;
                };
index 49649b7..2a0d16a 100644 (file)
@@ -47,7 +47,7 @@ namespace Contacts
                        /**
                         * @return ContactTypedObject associated with the item.
                         */
-                       const Model::ContactTypedObject &getTypedObject() const;
+                       Model::ContactTypedObject &getTypedObject() const;
 
                        /**
                         * @see GenItem::getContent()
@@ -58,10 +58,6 @@ namespace Contacts
                         * @see GenItem::getState()
                         */
                        virtual Eina_Bool getState(Evas_Object *parent, const char *part) override;
-
-               private:
-                       Model::ContactEnumField &m_TypeField;
-                       Model::ContactTextField &m_LabelField;
                };
        }
 }
index d2a18ca..6f086c0 100644 (file)
@@ -58,6 +58,11 @@ namespace Contacts
 
                protected:
                        /**
+                        * @brief Called for custom initialization of newly added field.
+                        */
+                       virtual void initializeField(ContactField &field) { }
+
+                       /**
                         * @return Array type metadata.
                         */
                        const ContactArrayMetadata &getArrayMetadata() const;
index b573048..2a89e61 100644 (file)
@@ -49,11 +49,6 @@ namespace Contacts
                        virtual bool isChanged() const override;
 
                        /**
-                        * @return Array of possible values.
-                        */
-                       Utils::Range<const int *> getValues() const;
-
-                       /**
                         * @return Enum value that specifies that custom value is set.
                         */
                        int getCustomValue() const;
index 6e91a66..cca3d1a 100644 (file)
@@ -85,6 +85,15 @@ namespace Contacts
                };
 
                /**
+                * @brief Enum value metadata.
+                */
+               struct ContactEnumValue
+               {
+                       int value;          /**< Enum value */
+                       bool isExclusive;   /**< Whether only one field in array can have this value */
+               };
+
+               /**
                 * @brief Enum type metadata.
                 *
                 * @see ContactFieldMetadata
@@ -92,7 +101,7 @@ namespace Contacts
                struct ContactEnumMetadata
                {
                        ContactTypeMetadata base;
-                       Utils::Range<const int *> values; /**< Possible values */
+                       Utils::Range<const ContactEnumValue *> values; /**< Possible values */
                        int defaultValue;    /**< Default value */
                        int customValue;     /**< Value that signifies the custom value being set */
                };
diff --git a/lib-contacts/inc/Contacts/Model/ContactTypedArray.h b/lib-contacts/inc/Contacts/Model/ContactTypedArray.h
new file mode 100644 (file)
index 0000000..ddd22bc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef CONTACTS_MODEL_CONTACT_TYPED_ARRAY_H
+#define CONTACTS_MODEL_CONTACT_TYPED_ARRAY_H
+
+#include "Contacts/Model/ContactArray.h"
+#include "Contacts/Model/ContactFieldMetadata.h"
+
+namespace Contacts
+{
+       namespace Model
+       {
+               class ContactTypedObject;
+
+               /**
+                * @brief Represent an array of ContactTypedObject's.
+                */
+               class ContactTypedArray : public ContactArray
+               {
+               public:
+                       using ContactArray::ContactArray;
+
+                       /**
+                        * @brief Get available types for a given objects.
+                        * @param[in]   object  Typed object to get types for
+                        * @return Available type values.
+                        */
+                       std::vector<int> getTypes(const ContactTypedObject &object) const;
+
+               protected:
+                       /**
+                        * @return Enum type metadata.
+                        */
+                       const ContactEnumMetadata &getEnumMetadata() const;
+
+                       /**
+                        * @see ContactFieldContainer::initializeField()
+                        */
+                       virtual void initializeField(ContactField &field) override;
+
+               private:
+                       bool isTypeUsed(const ContactField &excludedfield, int type) const;
+               };
+       }
+}
+
+#endif /* CONTACTS_MODEL_CONTACT_TYPED_ARRAY_H */
index 9ce6cfb..3c3c25d 100644 (file)
  */
 
 #include "Contacts/Input/ContactTypedFieldControl.h"
-#include "Contacts/Model/ContactEnumField.h"
-#include "Contacts/Model/ContactTextField.h"
+#include "Contacts/Model/ContactTypedArray.h"
 #include "Common/Strings.h"
 
 #include "Ux/EditfieldPopup.h"
+#include "Utils/Callback.h"
 #include "Utils/Logger.h"
 
 using namespace Common;
 using namespace Contacts::Input;
 using namespace Contacts::Model;
 
-ContactTypedFieldControl::ContactTypedFieldControl(ContactEnumField &typeField,
-               ContactTextField &labelField)
-       : m_TypeField(typeField), m_LabelField(labelField)
+ContactTypedFieldControl::ContactTypedFieldControl(Model::ContactTypedObject &object)
+       : m_Object(object), m_TypeField(object.getTypeField()), m_LabelField(object.getLabelField())
 {
 }
 
-void ContactTypedFieldControl::onCreated()
+const char *ContactTypedFieldControl::getValueName(int value) const
 {
-       int currentValue = m_TypeField.getValue();
-
-       auto pairs = getEnumValueNames(EnumType(m_TypeField.getSubType()));
-       for (auto &&pair : pairs) {
-               addItem(pair.name, (void *) (long) pair.value);
-
-               if (pair.value == currentValue) {
-                       setText(pair.name);
-               }
-       }
+       return getEnumValueName(EnumType(m_TypeField.getSubType()), value);
+}
 
+void ContactTypedFieldControl::onCreated()
+{
        if (m_TypeField.hasCustomValue()) {
                setText(m_LabelField.getValue());
+       } else {
+               setText(getValueName(m_TypeField.getValue()));
        }
 
        setSelectCallback(std::bind(&ContactTypedFieldControl::onSelected, this,
                        std::placeholders::_1));
+       evas_object_smart_callback_add(getEvasObject(), "clicked",
+                       makeCallback(&ContactTypedFieldControl::onClicked), this);
+}
+
+void ContactTypedFieldControl::onClicked(Evas_Object *hoversel, void *eventInfo)
+{
+       elm_hoversel_clear(getEvasObject());
+
+       auto types = static_cast<ContactTypedArray *>(m_Object.getParent())->getTypes(m_Object);
+       for (auto &&value : types) {
+               addItem(getValueName(value), (void *) (long) value);
+       }
 }
 
 bool ContactTypedFieldControl::onSelected(void *data)
index 310f955..356b262 100644 (file)
@@ -25,13 +25,11 @@ using namespace Contacts::Input;
 using namespace Contacts::Model;
 
 ContactTypedFieldItem::ContactTypedFieldItem(Model::ContactObject &object)
-       : ContactFieldItem(object),
-         m_TypeField(getTypedObject().getTypeField()),
-         m_LabelField(getTypedObject().getLabelField())
+       : ContactFieldItem(object)
 {
 }
 
-const ContactTypedObject &ContactTypedFieldItem::getTypedObject() const
+ContactTypedObject &ContactTypedFieldItem::getTypedObject() const
 {
        return getObject().cast<ContactTypedObject>();
 }
@@ -39,7 +37,7 @@ const ContactTypedObject &ContactTypedFieldItem::getTypedObject() const
 Evas_Object *ContactTypedFieldItem::getContent(Evas_Object *parent, const char *part)
 {
        if (strcmp(part, PART_TYPE) == 0) {
-               Ui::Control *control = new ContactTypedFieldControl(m_TypeField, m_LabelField);
+               Ui::Control *control = new ContactTypedFieldControl(getTypedObject());
                return control->create(parent);
        } else {
                return ContactFieldItem::getContent(parent, part);
index d5bac75..52d9e96 100644 (file)
@@ -51,6 +51,7 @@ ContactField &ContactArray::addField()
 
        ContactField &field = addField(record);
        field.reset();
+       initializeField(field);
        return field;
 }
 
index 7e97913..d202429 100644 (file)
@@ -32,11 +32,6 @@ bool ContactEnumField::isChanged() const
        return m_InitialValue != getValue();
 }
 
-Utils::Range<const int *> ContactEnumField::getValues() const
-{
-       return getEnumMetadata().values;
-}
-
 int ContactEnumField::getCustomValue() const
 {
        return getEnumMetadata().customValue;
index c1f072c..1442f9c 100644 (file)
@@ -25,6 +25,7 @@
 #include "Contacts/Model/ContactDateField.h"
 #include "Contacts/Model/ContactEnumField.h"
 #include "Contacts/Model/ContactTextField.h"
+#include "Contacts/Model/ContactTypedArray.h"
 #include "Contacts/Model/ContactTypedObject.h"
 
 #include "Contacts/Model/ContactName.h"
@@ -56,21 +57,30 @@ ContactFieldPtr ContactFieldFactory::createField(ContactFieldContainer *parent,
                case TypeDate:
                        field = new ContactDateField(parent, metadata); break;
                case TypeArray:
-                       field = new ContactArray(parent, metadata); break;
+               {
+                       auto arrayMetadata = (const ContactArrayMetadata *) typeMetadata;
+                       auto objectMetadata = (const ContactObjectMetadata *) arrayMetadata->element.typeMetadata;
+
+                       if (objectMetadata->interfaces & InterfaceTypedObject) {
+                               field = new ContactTypedArray(parent, metadata);
+                       } else {
+                               field = new ContactArray(parent, metadata);
+                       }
+               }
+                       break;
                case TypeObject:
                {
                        auto objectMetadata = (const ContactObjectMetadata *) typeMetadata;
                        unsigned interfaces = objectMetadata->interfaces;
+
                        if (interfaces & InterfaceTypedObject) {
                                field = new ContactTypedObject(parent, metadata);
                        } else if (interfaces & InterfaceCompoundObject) {
                                switch (typeMetadata->subType) {
                                        case ObjectTypeName:
-                                               field = new ContactName(parent, metadata);
-                                               break;
+                                               field = new ContactName(parent, metadata); break;
                                        case ObjectTypePhoneticName:
-                                               field = new ContactPhoneticName(parent, metadata);
-                                               break;
+                                               field = new ContactPhoneticName(parent, metadata); break;
                                }
                        } else {
                                field = new ContactObject(parent, metadata);
index e5a72a3..bbd9dc1 100644 (file)
@@ -141,15 +141,15 @@ const ContactObjectMetadata contactGroups = {
 };
 
 /****************************** Number Object *********************************/
-const int contactNumberTypeValues[] = {
-       CONTACTS_NUMBER_TYPE_CELL,
-       CONTACTS_NUMBER_TYPE_VOICE | CONTACTS_NUMBER_TYPE_WORK,
-       CONTACTS_NUMBER_TYPE_VOICE | CONTACTS_NUMBER_TYPE_HOME,
-       CONTACTS_NUMBER_TYPE_FAX | CONTACTS_NUMBER_TYPE_WORK,
-       CONTACTS_NUMBER_TYPE_FAX | CONTACTS_NUMBER_TYPE_HOME,
-       CONTACTS_NUMBER_TYPE_PAGER,
-       CONTACTS_NUMBER_TYPE_OTHER,
-       CONTACTS_NUMBER_TYPE_CUSTOM
+const ContactEnumValue contactNumberTypeValues[] = {
+       { CONTACTS_NUMBER_TYPE_CELL, false },
+       { CONTACTS_NUMBER_TYPE_VOICE | CONTACTS_NUMBER_TYPE_WORK, false },
+       { CONTACTS_NUMBER_TYPE_VOICE | CONTACTS_NUMBER_TYPE_HOME, false },
+       { CONTACTS_NUMBER_TYPE_FAX | CONTACTS_NUMBER_TYPE_WORK, false },
+       { CONTACTS_NUMBER_TYPE_FAX | CONTACTS_NUMBER_TYPE_HOME, false },
+       { CONTACTS_NUMBER_TYPE_PAGER, false },
+       { CONTACTS_NUMBER_TYPE_OTHER, false },
+       { CONTACTS_NUMBER_TYPE_CUSTOM, false }
 };
 const ContactEnumMetadata contactNumberType = {
        { TypeEnum, EnumNumberType }, makeRange(contactNumberTypeValues),
@@ -166,11 +166,11 @@ const ContactTypedObjectMetadata contactNumber = {
 };
 
 /******************************* Email Object *********************************/
-const int contactEmailTypeValues[] = {
-       CONTACTS_EMAIL_TYPE_HOME,
-       CONTACTS_EMAIL_TYPE_WORK,
-       CONTACTS_EMAIL_TYPE_OTHER,
-       CONTACTS_EMAIL_TYPE_CUSTOM
+const ContactEnumValue contactEmailTypeValues[] = {
+       { CONTACTS_EMAIL_TYPE_HOME, false },
+       { CONTACTS_EMAIL_TYPE_WORK, false },
+       { CONTACTS_EMAIL_TYPE_OTHER, false },
+       { CONTACTS_EMAIL_TYPE_CUSTOM, false }
 };
 const ContactEnumMetadata contactEmailType = {
        { TypeEnum, EnumEmailType }, makeRange(contactEmailTypeValues),
@@ -187,11 +187,11 @@ const ContactTypedObjectMetadata contactEmail = {
 };
 
 /****************************** Address Object ********************************/
-const int contactAddrTypeValues[] = {
-       CONTACTS_ADDRESS_TYPE_HOME,
-       CONTACTS_ADDRESS_TYPE_WORK,
-       CONTACTS_ADDRESS_TYPE_OTHER,
-       CONTACTS_ADDRESS_TYPE_CUSTOM
+const ContactEnumValue contactAddrTypeValues[] = {
+       { CONTACTS_ADDRESS_TYPE_HOME, false },
+       { CONTACTS_ADDRESS_TYPE_WORK, false },
+       { CONTACTS_ADDRESS_TYPE_OTHER, false },
+       { CONTACTS_ADDRESS_TYPE_CUSTOM, false }
 };
 const ContactEnumMetadata contactAddrType = {
        { TypeEnum, EnumAddressType }, makeRange(contactAddrTypeValues),
@@ -208,11 +208,11 @@ const ContactTypedObjectMetadata contactAddr = {
 };
 
 /******************************* Event Object *********************************/
-const int contactEventTypeValues[] = {
-       CONTACTS_EVENT_TYPE_BIRTH,
-       CONTACTS_EVENT_TYPE_ANNIVERSARY,
-       CONTACTS_EVENT_TYPE_OTHER,
-       CONTACTS_EVENT_TYPE_CUSTOM
+const ContactEnumValue contactEventTypeValues[] = {
+       { CONTACTS_EVENT_TYPE_BIRTH, true },
+       { CONTACTS_EVENT_TYPE_ANNIVERSARY, false },
+       { CONTACTS_EVENT_TYPE_OTHER, false },
+       { CONTACTS_EVENT_TYPE_CUSTOM, false }
 };
 const ContactEnumMetadata contactEventType = {
        { TypeEnum, EnumEventType }, makeRange(contactEventTypeValues),
@@ -229,22 +229,22 @@ const ContactTypedObjectMetadata contactEvent = {
 };
 
 /**************************** Relationship Object *****************************/
-const int contactRelTypeValues[] = {
-       CONTACTS_RELATIONSHIP_TYPE_ASSISTANT,
-       CONTACTS_RELATIONSHIP_TYPE_BROTHER,
-       CONTACTS_RELATIONSHIP_TYPE_CHILD,
-       CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER,
-       CONTACTS_RELATIONSHIP_TYPE_FATHER,
-       CONTACTS_RELATIONSHIP_TYPE_FRIEND,
-       CONTACTS_RELATIONSHIP_TYPE_MANAGER,
-       CONTACTS_RELATIONSHIP_TYPE_MOTHER,
-       CONTACTS_RELATIONSHIP_TYPE_PARENT,
-       CONTACTS_RELATIONSHIP_TYPE_PARTNER,
-       CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY,
-       CONTACTS_RELATIONSHIP_TYPE_RELATIVE,
-       CONTACTS_RELATIONSHIP_TYPE_SISTER,
-       CONTACTS_RELATIONSHIP_TYPE_SPOUSE,
-       CONTACTS_RELATIONSHIP_TYPE_CUSTOM
+const ContactEnumValue contactRelTypeValues[] = {
+       { CONTACTS_RELATIONSHIP_TYPE_ASSISTANT, false },
+       { CONTACTS_RELATIONSHIP_TYPE_BROTHER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_CHILD, false },
+       { CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_FATHER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_FRIEND, false },
+       { CONTACTS_RELATIONSHIP_TYPE_MANAGER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_MOTHER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_PARENT, false },
+       { CONTACTS_RELATIONSHIP_TYPE_PARTNER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY, false },
+       { CONTACTS_RELATIONSHIP_TYPE_RELATIVE, false },
+       { CONTACTS_RELATIONSHIP_TYPE_SISTER, false },
+       { CONTACTS_RELATIONSHIP_TYPE_SPOUSE, false },
+       { CONTACTS_RELATIONSHIP_TYPE_CUSTOM, false }
 };
 const ContactEnumMetadata contactRelType = {
        { TypeEnum, EnumRelationshipType }, makeRange(contactRelTypeValues),
@@ -270,15 +270,15 @@ const ContactObjectMetadata contactUrl = {
 };
 
 /***************************** Messenger Object *******************************/
-const int contactMsgTypeValues[] = {
-       CONTACTS_MESSENGER_TYPE_AIM,
-       CONTACTS_MESSENGER_TYPE_YAHOO,
-       CONTACTS_MESSENGER_TYPE_SKYPE,
-       CONTACTS_MESSENGER_TYPE_QQ,
-       CONTACTS_MESSENGER_TYPE_GOOGLE,
-       CONTACTS_MESSENGER_TYPE_ICQ,
-       CONTACTS_MESSENGER_TYPE_JABBER,
-       CONTACTS_MESSENGER_TYPE_CUSTOM
+const ContactEnumValue contactMsgTypeValues[] = {
+       { CONTACTS_MESSENGER_TYPE_AIM, false },
+       { CONTACTS_MESSENGER_TYPE_YAHOO, false },
+       { CONTACTS_MESSENGER_TYPE_SKYPE, false },
+       { CONTACTS_MESSENGER_TYPE_QQ, false },
+       { CONTACTS_MESSENGER_TYPE_GOOGLE, false },
+       { CONTACTS_MESSENGER_TYPE_ICQ, false },
+       { CONTACTS_MESSENGER_TYPE_JABBER, false },
+       { CONTACTS_MESSENGER_TYPE_CUSTOM, false }
 };
 const ContactEnumMetadata contactMsgType = {
        { TypeEnum, EnumMessengerType }, makeRange(contactMsgTypeValues),
diff --git a/lib-contacts/src/Contacts/Model/ContactTypedArray.cpp b/lib-contacts/src/Contacts/Model/ContactTypedArray.cpp
new file mode 100644 (file)
index 0000000..34740df
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Contacts/Model/ContactTypedArray.h"
+#include "Contacts/Model/ContactTypedObject.h"
+#include "Common/Database/ChildRecordIterator.h"
+
+using namespace Common;
+using namespace Common::Database;
+using namespace Contacts::Model;
+
+std::vector<int> ContactTypedArray::getTypes(const ContactTypedObject &object) const
+{
+       auto enumValues = getEnumMetadata().values;
+
+       std::vector<int> types;
+       types.reserve(enumValues.count());
+
+       for (auto &&value : enumValues) {
+               if (!value.isExclusive || !isTypeUsed(object, value.value)) {
+                       types.push_back(value.value);
+               }
+       }
+
+       return types;
+}
+
+const ContactEnumMetadata &ContactTypedArray::getEnumMetadata() const
+{
+       auto objectMetadata = (ContactTypedObjectMetadata *) getArrayMetadata().element.typeMetadata;
+       auto enumMetadata = (ContactEnumMetadata *) objectMetadata->typeField.typeMetadata;
+       return *enumMetadata;
+}
+
+void ContactTypedArray::initializeField(ContactField &field)
+{
+       auto &enumMetadata = getEnumMetadata();
+
+       int nextValue = 0;
+       for (auto &&value : enumMetadata.values) {
+               if (value.value != enumMetadata.customValue) {
+                       nextValue = value.value;
+                       if (!isTypeUsed(field, nextValue)) {
+                               break;
+                       }
+               }
+       }
+
+       field.cast<ContactTypedObject>().getTypeField().setValue(nextValue);
+}
+
+bool ContactTypedArray::isTypeUsed(const ContactField &excludedfield, int type) const
+{
+       for (auto &&field : *this) {
+               auto &typeField = field.cast<ContactTypedObject>().getTypeField();
+               if (&field != &excludedfield && typeField.getValue() == type) {
+                       return true;
+               }
+       }
+       return false;
+}