TizenRefApp-5177 Implement update of the existing contact on event from database 98/54898/3
authorSergei Kobec <s.kobec@samsung.com>
Fri, 18 Dec 2015 13:11:58 +0000 (15:11 +0200)
committerSergei Kobec <s.kobec@samsung.com>
Fri, 18 Dec 2015 13:11:58 +0000 (15:11 +0200)
Change-Id: I07c70bdea7ea2962346b774981e3dec738603d35
Signed-off-by: Sergei Kobec <s.kobec@samsung.com>
lib-contact/inc/Contacts/List/ContactGroupItem.h
lib-contact/inc/Contacts/List/ContactItem.h
lib-contact/inc/Contacts/List/ListView.h
lib-contact/inc/Contacts/List/Model/Contact.h
lib-contact/inc/Contacts/List/Model/ContactProvider.h
lib-contact/src/Contacts/List/ContactGroupItem.cpp
lib-contact/src/Contacts/List/ContactItem.cpp
lib-contact/src/Contacts/List/ListView.cpp
lib-contact/src/Contacts/List/Model/Contact.cpp
lib-contact/src/Contacts/List/Model/ContactProvider.cpp

index 2bad299..844fb9f 100644 (file)
  * limitations under the License.
  *
  */
+
 #ifndef CONTACTS_LIST_CONTACT_GROUP_ITEM_H
 #define CONTACTS_LIST_CONTACT_GROUP_ITEM_H
 
 #include "Ui/GenlistGroupItem.h"
 #include <string>
 
+namespace Utils
+{
+       class UniString;
+}
+
 namespace Contacts
 {
        namespace List
@@ -40,7 +46,7 @@ namespace Contacts
                        /**
                         * @return Group item title
                         */
-                       const char *getTitle() const;
+                       const Utils::UniString &getTitle() const;
 
                        /**
                         * @return Linked index item
@@ -51,6 +57,8 @@ namespace Contacts
                        virtual char *getText(Evas_Object *parent, const char *part);
 
                        std::string m_Title;
+                       mutable Utils::UniString *m_UniTitle;
+
                        Elm_Object_Item *m_IndexItem;
                };
        }
index 35f8d41..3419128 100644 (file)
@@ -47,6 +47,12 @@ namespace Contacts
                         */
                        const Model::Contact &getContact() const;
 
+                       /**
+                        * @brief Set contact object
+                        * @param[in]   contact     Contact object
+                        */
+                       void setContact(Model::ContactPtr contact);
+
                private:
                        virtual char *getText(Evas_Object *parent, const char *part) override;
                        virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
index 9e3ec19..d6efef6 100644 (file)
@@ -18,8 +18,9 @@
 #ifndef CONTACTS_LIST_LIST_VIEW_H
 #define CONTACTS_LIST_LIST_VIEW_H
 
-#include "Ui/View.h"
 #include "Contacts/List/Model/ContactProvider.h"
+#include "Ui/View.h"
+#include "Utils/UniString.h"
 #include <map>
 
 namespace Ui
@@ -52,13 +53,18 @@ namespace Contacts
 
                        void fillList();
 
+                       Elm_Index_Item *insertIndexItem(const char *indexLetter,
+                                       Elm_Index_Item *nextItem = nullptr);
+
                        ContactGroupItem *insertGroupItem(const char *indexLetter,
                                        ContactGroupItem *nextGroup = nullptr);
-                       ContactGroupItem *getNextGroupItem(const char *indexLetter);
+                       void deleteGroupItem(ContactGroupItem *group);
+                       ContactGroupItem *getNextGroupItem(const Utils::UniString &indexLetter);
 
-                       ContactItem *insertItem(Model::ContactPtr contact, ContactGroupItem *group,
-                                       ContactItem *nextItem = nullptr);
-                       ContactItem *getNextItem(ContactGroupItem *group, const Model::Contact &contact);
+                       ContactItem *createContactItem(Model::ContactPtr contact);
+                       void insertContactItem(ContactItem *item);
+                       void updateContactItem(ContactItem *item, Model::ContactPtr contact);
+                       ContactItem *getNextContactItem(ContactGroupItem *group, const Model::Contact &contact);
 
                        void onItemSelected(Evas_Object *genlist, Elm_Object_Item *genlistItem);
                        void onIndexChanged(Evas_Object *index, Elm_Object_Item *indexItem);
@@ -68,10 +74,11 @@ namespace Contacts
                        virtual void onMenuPressed() override;
 
                        void onContactInserted(Model::ContactPtr contact);
+                       void onContactChanged(Model::ContactPtr contact, contacts_changed_e changeType, ContactItem *item);
 
                        Ui::Genlist *m_Genlist;
                        Evas_Object *m_Index;
-                       std::map<std::string, ContactGroupItem *> m_Groups;
+                       std::map<Utils::UniString, ContactGroupItem *> m_Groups;
 
                        Model::ContactProvider m_Provider;
                };
index cfd2ec4..96ac1ef 100644 (file)
 #include <contacts.h>
 #include <memory>
 #include <vector>
-#include <utils_i18n.h>
+
+namespace Utils
+{
+       class UniString;
+}
 
 namespace Contacts
 {
@@ -57,6 +61,18 @@ namespace Contacts
                                bool operator<(const Contact &that) const;
 
                                /**
+                                * @brief Compares contact's "Sort by" (first name/last name) values on equality
+                                * @return True if sort values are equivalent, otherwise false
+                                */
+                               bool operator==(const Contact &that) const;
+
+                               /**
+                                * @brief Compares contact's "Sort by" (first name/last name) values on inequality
+                                * @return True if sort values are not equivalent, otherwise false
+                                */
+                               bool operator!=(const Contact &that) const;
+
+                               /**
                                 * @return Person ID
                                 */
                                int getPersonId() const;
@@ -82,14 +98,14 @@ namespace Contacts
                                const contacts_record_h getRecord() const;
 
                        private:
-                               const i18n_uchar *getSortValue() const;
+                               const Utils::UniString &getSortValue() const;
                                void initSortValue(const char *sortValue) const;
                                const char *getDbSortValue() const;
 
                                contacts_record_h m_PersonRecord;
                                contacts_record_h m_ContactRecord;
 
-                               mutable i18n_uchar *m_SortValue;
+                               mutable Utils::UniString *m_SortValue;
                        };
                }
        }
index 15ec659..94b74cf 100644 (file)
@@ -48,10 +48,10 @@ namespace Contacts
 
                                /**
                                 * @brief Person change callback
-                                * @param[in]    id            Person ID
+                                * @param[in]    contact       Contact object
                                 * @param[in]    changeType    Change type
                                 */
-                               typedef std::function<void(int id, contacts_changed_e changeType)> ChangeCallback;
+                               typedef std::function<void(ContactPtr contact, contacts_changed_e changeType)> ChangeCallback;
 
                                /**
                                 * @brief Person insert callback
index 6fce723..51686c9 100644 (file)
  */
 
 #include "Contacts/List/ContactGroupItem.h"
+#include "Utils/UniString.h"
 
 using namespace Contacts::List;
+using namespace Utils;
 
 ContactGroupItem::ContactGroupItem(const char *title, Elm_Object_Item *indexItem)
-       : m_IndexItem(indexItem)
+       : m_UniTitle(nullptr), m_IndexItem(indexItem)
 {
        if (title) {
                m_Title = title;
        }
 }
 
-const char *Contacts::List::ContactGroupItem::getTitle() const
+const UniString &ContactGroupItem::getTitle() const
 {
-       return m_Title.c_str();
+       if (!m_UniTitle) {
+               m_UniTitle = new UniString(m_Title.c_str());
+       }
+
+       return *m_UniTitle;
 }
 
 Elm_Object_Item *ContactGroupItem::getIndexItem() const
index 26758a0..2cde922 100644 (file)
@@ -32,6 +32,11 @@ const Contact &ContactItem::getContact() const
        return *m_Contact;
 }
 
+void ContactItem::setContact(Model::ContactPtr contact)
+{
+       m_Contact = std::move(contact);
+}
+
 char *ContactItem::getText(Evas_Object *parent, const char *part)
 {
        if (strcmp(part, PART_CONTACT_NAME) == 0) {
index cf4f7ff..00f5dec 100644 (file)
@@ -31,6 +31,7 @@
 using namespace Contacts;
 using namespace Contacts::List;
 using namespace Contacts::List::Model;
+using namespace Utils;
 
 ListView::ListView()
        : m_Genlist(nullptr), m_Index(nullptr),
@@ -89,7 +90,6 @@ void ListView::onCreated()
 void ListView::fillList()
 {
        ContactList list = m_Provider.getContactList();
-
        const char *currentLetter = nullptr;
        ContactGroupItem *group = nullptr;
 
@@ -101,20 +101,27 @@ void ListView::fillList()
                        currentLetter = nextLetter;
                }
 
-               insertItem(std::move(contact), group);
+               m_Genlist->insert(createContactItem(std::move(contact)), group);
        }
 }
 
-ContactGroupItem *ListView::insertGroupItem(const char *indexLetter, ContactGroupItem *nextGroup)
+Elm_Object_Item *ListView::insertIndexItem(const char *indexLetter, Elm_Object_Item *nextItem)
 {
        Elm_Object_Item *indexItem = nullptr;
 
-       if (nextGroup) {
-               indexItem = elm_index_item_insert_before(m_Index, nextGroup->getIndexItem(), indexLetter, nullptr, nullptr);
+       if (nextItem) {
+               indexItem = elm_index_item_insert_before(m_Index, nextItem, indexLetter, nullptr, nullptr);
        } else {
                indexItem = elm_index_item_append(m_Index, indexLetter, nullptr, nullptr);
        }
-       elm_index_level_go(indexItem, 0);
+       elm_index_level_go(m_Index, 0);
+
+       return indexItem;
+}
+
+ContactGroupItem *ListView::insertGroupItem(const char *indexLetter, ContactGroupItem *nextGroup)
+{
+       Elm_Object_Item *indexItem = insertIndexItem(indexLetter, nextGroup ? nextGroup->getIndexItem() : nullptr);
 
        ContactGroupItem *item = new ContactGroupItem(indexLetter, indexItem);
        m_Genlist->insert(item, nullptr, nextGroup);
@@ -125,7 +132,13 @@ ContactGroupItem *ListView::insertGroupItem(const char *indexLetter, ContactGrou
        return item;
 }
 
-ContactGroupItem *ListView::getNextGroupItem(const char *indexLetter)
+void ListView::deleteGroupItem(ContactGroupItem *group)
+{
+       m_Groups.erase(group->getTitle());
+       delete group;
+}
+
+ContactGroupItem *ListView::getNextGroupItem(const Utils::UniString &indexLetter)
 {
        auto it = m_Groups.lower_bound(indexLetter);
        if (it != m_Groups.end()) {
@@ -135,19 +148,61 @@ ContactGroupItem *ListView::getNextGroupItem(const char *indexLetter)
        return nullptr;
 }
 
-ContactItem *ListView::insertItem(Model::ContactPtr contact, ContactGroupItem *group, ContactItem *nextItem)
+ContactItem *ListView::createContactItem(ContactPtr contact)
 {
+       using namespace std::placeholders;
+
        ContactItem *item = new ContactItem(std::move(contact));
-       m_Genlist->insert(item, group, nextItem);
+       m_Provider.setChangeCallback(item->getContact().getPersonId(),
+                       std::bind(&ListView::onContactChanged, this, _1, _2, item));
 
        return item;
 }
 
-ContactItem *ListView::getNextItem(ContactGroupItem *group, const Contact &contact)
+void ListView::insertContactItem(ContactItem *item)
+{
+       ContactGroupItem *group = nullptr;
+       ContactItem *nextItem = nullptr;
+       const char *indexLetter = item->getContact().getIndexLetter();
+
+       auto it = m_Groups.find(indexLetter);
+       if (it != m_Groups.end()) {
+               group = it->second;
+               nextItem = getNextContactItem(it->second, item->getContact());
+       } else {
+               group = insertGroupItem(indexLetter, getNextGroupItem(indexLetter));
+       }
+
+       m_Genlist->insert(item, group, nextItem);
+}
+
+void ListView::updateContactItem(ContactItem *item, Model::ContactPtr contact)
+{
+       if (item->getContact() != *contact) {
+               ContactGroupItem *oldGroup = static_cast<ContactGroupItem *>(item->getParentItem());
+
+               item->pop();
+
+               item->setContact(std::move(contact));
+               insertContactItem(item);
+
+               if (oldGroup->empty()) {
+                       deleteGroupItem(oldGroup);
+               }
+       } else {
+               item->setContact(std::move(contact));
+               if (strcmp(item->getContact().getImagePath(), contact->getImagePath()) != 0) {
+                       elm_genlist_item_fields_update(item->getObjectItem(),
+                                       PART_CONTACT_THUMBNAIL, ELM_GENLIST_ITEM_FIELD_CONTENT);
+               }
+       }
+}
+
+ContactItem *ListView::getNextContactItem(ContactGroupItem *group, const Contact &contact)
 {
        for (auto &&item : *group) {
                ContactItem *contactItem = static_cast<ContactItem *>(item);
-               if (!(contactItem->getContact() < contact)) {
+               if (contact < contactItem->getContact()) {
                        return contactItem;
                }
        }
@@ -195,14 +250,14 @@ void ListView::onMenuPressed()
 
 void ListView::onContactInserted(ContactPtr contact)
 {
-       const char *indexLetter = contact->getIndexLetter();
-       auto it = m_Groups.find(indexLetter);
+       insertContactItem(createContactItem(std::move(contact)));
+}
 
-       if (it != m_Groups.end()) {
-               ContactItem *nextItem = getNextItem(it->second, *contact);
-               insertItem(std::move(contact), it->second, nextItem);
-       } else {
-               ContactGroupItem *group = insertGroupItem(indexLetter, getNextGroupItem(indexLetter));
-               insertItem(std::move(contact), group);
+void ListView::onContactChanged(ContactPtr contact, contacts_changed_e changeType, ContactItem *item)
+{
+       if (changeType == CONTACTS_CHANGE_DELETED) {
+//             Todo: Implement delete contact functionality
+       } else if (changeType == CONTACTS_CHANGE_UPDATED) {
+               updateContactItem(item, std::move(contact));
        }
 }
index dd79886..c1c6de5 100644 (file)
  */
 
 #include "Contacts/List/Model/Contact.h"
+#include "Utils/UniString.h"
 
 using namespace Contacts::List::Model;
+using namespace Utils;
 
 namespace
 {
@@ -43,12 +45,22 @@ Contact::~Contact()
        contacts_record_destroy(m_PersonRecord, true);
        contacts_record_destroy(m_ContactRecord, true);
 
-       delete[] m_SortValue;
+       delete m_SortValue;
 }
 
 bool Contact::operator<(const Contact &that) const
 {
-       return i18n_ustring_compare_code_point_order(getSortValue(), that.getSortValue()) < 0;
+       return getSortValue() < that.getSortValue();
+}
+
+bool Contact::operator==(const Contact &that) const
+{
+       return getSortValue() == that.getSortValue();
+}
+
+bool Contact::operator!=(const Contact &that) const
+{
+       return getSortValue() != that.getSortValue();
 }
 
 int Contact::getPersonId() const
@@ -84,25 +96,13 @@ const contacts_record_h Contact::getRecord() const
        return m_PersonRecord;
 }
 
-const i18n_uchar *Contact::getSortValue() const
+const UniString &Contact::getSortValue() const
 {
        if (!m_SortValue) {
-               initSortValue(getDbSortValue());
+               m_SortValue = new UniString(getDbSortValue());
        }
 
-       return m_SortValue;
-}
-
-void Contact::initSortValue(const char *sortValue) const
-{
-       i18n_uchar fakeValue;
-       int length = 0;
-       i18n_error_code_e err = I18N_ERROR_NONE;
-       i18n_ustring_from_UTF8(&fakeValue, 1, &length, sortValue, -1, &err);
-
-       m_SortValue = new i18n_uchar[length + 1];
-
-       i18n_ustring_from_UTF8(m_SortValue, length + 1, &length, sortValue, -1, &err);
+       return *m_SortValue;
 }
 
 const char *Contact::getDbSortValue() const
index 96aa5bf..27bddef 100644 (file)
 #include "Contacts/List/Model/ContactProvider.h"
 #include "Contacts/Utils.h"
 #include "Utils/Callback.h"
+#include "Utils/Range.h"
 
 using namespace Contacts::List::Model;
 
 namespace
 {
+       unsigned projection[] = {
+               _contacts_person.id,
+               _contacts_person.display_name,
+               _contacts_person.display_name_index,
+               _contacts_person.display_contact_id,
+               _contacts_person.image_thumbnail_path,
+               _contacts_person.is_favorite,
+               _contacts_person.favorite_priority
+       };
+
        contacts_filter_h getProviderFilter(ContactProvider::FilterType filterType)
        {
                bool emptyFilter = true;
@@ -48,28 +59,18 @@ namespace
 
        contacts_list_h getContactList(ContactProvider::FilterType filterType)
        {
-               contacts_list_h list = nullptr;
-               contacts_query_h query = nullptr;
-               unsigned projection[] = {
-                       _contacts_person.id,
-                       _contacts_person.display_name,
-                       _contacts_person.display_name_index,
-                       _contacts_person.display_contact_id,
-                       _contacts_person.image_thumbnail_path,
-                       _contacts_person.is_favorite,
-                       _contacts_person.favorite_priority
-               };
+               contacts_filter_h filter = getProviderFilter(filterType);
 
+               contacts_query_h query = nullptr;
                contacts_query_create(_contacts_person._uri, &query);
-
-               contacts_filter_h filter = getProviderFilter(filterType);
                contacts_query_set_filter(query, filter);
+               contacts_query_set_projection(query, projection, Utils::count(projection));
 
-               contacts_query_set_projection(query, projection, sizeof(projection) / sizeof(*projection));
+               contacts_list_h list = nullptr;
                contacts_db_get_records_with_query(query, 0, 0, &list);
 
-               contacts_filter_destroy(filter);
                contacts_query_destroy(query);
+               contacts_filter_destroy(filter);
 
                return list;
        }
@@ -83,6 +84,7 @@ namespace
                contacts_query_h query = nullptr;
                contacts_query_create(_contacts_person._uri, &query);
                contacts_query_set_filter(query, filter);
+               contacts_query_set_projection(query, projection, Utils::count(projection));
 
                contacts_list_h list = nullptr;
                contacts_db_get_records_with_query(query, 0, 1, &list);
@@ -172,7 +174,7 @@ void ContactProvider::notify(contacts_changed_e changeType, ContactPtr contact)
                case CONTACTS_CHANGE_DELETED:
                        auto it = m_ChangeCallbacks.find(contact->getPersonId());
                        if (it != m_ChangeCallbacks.end()) {
-                               it->second(it->first, changeType);
+                               it->second(std::move(contact), changeType);
                        }
                        break;
        }