#include "Contacts/Model/Contact.h"
#include "Ui/View.h"
+#include <memory>
+
namespace Ui
{
class Genlist;
void onObjectUpdated(FieldItem *item, Model::ContactField &field, contacts_changed_e change);
int m_RecordId;
- Model::Contact m_Contact;
+ std::unique_ptr<Model::Contact> m_Contact;
Ui::Genlist *m_Genlist;
BasicInfoItem *m_BasicInfoItem;
#include "Contacts/Model/Contact.h"
#include "Ui/View.h"
+#include <memory>
+
namespace Ui
{
class Genlist;
bool onCancel();
void onSave();
- Model::Contact m_Contact;
+ std::unique_ptr<Model::Contact> m_Contact;
ResultCallback m_OnResult;
Evas_Object *m_DoneButton;
--- /dev/null
+/*
+ * 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_INPUT_MY_PROFILE_NUMBER_ITEM_H
+#define CONTACTS_INPUT_MY_PROFILE_NUMBER_ITEM_H
+
+#include "Contacts/Input/ContactFieldItem.h"
+
+namespace Contacts
+{
+ namespace Input
+ {
+ /**
+ * @brief Genlist item representing SIM phone number for My Profile.
+ */
+ class MyProfileNumberItem : public ContactFieldItem
+ {
+ public:
+ /**
+ * @see ContactFieldItem::ContactFieldItem()
+ */
+ MyProfileNumberItem(Model::ContactObject &object);
+
+ /**
+ * @see GenItem::isFocusable()
+ */
+ virtual bool isFocusable() const override;
+
+ private:
+ virtual Elm_Genlist_Item_Class *getItemClass() const override;
+ virtual char *getText(Evas_Object *parent, const char *part) override;
+ };
+ }
+}
+
+#endif /* CONTACTS_INPUT_MY_PROFILE_NUMBER_ITEM_H */
*/
virtual const char *getImagePath() const override;
+ /**
+ * @return SIM phone number if available, otherwise nullptr.
+ */
+ static const char *fetchSimNumber();
+
private:
virtual int onUpdate(void *data) override;
- static const char *fetchNumber();
static contacts_record_h fetchRecord();
static void onChanged(const char *uri, void *data);
static void onNameFormatChanged(contacts_name_display_order_e order, void *data);
* @brief Create contact object.
* @param[in] type Contact object type (ObjectTypeContact or ObjectTypeMyProfile)
*/
- Contact(Common::ObjectType type);
+ Contact(Common::ObjectType type = Common::ObjectTypeContact);
Contact(const Contact &that) = delete;
virtual ~Contact() override;
bool isUnique() const;
/**
+ * @return ID of person to which contact belongs.
+ */
+ virtual int getPersonId() const;
+
+ /**
* @brief Save contact to the database.
* @return Contact ID on success, Contacts API error code otherwise.
*/
Contact &operator=(const Contact &that) = delete;
+ protected:
+ /**
+ * @return Object change type (Updated/Deleted).
+ */
+ virtual int getChangeType();
+
+ /**
+ * @return Database version since last update.
+ */
+ int &getDbVersion();
+
private:
void setChangeCallback();
void unsetChangeCallback();
-
- int getContactChange();
- int getMyProfileChange();
void onDatabaseChanged(const char *uri);
bool m_IsNew;
--- /dev/null
+/*
+ * 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_MY_PROFILE_H
+#define CONTACTS_MODEL_MY_PROFILE_H
+
+#include "Contacts/Model/Contact.h"
+
+#define SIM_NUMBER_LABEL "sim"
+
+namespace Contacts
+{
+ namespace Model
+ {
+ /**
+ * @brief MyProfile record wrapper. Provides database update and SIM number.
+ * @details SIM number is provided by inserting a fake number record
+ * with a special label. SIM number is never saved into database.
+ */
+ class MyProfile : public Contact
+ {
+ public:
+ MyProfile();
+ virtual ~MyProfile() override;
+
+ /**
+ * @return My Profile ID.
+ */
+ virtual int getPersonId() const override;
+
+ protected:
+ /**
+ * @see ContactField::onInitialize()
+ */
+ virtual void onInitialize(contacts_record_h record) override;
+
+ /**
+ * @see ContactField::onUpdate()
+ */
+ virtual void onUpdate(contacts_record_h record) override;
+
+ /**
+ * @see Contact::getChangeType()
+ */
+ virtual int getChangeType() override;
+
+ private:
+ void insertSimNumber(contacts_record_h record);
+ contacts_record_h m_SimNumberRecord;
+ };
+ }
+}
+
+#endif /* CONTACTS_MODEL_MY_PROFILE_H */
#include "Contacts/Input/InputView.h"
#include "Contacts/Model/ContactArray.h"
+#include "Contacts/Model/MyProfile.h"
#include "Common/Strings.h"
#include "App/Path.h"
}
DetailsView::DetailsView(int recordId, Type type)
- : m_RecordId(recordId), m_Contact(ObjectType(type)),
+ : m_RecordId(recordId),
m_Genlist(nullptr), m_BasicInfoItem(nullptr), m_Items{nullptr}
{
+ m_Contact.reset((type == TypeContact) ? new Contact() : new MyProfile());
}
Evas_Object *DetailsView::onCreate(Evas_Object *parent)
void DetailsView::onCreated()
{
- int err = m_Contact.initialize(m_RecordId);
+ int err = m_Contact->initialize(m_RecordId);
RETM_IF_ERR(err, "Contact::initialize() failed.");
- m_BasicInfoItem = new BasicInfoItem(m_Contact);
+ m_BasicInfoItem = new BasicInfoItem(*m_Contact);
m_Genlist->insert(m_BasicInfoItem);
- for (auto &&field : m_Contact) {
+ for (auto &&field : *m_Contact) {
ContactFieldId fieldId = ContactFieldId(field.getId());
if (!isFieldVisible[fieldId]) {
continue;
menu->create(getEvasObject());
menu->addItem("IDS_PB_OPT_EDIT", [this] {
- auto type = (Input::InputView::Type) m_Contact.getSubType();
+ auto type = (Input::InputView::Type) m_Contact->getSubType();
getNavigator()->navigateTo(new Input::InputView(m_RecordId, type));
});
menu->addItem("IDS_PB_BUTTON_DELETE_ABB4", [this] {
popup->setText("IDS_PB_POP_THIS_CONTACT_WILL_BE_DELETED");
popup->addButton("IDS_PB_BUTTON_CANCEL");
popup->addButton("IDS_PB_BUTTON_DELETE_ABB4", [this] {
- m_Contact.remove();
+ m_Contact->remove();
getPage()->close();
return true;
});
popup->show();
});
menu->addItem("IDS_PB_OPT_SHARE", [this] {
- SharePopup *popup = nullptr;
- if (m_Contact.getSubType() == ObjectTypeContact) {
- int personId = 0;
- contacts_record_get_int(m_Contact.getRecord(), _contacts_contact.person_id, &personId);
- popup = new SharePopup(personId, false);
- } else {
- popup = new SharePopup(m_Contact.getRecordId(), true);
- }
+ SharePopup *popup = new SharePopup(m_Contact->getPersonId(), m_Contact->getSubType() == ObjectTypeMyProfile);
popup->create(getEvasObject());
popup->show();
});
#include "Contacts/Input/InputView.h"
#include "Contacts/Input/AddFieldsItem.h"
#include "Contacts/Input/BasicInfoItem.h"
+#include "Contacts/Input/MyProfileNumberItem.h"
#include "Contacts/Input/ContactCompoundFieldItem.h"
#include "Contacts/Input/ContactGroupsFieldItem.h"
#include "Contacts/Input/ContactNoteFieldItem.h"
#include "Contacts/Model/ContactDateField.h"
#include "Contacts/Model/ContactTextField.h"
#include "Contacts/Model/ContactCompoundObject.h"
+#include "Contacts/Model/ContactTypedObject.h"
+#include "Contacts/Model/MyProfile.h"
#include "App/AppControlRequest.h"
#include "App/Path.h"
}
InputView::InputView(int recordId, Type type)
- : m_Contact(ObjectType(type)),
- m_DoneButton(nullptr), m_Genlist(nullptr),
+ : m_DoneButton(nullptr), m_Genlist(nullptr),
m_Items{nullptr}, m_BasicInfoItem(nullptr), m_AddFieldsItem(nullptr)
{
- m_Contact.initialize(recordId);
- m_Contact.setFillCallback(std::bind(&InputView::onContactFilled, this, _1));
+ m_Contact.reset((type == TypeContact) ? new Contact() : new MyProfile());
+ m_Contact->initialize(recordId);
+ m_Contact->setFillCallback(std::bind(&InputView::onContactFilled, this, _1));
}
void InputView::addField(Model::ContactFieldId fieldId, const char *value)
m_Genlist->create(parent);
elm_genlist_homogeneous_set(m_Genlist->getEvasObject(), EINA_FALSE);
- m_BasicInfoItem = new BasicInfoItem(m_Contact);
+ m_BasicInfoItem = new BasicInfoItem(*m_Contact);
m_Genlist->insert(m_BasicInfoItem);
m_AddFieldsItem = new AddFieldsItem();
elm_genlist_item_select_mode_set(m_AddFieldsItem->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
for (unsigned id = FieldBegin; id < FieldEnd; ++id) {
- if (!isFieldVisible[id] || !m_Contact.getFieldById(id)) {
+ if (!isFieldVisible[id] || !m_Contact->getFieldById(id)) {
m_AddFieldsItem->setAddFieldState(ContactFieldId(id), false);
}
}
{
ContactFieldItem *nameItem = addFieldItem(addField(FieldName));
- for (auto &&field : m_Contact) {
+ for (auto &&field : *m_Contact) {
ContactFieldId fieldId = ContactFieldId(field.getId());
if (!isFieldVisible[fieldId]) {
continue;
}
}
- if (m_Contact.isNew()) {
- if (m_Contact.getFieldById(FieldNumber)->isEmpty()) {
+ if (m_Contact->isNew()) {
+ if (m_Contact->getFieldById(FieldNumber)->isEmpty()) {
addFieldItem(addField(FieldNumber));
}
nameItem->focus();
m_DoneButton = page->addTitleButton(Ui::ButtonRight, "IDS_TPLATFORM_ACBUTTON_DONE_ABB",
makeCallback(&InputView::onDonePressed), this);
- elm_object_disabled_set(m_DoneButton, !m_Contact.isFilled());
+ elm_object_disabled_set(m_DoneButton, !m_Contact->isFilled());
- page->setTitle(m_Contact.isNew() ? "IDS_PB_HEADER_CREATE" : "IDS_PB_HEADER_EDIT");
+ page->setTitle(m_Contact->isNew() ? "IDS_PB_HEADER_CREATE" : "IDS_PB_HEADER_EDIT");
}
bool InputView::onBackPressed()
} else if (field.getId() == FieldGroups) {
item = new ContactGroupsFieldItem(field);
} else if (field.getInterfaces() & InterfaceTypedObject) {
- item = new ContactTypedFieldItem(field);
+ auto &typedObject = field.cast<ContactTypedObject>();
+ if (field.getId() == FieldNumber
+ && typedObject.getTypeField().getValue() != CONTACTS_NUMBER_TYPE_CUSTOM
+ && Utils::safeCmp(typedObject.getLabelField().getValue(), SIM_NUMBER_LABEL)) {
+ item = new MyProfileNumberItem(field);
+ } else {
+ item = new ContactTypedFieldItem(field);
+ }
} else if (field.getInterfaces() & InterfaceCompoundObject) {
item = new ContactCompoundFieldItem(field);
} else {
ContactObject &InputView::addField(ContactFieldId fieldId)
{
- ContactField &parentField = *m_Contact.getFieldById(fieldId);
+ ContactField &parentField = *m_Contact->getFieldById(fieldId);
if (parentField.getType() == TypeArray) {
return parentField.cast<ContactArray>().addField().cast<ContactObject>();
} else {
void InputView::removeField(ContactObject &field)
{
ContactFieldId fieldId = ContactFieldId(field.getId());
- ContactField &parentField = *m_Contact.getFieldById(fieldId);
+ ContactField &parentField = *m_Contact->getFieldById(fieldId);
if (parentField.getType() == TypeArray) {
parentField.cast<ContactArray>().removeField(field);
} else {
void InputView::onDonePressed(Evas_Object *button, void *eventInfo)
{
- if (m_Contact.isNew() && !m_Contact.isUnique()) {
+ if (m_Contact->isNew() && !m_Contact->isUnique()) {
Ui::Popup *popup = new Ui::Popup();
popup->create(getEvasObject());
popup->setTitle("IDS_PB_HEADER_NAME_ALREADY_IN_USE_ABB3");
bool InputView::onCancel()
{
- if (!m_Contact.isChanged()) {
+ if (!m_Contact->isChanged()) {
return true;
}
void InputView::onSave()
{
- int id = m_Contact.save();
+ int id = m_Contact->save();
if (m_OnResult) {
m_OnResult(id);
}
- if (m_Contact.isNew()) {
+ if (m_Contact->isNew()) {
using Details::DetailsView;
- DetailsView *view = new DetailsView(id, DetailsView::Type(m_Contact.getSubType()));
+ DetailsView *view = new DetailsView(id, DetailsView::Type(m_Contact->getSubType()));
getNavigator()->navigateTo(view);
}
--- /dev/null
+/*
+ * 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/Input/MyProfileNumberItem.h"
+#include "Contacts/Model/ContactObject.h"
+#include "Contacts/Model/ContactTextField.h"
+
+#include <app_i18n.h>
+
+using namespace Common;
+using namespace Contacts::Input;
+using namespace Contacts::Model;
+
+MyProfileNumberItem::MyProfileNumberItem(ContactObject &object)
+ : ContactFieldItem(object)
+{
+}
+
+bool MyProfileNumberItem::isFocusable() const
+{
+ return false;
+}
+
+Elm_Genlist_Item_Class *MyProfileNumberItem::getItemClass() const
+{
+ static Elm_Genlist_Item_Class itc = createItemClass("type2");
+ return &itc;
+}
+
+char *MyProfileNumberItem::getText(Evas_Object *parent, const char *part)
+{
+ if (strcmp(part, "elm.text") == 0) {
+ return Utils::safeDup(getField().cast<ContactTextField>().getValue());
+ } else if (strcmp(part, "elm.text.sub") == 0) {
+ return strdup(_("IDS_PB_OPT_MOBILE"));
+ }
+
+ return nullptr;
+}
}
}
- return fetchNumber();
+ return fetchSimNumber();
}
const char *MyProfile::getImagePath() const
return changes;
}
-const char *MyProfile::fetchNumber()
+const char *MyProfile::fetchSimNumber()
{
static bool isInitialized = false;
static std::string number;
if (id > 0) {
navigator->navigateTo(new DetailsView(id, DetailsView::TypeMyProfile));
} else {
- InputView *view = new InputView(id, InputView::TypeMyProfile);
- view->addField(Contacts::Model::FieldNumber, m_MyProfile.getNumber());
- navigator->navigateTo(view);
+ navigator->navigateTo(new InputView(id, InputView::TypeMyProfile));
}
}
#include "Contacts/Model/Contact.h"
#include "Contacts/Model/ContactFieldMetadata.h"
#include "Contacts/Model/ContactCompoundObject.h"
+#include "Common/Database/RecordIterator.h"
#include "Common/Database/RecordUtils.h"
#include "Utils/Callback.h"
#include "Utils/Logger.h"
using namespace Common;
+using namespace Common::Database;
using namespace Contacts::Model;
Contact::Contact(ObjectType type)
return count == 0;
}
+int Contact::getPersonId() const
+{
+ return getRecordInt(getRecord(), _contacts_contact.person_id);
+}
+
int Contact::save()
{
int id = 0;
makeCallbackWithLastParam(&Contact::onDatabaseChanged), this);
}
-int Contact::getContactChange()
+int Contact::getChangeType()
{
int changeType = -1;
contacts_db_get_changes_by_version(_contacts_contact_updated_info._uri, 0,
m_DbVersion, &list, &m_DbVersion);
- contacts_record_h record = nullptr;
- CONTACTS_LIST_FOREACH(list, record) {
- int id = 0;
- contacts_record_get_int(record, _contacts_contact_updated_info.contact_id, &id);
-
+ for (auto &&record : makeRange(list)) {
+ int id = getRecordInt(record, _contacts_contact_updated_info.contact_id);
if (id == getRecordId()) {
contacts_record_get_int(record, _contacts_contact_updated_info.type, &changeType);
break;
return changeType;
}
-int Contact::getMyProfileChange()
+int &Contact::getDbVersion()
{
- contacts_list_h list = nullptr;
- contacts_db_get_changes_by_version(_contacts_my_profile_updated_info._uri, 0,
- m_DbVersion, &list, &m_DbVersion);
-
- contacts_record_h record = nullptr;
- contacts_list_get_current_record_p(list, &record);
-
- int changeType = -1;
- contacts_record_get_int(record, _contacts_my_profile_updated_info.last_changed_type, &changeType);
- contacts_list_destroy(list, true);
-
- return changeType;
+ return m_DbVersion;
}
void Contact::onDatabaseChanged(const char *uri)
{
- int changeType = (getSubType() == ObjectTypeContact)
- ? getContactChange() : getMyProfileChange();
-
+ int changeType = getChangeType();
if (changeType == CONTACTS_CHANGE_UPDATED) {
contacts_record_h oldRecord = getRecord();
contacts_record_h newRecord = nullptr;
--- /dev/null
+/*
+ * 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/MyProfile.h"
+#include "Contacts/List/Model/MyProfile.h"
+#include "Common/Database/RecordUtils.h"
+
+using namespace Common;
+using namespace Common::Database;
+using namespace Contacts;
+using namespace Contacts::Model;
+
+MyProfile::MyProfile()
+ : Contact(ObjectTypeMyProfile), m_SimNumberRecord(nullptr)
+{
+ const char *number = List::Model::MyProfile::fetchSimNumber();
+ if (number) {
+ contacts_record_create(_contacts_number._uri, &m_SimNumberRecord);
+ contacts_record_set_str(m_SimNumberRecord, _contacts_number.number, number);
+ contacts_record_set_int(m_SimNumberRecord, _contacts_number.type, CONTACTS_NUMBER_TYPE_CELL);
+ contacts_record_set_str(m_SimNumberRecord, _contacts_number.label, SIM_NUMBER_LABEL);
+ }
+}
+
+MyProfile::~MyProfile()
+{
+ contacts_record_destroy(m_SimNumberRecord, true);
+}
+
+int MyProfile::getPersonId() const
+{
+ return getRecordId();
+}
+
+void MyProfile::onInitialize(contacts_record_h record)
+{
+ insertSimNumber(record);
+ Contact::onInitialize(record);
+ contacts_record_remove_child_record(record, _contacts_my_profile.number, m_SimNumberRecord);
+}
+
+void MyProfile::onUpdate(contacts_record_h record)
+{
+ insertSimNumber(record);
+ Contact::onUpdate(record);
+ contacts_record_remove_child_record(record, _contacts_my_profile.number, m_SimNumberRecord);
+}
+
+int MyProfile::getChangeType()
+{
+ contacts_list_h list = nullptr;
+ contacts_db_get_changes_by_version(_contacts_my_profile_updated_info._uri, 0,
+ getDbVersion(), &list, &getDbVersion());
+
+ contacts_record_h record = nullptr;
+ contacts_list_get_current_record_p(list, &record);
+
+ int changeType = getRecordInt(record, _contacts_my_profile_updated_info.last_changed_type);
+ contacts_list_destroy(list, true);
+
+ return changeType;
+}
+
+void MyProfile::insertSimNumber(contacts_record_h record)
+{
+ if (m_SimNumberRecord) {
+ int count = 0;
+ contacts_record_get_child_record_count(record, _contacts_my_profile.number, &count);
+
+ std::vector<contacts_record_h> numbers;
+ numbers.reserve(count + 1);
+ numbers.push_back(m_SimNumberRecord);
+
+ while (count--) {
+ contacts_record_h number = nullptr;
+ contacts_record_get_child_record_at_p(record, _contacts_my_profile.number, 0, &number);
+ contacts_record_remove_child_record(record, _contacts_my_profile.number, number);
+ numbers.push_back(number);
+ }
+
+ for (auto &&numberRecord : numbers) {
+ contacts_record_add_child_record(record, _contacts_my_profile.number, numberRecord);
+ }
+ }
+}