TizenRefApp-7036 Group's name isn't updated after editing 46/86646/3
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Fri, 2 Sep 2016 06:34:41 +0000 (09:34 +0300)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Mon, 5 Sep 2016 13:26:34 +0000 (06:26 -0700)
TizenRefApp-7038 Incorrect number of group members

[Implementation] Implemented ability for Group to update itself without provider.
Refactored MembersListView title update logic.

Change-Id: I28e26cc6424827914a85614f17a582c73fe2a652
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
lib-apps-common/inc/Model2/DataItem.h
lib-apps-common/src/Model2/DataItem.cpp
lib-contacts/inc/Contacts/Groups/MembersListView.h
lib-contacts/inc/Contacts/Groups/Model/Group.h
lib-contacts/inc/Contacts/Groups/Model/MembersProvider.h
lib-contacts/inc/Contacts/List/ListView.h
lib-contacts/src/Contacts/Groups/GroupItem.cpp
lib-contacts/src/Contacts/Groups/MembersListView.cpp
lib-contacts/src/Contacts/Groups/Model/Group.cpp
lib-contacts/src/Contacts/Groups/Model/MembersProvider.cpp
lib-contacts/src/Contacts/List/ListView.cpp

index 47c965a..dd92e70 100644 (file)
@@ -60,6 +60,17 @@ namespace Model2
                void update(void *data);
 
                /**
+                * @return Whether is standalone (not managed by DataProvider).
+                */
+               bool isStandalone() const;
+
+               /**
+                * @brief Set whether item is standalone or managed by DataProvider.
+                * @param[in]   isStandalone    Whether item is standalone
+                */
+               void setStandalone(bool isStandalone);
+
+               /**
                 * @brief Set update callback.
                 * @param[in]   callback    Update callback
                 */
@@ -73,10 +84,17 @@ namespace Model2
 
        protected:
                /**
-                * @brief Mark item as updated without calling update().
-                * @param[in]   changes     Which item data was updated
+                * @brief Mark item as changed with specified change type.
+                * @param[in]   changeType  Item change type
+                * @param[in]   changes     Which item data was updated if type is ChangeUpdate
+                */
+               void setChanged(ChangeType changeType, int changes = 0);
+
+               /**
+                * @brief Called after setStandalone() to change item standalone state.
+                * @param[in]   isStandalone    Whether item is standalone
                 */
-               void setUpdated(int changes);
+               virtual void onStandalone(bool isStandalone) { }
 
                /**
                 * @brief Called after update() to update item data.
@@ -89,6 +107,7 @@ namespace Model2
                friend class DataProvider;
                void onUpdated();
 
+               bool m_IsStandalone;
                int m_Changes;
                ChangeType m_ChangeType;
 
index b08b21b..faf0d47 100644 (file)
@@ -20,7 +20,7 @@
 using namespace Model2;
 
 DataItem::DataItem()
-       : m_Changes(0), m_ChangeType(ChangeNone)
+       : m_IsStandalone(false), m_Changes(0), m_ChangeType(ChangeNone)
 {
 }
 
@@ -28,6 +28,23 @@ void DataItem::update(void *data)
 {
        m_Changes |= onUpdate(data);
        m_ChangeType = ChangeUpdate;
+
+       if (m_IsStandalone) {
+               onUpdated();
+       }
+}
+
+bool DataItem::isStandalone() const
+{
+       return m_IsStandalone;
+}
+
+void DataItem::setStandalone(bool isStandalone)
+{
+       if (m_IsStandalone != isStandalone) {
+               m_IsStandalone = isStandalone;
+               onStandalone(m_IsStandalone);
+       }
 }
 
 void DataItem::setUpdateCallback(UpdateCallback callback)
@@ -40,13 +57,18 @@ void DataItem::setDeleteCallback(DeleteCallback callback)
        m_OnDeleted = std::move(callback);
 }
 
-void DataItem::setUpdated(int changes)
+void DataItem::setChanged(ChangeType changeType, int changes)
 {
        if (m_ChangeType == ChangeNone) {
-               m_ChangeType = ChangeUpdate;
+               m_ChangeType = changeType;
+       }
+       if (changeType == ChangeUpdate) {
+               m_Changes |= changes;
        }
 
-       m_Changes |= changes;
+       if (m_IsStandalone) {
+               onUpdated();
+       }
 }
 
 void DataItem::onUpdated()
index c2c6f34..8ae5f98 100644 (file)
@@ -38,10 +38,9 @@ namespace Contacts
                public:
                        /**
                         * @brief Create members list view.
-                        * @param[in]   id          Group id
-                        * @param[in]   provider    Group provider
+                        * @param[in]   provider    Group members provider
                         */
-                       MembersListView(int id, Model::MembersProvider *provider);
+                       MembersListView(Model::MembersProvider *provider);
 
                private:
                        enum EditType {
@@ -56,9 +55,10 @@ namespace Contacts
 
                        virtual void onPageAttached(Ui::NavigatorPage *page) override;
                        virtual void onMenuPressed() override;
+                       virtual void onInitialized() override;
                        virtual void onUpdateFinished() override;
 
-                       std::string getTitle() const;
+                       void updateTitle();
 
                        void onAddSelected();
                        void onRemoveSelected();
index 0d8d629..39d9959 100644 (file)
@@ -107,13 +107,20 @@ namespace Contacts
 
                        private:
                                friend class GroupsProvider;
-
                                const Utils::UniString &getSortValue() const;
-                               virtual int onUpdate(void *data) override;
+
                                void updateMembersCount();
+                               virtual int onUpdate(void *data) override;
+                               virtual void onStandalone(bool isStandalone) override;
+                               void onGroupsChanged(const char *uri);
+
+                               void setChangeCallback();
+                               void unsetChangeCallback();
 
-                               Common::GroupType m_Type;
                                contacts_record_h m_Record;
+                               int m_DbVersion;
+
+                               Common::GroupType m_Type;
                                mutable Utils::UniString m_SortValue;
                                int m_MembersCount;
                        };
index 61cf15d..fb41bba 100644 (file)
@@ -33,36 +33,36 @@ namespace Contacts
                        {
                        public:
                                /**
-                            * @brief Determines which items are displayed.
+                                * @brief Determines which items are displayed.
                                 */
                                enum Mode
                                {
-                                       ModeDefault,        /**< Group's members are displayed */
-                                       ModeExclude         /**< Displayed all contacts which are not group's members */
+                                       ModeDefault, /**< Group's members are displayed */
+                                       ModeExclude  /**< Displayed all contacts which are not group's members */
                                };
 
                                /**
                                 * @brief Constructor.
                                 * @param[in]   groupId     Group id
                                 * @param[in]   mode        Members mode
-                                * @param[in]   type        Fiter type
+                                * @param[in]   type        Filter type
                                 */
                                explicit MembersProvider(int groupId, Mode mode = ModeDefault,
                                                int type = FilterNone);
-                               virtual ~MembersProvider() override;
+
+                               /**
+                                * @return Group ID.
+                                */
+                               int getGroupId() const;
 
                        private:
                                virtual contacts_filter_h getFilter() const override;
                                virtual contacts_list_h getPersonList() const override;
                                virtual contacts_record_h getPersonRecord(int id, IdType idType) const override;
-
                                contacts_list_h getMembersList() const;
 
-                               void onGroupChanged(const char *uri);
-
                                int m_GroupId;
                                Mode m_Mode;
-                               int m_GroupDbVersion;
                        };
                }
        }
index 6f28e43..0e4804b 100644 (file)
@@ -108,7 +108,12 @@ namespace Contacts
                        Model::PersonProvider *getProvider() const;
 
                        /**
-                        * @brief Called when updating is finished
+                        * @brief Called when provider initialization is finished.
+                        */
+                       virtual void onInitialized();
+
+                       /**
+                        * @brief Called when updating is finished.
                         */
                        virtual void onUpdateFinished();
 
index dc97966..0150467 100644 (file)
@@ -87,6 +87,5 @@ void GroupItem::onSelected()
                return;
        }
 
-       navigator->navigateTo(new MembersListView(m_Group.getId(),
-                       new MembersProvider(m_Group.getId())));
+       navigator->navigateTo(new MembersListView(new MembersProvider(m_Group.getId())));
 }
index 70c7acb..3f5a8a0 100644 (file)
@@ -54,30 +54,35 @@ namespace
                unsigned int propertyId;
                const char *scheme;
        } composerData[] = {
-               /*ComposerMessage = */ { Contacts::FilterNumber, CONTACTS_PERSON_PROPERTY_NUMBER,
+               /* ComposerMessage = */ { Contacts::FilterNumber, CONTACTS_PERSON_PROPERTY_NUMBER,
                                _contacts_number._uri, _contacts_number.number, "sms:" },
-               /*ComposerEmail   = */ { Contacts::FilterEmail, CONTACTS_PERSON_PROPERTY_EMAIL,
+               /* ComposerEmail   = */ { Contacts::FilterEmail, CONTACTS_PERSON_PROPERTY_EMAIL,
                                _contacts_email._uri, _contacts_email.email, "mailto:" }
        };
 }
 
-MembersListView::MembersListView(int id, MembersProvider *provider)
-       : ListView(provider), m_Group(id)
+MembersListView::MembersListView(MembersProvider *provider)
+       : ListView(provider), m_Group(provider->getGroupId())
 {
        setAddButtonVisibility(false);
        setNoContentHelpText("IDS_PB_BODY_AFTER_YOU_ADD_CONTACTS_THEY_WILL_BE_SHOWN_HERE");
        for (size_t i = ListView::SectionFirst; i < ListView::SectionMax; ++i) {
                setSectionVisibility(static_cast<ListView::SectionId>(i), false);
        }
+
+       m_Group.setStandalone(true);
+       m_Group.setUpdateCallback([this](int changes) {
+               updateTitle();
+       });
+       m_Group.setDeleteCallback([this] {
+               getPage()->close();
+       });
 }
 
 void MembersListView::onPageAttached(NavigatorPage *page)
 {
-       if (getSelectMode() == SelectNone) {
-               page->setTitle(getTitle().c_str());
-       } else {
-               SelectView::onPageAttached(page);
-       }
+       SelectView::onPageAttached(page);
+       updateTitle();
 }
 
 void MembersListView::onMenuPressed()
@@ -107,28 +112,37 @@ void MembersListView::onMenuPressed()
        menu->show();
 }
 
+void MembersListView::onInitialized()
+{
+       ListView::onInitialized();
+       updateTitle();
+}
+
 void MembersListView::onUpdateFinished()
 {
        ListView::onUpdateFinished();
-
-       if (getSelectMode() == SelectNone) {
-               getPage()->setTitle(getTitle().c_str());
-       }
+       updateTitle();
 }
 
-std::string MembersListView::getTitle() const
+void MembersListView::updateTitle()
 {
-       const char *name = (m_Group.getType() == GroupCustom) ? m_Group.getName()
-                       : _(getDefaultGroupName(m_Group.getType()));
+       Ui::NavigatorPage *page = getPage();
+       if (!page || getSelectMode() != SelectNone) {
+               return;
+       }
+
+       const char *name = (m_Group.getType() == GroupCustom) ?
+                       m_Group.getName() : _(getDefaultGroupName(m_Group.getType()));
 
-       char title[BUFFER_SIZE] = { 0, };
        int count = getProvider()->getDataList().size();
-       if (count) {
-               snprintf(title, sizeof(title), "%s (%d)", name, count);
-       } else {
-               snprintf(title, sizeof(title), "%s", name);
+       if (count == 0) {
+               page->setTitle(name);
+               return;
        }
-       return std::string(title);
+
+       char title[BUFFER_SIZE];
+       snprintf(title, sizeof(title), "%s (%d)", name, count);
+       page->setTitle(title);
 }
 
 void MembersListView::onAddSelected()
@@ -170,10 +184,12 @@ void MembersListView::onRemoveSelected()
 bool MembersListView::onRemoveFinished()
 {
        setSelectMode(SelectNone);
-       getPage()->setTitleVisibility(true);
-       getPage()->setTitle(getTitle().c_str());
        setCancelCallback(nullptr);
        setSelectCallback(nullptr);
+
+       getPage()->setTitleVisibility(true);
+       updateTitle();
+
        return false;
 }
 
@@ -200,7 +216,7 @@ void MembersListView::onMembersSelected(SelectResults results, EditType type)
 
 void MembersListView::onSendSelected(ComposerType composerType)
 {
-       MembersListView *view = new MembersListView(m_Group.getId(), new MembersProvider(m_Group.getId(),
+       MembersListView *view = new MembersListView(new MembersProvider(m_Group.getId(),
                        MembersProvider::ModeDefault, composerData[composerType].type));
        view->setSelectMode(SelectMulti);
        view->setNoContentHelpText("");
index d96247c..6ab8584 100644 (file)
 
 #include "Contacts/Groups/Model/Group.h"
 #include "Contacts/Groups/Model/Queries.h"
+#include "Common/Database/RecordIterator.h"
 #include "Common/Database/RecordUtils.h"
+
+#include "Utils/Callback.h"
 #include "Utils/Logger.h"
 
 using namespace Common::Database;
 using namespace Contacts::Groups::Model;
 
-Group::Group(int id)
+namespace
 {
-       if (id) {
-               contacts_db_get_record(_contacts_group._uri, id, &m_Record);
-       } else {
-               contacts_record_create(_contacts_group._uri, &m_Record);
+       contacts_record_h fetchGroupRecord(int id)
+       {
+               contacts_record_h record = nullptr;
+               if (id) {
+                       contacts_db_get_record(_contacts_group._uri, id, &record);
+               } else {
+                       contacts_record_create(_contacts_group._uri, &record);
+               }
+
+               return record;
        }
-       m_Type = Common::getGroupType(getName());
-       m_MembersCount = Model::getMembersCount(id);
+}
+
+Group::Group(int id)
+       : Group(fetchGroupRecord(id))
+{
 }
 
 Group::Group(contacts_record_h record)
-       : m_Record(record)
+       : m_Record(record), m_DbVersion(0)
 {
        m_Type = Common::getGroupType(getName());
        m_MembersCount = Model::getMembersCount(getId());
@@ -43,6 +55,10 @@ Group::Group(contacts_record_h record)
 
 Group::~Group()
 {
+       if (isStandalone()) {
+               unsetChangeCallback();
+       }
+
        contacts_record_destroy(m_Record, true);
 }
 
@@ -130,6 +146,12 @@ const Utils::UniString &Group::getSortValue() const
        return m_SortValue;
 }
 
+void Group::updateMembersCount()
+{
+       m_MembersCount = Model::getMembersCount(getId());
+       setChanged(Model2::ChangeUpdate, ChangedMembersCount);
+}
+
 int Group::onUpdate(void *data)
 {
        contacts_record_h record = (contacts_record_h) data;
@@ -145,8 +167,47 @@ int Group::onUpdate(void *data)
        return changes;
 }
 
-void Group::updateMembersCount()
+void Group::onStandalone(bool isStandalone)
 {
-       m_MembersCount = Model::getMembersCount(getId());
-       setUpdated(ChangedMembersCount);
+       if (isStandalone) {
+               setChangeCallback();
+       } else {
+               unsetChangeCallback();
+       }
+}
+
+void Group::onGroupsChanged(const char *uri)
+{
+       contacts_list_h changes = nullptr;
+       contacts_db_get_changes_by_version(_contacts_group_updated_info._uri, 0,
+                       m_DbVersion, &changes, &m_DbVersion);
+
+       for (auto &&record : makeRange(changes)) {
+               int groupId = getRecordInt(record, _contacts_group_updated_info.group_id);
+               if (groupId == getId()) {
+                       int changeType = getRecordInt(record, _contacts_group_updated_info.type);
+                       if (changeType == CONTACTS_CHANGE_UPDATED) {
+                               update(fetchGroupRecord(getId()));
+                       } else if (changeType == CONTACTS_CHANGE_DELETED) {
+                               setChanged(Model2::ChangeDelete);
+                       }
+                       break;
+               }
+       }
+
+       contacts_list_destroy(changes, true);
+}
+
+void Group::setChangeCallback()
+{
+       contacts_db_get_current_version(&m_DbVersion);
+       contacts_db_add_changed_cb(_contacts_group._uri,
+                       makeCallbackWithLastParam(&Group::onGroupsChanged), this);
+}
+
+void Group::unsetChangeCallback()
+{
+       contacts_db_remove_changed_cb(_contacts_group._uri,
+                       makeCallbackWithLastParam(&Group::onGroupsChanged), this);
+       m_DbVersion = 0;
 }
index 2ff5111..fe2e00b 100644 (file)
@@ -40,15 +40,11 @@ namespace
 MembersProvider::MembersProvider(int groupId, Mode mode, int type)
        : PersonProvider(type), m_GroupId(groupId), m_Mode(mode)
 {
-       contacts_db_get_current_version(&m_GroupDbVersion);
-       contacts_db_add_changed_cb(_contacts_group._uri,
-                       makeCallbackWithLastParam(&MembersProvider::onGroupChanged), this);
 }
 
-MembersProvider::~MembersProvider()
+int MembersProvider::getGroupId() const
 {
-       contacts_db_remove_changed_cb(_contacts_group._uri,
-                       makeCallbackWithLastParam(&MembersProvider::onGroupChanged), this);
+       return m_GroupId;
 }
 
 contacts_filter_h MembersProvider::getFilter() const
@@ -138,28 +134,3 @@ contacts_list_h MembersProvider::getMembersList() const
        contacts_query_destroy(query);
        return list;
 }
-
-void MembersProvider::onGroupChanged(const char *uri)
-{
-       contacts_list_h changes = nullptr;
-       contacts_db_get_changes_by_version(_contacts_group_updated_info._uri, 0,
-                       m_GroupDbVersion, &changes, &m_GroupDbVersion);
-       bool isChanged = false;
-
-       for (auto &&record : makeRange(changes)) {
-               if (getRecordInt(record, _contacts_group_updated_info.group_id) != m_GroupId) {
-                       continue;
-               }
-               int changeType = getRecordInt(record, _contacts_group_updated_info.type);
-               switch (changeType) {
-                       case CONTACTS_CHANGE_UPDATED:
-                               isChanged = true;
-                               break;
-               }
-       }
-       contacts_list_destroy(changes, true);
-
-       if (isChanged) {
-               onUpdateFinished();
-       }
-}
index c74850e..bd02ddf 100644 (file)
@@ -111,6 +111,20 @@ PersonProvider *ListView::getProvider() const
        return m_PersonProvider;
 }
 
+void ListView::onInitialized()
+{
+       fillPersonList();
+       updateSections();
+       updateEmptyState();
+       if (auto item = m_Genlist->getFirstItem()) {
+               item->scrollTo();
+       }
+       elm_index_level_go(m_Index, 0);
+       if (m_OnFillFinished) {
+               m_OnFillFinished();
+       }
+}
+
 void ListView::onUpdateFinished()
 {
        elm_index_level_go(m_Index, 0);
@@ -134,19 +148,7 @@ void ListView::onCreated()
        fillLayout();
        updateSection(SectionMyProfile);
 
-       m_SearchProvider.initialize([this] {
-               fillPersonList();
-               updateSections();
-               updateEmptyState();
-               if (auto item = m_Genlist->getFirstItem()) {
-                       item->scrollTo();
-               }
-               elm_index_level_go(m_Index, 0);
-               if (m_OnFillFinished) {
-                       m_OnFillFinished();
-               }
-       });
-
+       m_SearchProvider.initialize(std::bind(&ListView::onInitialized, this));
        m_SearchProvider.setInsertCallback(std::bind(&ListView::onPersonInserted, this, _1));
        m_PersonProvider->setUpdateFinishedCallback(std::bind(&ListView::onUpdateFinished, this));
 }