TizenRefApp-6824 Implement selecting of group members in the "Select memberlist"... 17/83917/7
authorNataliia Sydorchuk <n.sydorchuk@samsung.com>
Thu, 18 Aug 2016 06:43:35 +0000 (09:43 +0300)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 18 Aug 2016 14:48:25 +0000 (07:48 -0700)
Change-Id: I407f55451de13adace43c00d14eb15daf551dc3a
Signed-off-by: Nataliia Sydorchuk <n.sydorchuk@samsung.com>
lib-apps-common/inc/Ux/SelectView.h
lib-apps-common/src/Ux/SelectView.cpp
lib-contacts/inc/Contacts/Groups/AddMembersItem.h
lib-contacts/inc/Contacts/Groups/InputView.h
lib-contacts/inc/Contacts/List/ListView.h
lib-contacts/src/Contacts/Groups/AddMembersItem.cpp
lib-contacts/src/Contacts/Groups/InputView.cpp
lib-contacts/src/Contacts/Groups/Model/MembersProvider.cpp
lib-contacts/src/Contacts/List/ListView.cpp

index b612146..ebed347 100644 (file)
@@ -116,6 +116,12 @@ namespace Ux
                 */
                const SelectItems &getSelectItems() const;
 
+               /**
+                * @brief Enable active Done button despite number of selections.
+                * @param[in]   isAllowed   True - Done button should be enabled, otherwise false
+                */
+               void setEmptyResultAllowed(bool isAllowed);
+
        protected:
                /**
                 * @return View selection mode.
@@ -219,6 +225,7 @@ namespace Ux
                size_t m_TotalCount;
                size_t m_SelectCount;
                size_t m_SelectLimit;
+               bool m_IsEmptyResultAllowed;
 
                SelectMode m_SelectMode;
                SelectCallback m_OnSelected;
index 07dccf8..f3c0f86 100644 (file)
@@ -33,8 +33,8 @@ using namespace std::placeholders;
 
 SelectView::SelectView()
        : m_DoneButton(nullptr), m_CancelButton(nullptr), m_IsChecking(false),
-         m_TotalCount(0), m_SelectCount(0), m_SelectLimit(0), m_SelectMode(SelectNone),
-         m_Strings{ nullptr }
+         m_TotalCount(0), m_SelectCount(0), m_SelectLimit(0), m_IsEmptyResultAllowed(false),
+         m_SelectMode(SelectNone), m_Strings{ nullptr }
 {
 }
 
@@ -111,6 +111,14 @@ const SelectView::SelectItems &SelectView::getSelectItems() const
        return m_Items;
 }
 
+void SelectView::setEmptyResultAllowed(bool isAllowed)
+{
+       if (isAllowed != m_IsEmptyResultAllowed) {
+               m_IsEmptyResultAllowed = isAllowed;
+               updateDoneButtonState();
+       }
+}
+
 SelectMode SelectView::getSelectMode() const
 {
        return m_SelectMode;
@@ -257,7 +265,8 @@ void SelectView::updateSelectAllItem()
 
 void SelectView::updateDoneButtonState()
 {
-       elm_object_disabled_set(m_DoneButton, m_SelectCount == 0);
+       elm_object_disabled_set(m_DoneButton,
+                       m_IsEmptyResultAllowed ? m_TotalCount == 0 : m_SelectCount == 0);
 }
 
 void SelectView::updateSelectAllState()
@@ -310,6 +319,7 @@ void SelectView::updateItemCount(CountChange change, SelectItem *item)
        }
        /* m_TotalCount: 0 -> 1 or 1 -> 0 */
        if (checkCount == 0) {
+               updateDoneButtonState();
                updateSelectAllItem();
        }
 }
index e158cd8..3908006 100644 (file)
@@ -45,14 +45,14 @@ namespace Contacts
                public:
                        /**
                         * @brief Constructor.
-                        * param[in]   groupId  Group id
+                        * param[in]   groupMembers Group members ids list
                         */
-                       AddMembersItem(int groupId);
+                       AddMembersItem(std::vector<int> groupMembers);
 
                        /**
-                        * @return the list of contact id added by user
+                        * @return the list of person id added by user
                         */
-                       const std::vector<int> &getMemberIdList() const;
+                       const std::vector<int> &getMembers() const;
 
                private:
                        virtual Elm_Genlist_Item_Class *getItemClass() const override;
@@ -64,9 +64,8 @@ namespace Contacts
                        void addMembers(Ux::SelectResults results);
                        void onAddMembersFinished(List::ListView *view, Ui::ProcessPopup *popup);
 
-                       int m_GroupId;
                        int m_Count;
-                       std::vector<int> m_ContactIdList;
+                       std::vector<int> m_Members;
                };
        }
 }
index e13bda2..888b1c6 100644 (file)
@@ -21,6 +21,7 @@
 #include "Ui/View.h"
 
 #include <contacts.h>
+#include <vector>
 
 namespace Ui
 {
@@ -64,8 +65,12 @@ namespace Contacts
                        bool isAlreadyExists();
                        void save();
 
+                       void getGroupMembers();
+
                        int m_Id;
                        contacts_record_h m_Record;
+                       std::vector<int> m_GroupMembers;
+
                        Evas_Object *m_CancelButton;
                        Evas_Object *m_DoneButton;
                        Ui::Genlist *m_Genlist;
index 40dd00a..69d11ba 100644 (file)
@@ -50,6 +50,11 @@ namespace Contacts
                {
                public:
                        /**
+                        * @brief Called when fill of list view is finished
+                        */
+                       typedef std::function<void()> FillFinishCallback;
+
+                       /**
                         * @brief Sections types
                         */
                        enum SectionId
@@ -93,6 +98,12 @@ namespace Contacts
                         */
                        void setNoContentHelpText(const char *text);
 
+                       /**
+                        * @brief Set view fill finish callback
+                        * @param[in]   callback    Callback to be called when fill of list view is finished
+                        */
+                       void setFillFinishCallback(FillFinishCallback callback);
+
                protected:
                        Model::PersonProvider *getProvider() const;
 
@@ -207,6 +218,8 @@ namespace Contacts
                        std::map<Utils::UniString, PersonGroupItem *> m_PersonGroups;
                        Model::PersonProvider *m_PersonProvider;
                        Model::PersonSearchProvider m_SearchProvider;
+
+                       FillFinishCallback m_OnFillFinished;
                };
        }
 }
index 447d96f..6dd35d3 100644 (file)
 #include "Contacts/Groups/AddMembersItem.h"
 
 #include "Contacts/Groups/Model/Queries.h"
-#include "Contacts/Groups/Model/MembersProvider.h"
 #include "Contacts/List/ListView.h"
+#include "Contacts/List/Model/Person.h"
+#include "Contacts/List/PersonItem.h"
 #include "GroupItemLayout.h"
 
 #include "Common/Database/RecordUtils.h"
 #include "Ui/Navigator.h"
 #include "Ui/ProcessPopup.h"
-#include "Utils/Logger.h"
 #include "Utils/Thread.h"
 
+#include <algorithm>
 #include <app_i18n.h>
 
 #define BUFFER_SIZE 32
@@ -36,16 +37,17 @@ using namespace Common::Database;
 using namespace Contacts::Groups;
 using namespace Contacts::Groups::Model;
 using namespace Contacts::List;
+using namespace Contacts::List::Model;
 
-AddMembersItem::AddMembersItem(int groupId)
-       : m_GroupId(groupId)
+AddMembersItem::AddMembersItem(std::vector<int> groupMembers)
+       : m_Members(std::move(groupMembers))
 {
-       m_Count = getMembersCount(m_GroupId);
+       m_Count = m_Members.size();
 }
 
-const std::vector<int> &AddMembersItem::getMemberIdList() const
+const std::vector<int> &AddMembersItem::getMembers() const
 {
-       return m_ContactIdList;
+       return m_Members;
 }
 
 Elm_Genlist_Item_Class *AddMembersItem::getItemClass() const
@@ -84,18 +86,25 @@ void AddMembersItem::onSelected()
                return;
        }
 
-       MembersProvider *provider = new MembersProvider(m_GroupId, MembersProvider::ModeExclude);
-       m_Count = getMembersCount(m_GroupId);
-       elm_genlist_item_fields_update(getObjectItem(),
-                       PART_GROUP_ADD_MEMBERS_COUNTER, ELM_GENLIST_ITEM_FIELD_TEXT);
-       m_ContactIdList.clear();
-
-       ListView *view = new ListView(provider);
+       ListView *view = new ListView(FilterNone);
        view->setSelectMode(Ux::SelectMulti);
        view->setSectionVisibility(ListView::SectionFavorites, false);
        view->setSelectCallback(std::bind(&AddMembersItem::onMembersSelected, this, view,
                        std::placeholders::_1));
-
+       view->setEmptyResultAllowed(true);
+
+       view->setFillFinishCallback([this, view] {
+               for (auto &&item : view->getSelectItems()) {
+                       PersonItem &personItem = static_cast<PersonItem &>(*item);
+                       int personId = personItem.getPerson().getId();
+                       auto it = std::find_if(m_Members.begin(), m_Members.end(), [personId](int id) {
+                               return personId == id;
+                       });
+                       if (it != m_Members.end()) {
+                               personItem.setChecked(true);
+                       }
+               }
+       });
        navigator->navigateTo(view);
 }
 
@@ -110,13 +119,15 @@ bool AddMembersItem::onMembersSelected(ListView *view, Ux::SelectResults results
 void AddMembersItem::addMembers(Ux::SelectResults results)
 {
        contacts_connect_on_thread();
+       m_Members.clear();
+
        for (auto &&result : results) {
                contacts_record_h record = nullptr;
                contacts_db_get_record(_contacts_person._uri, result.value.id, &record);
-               m_ContactIdList.push_back(getRecordInt(record, _contacts_person.display_contact_id));
+               m_Members.push_back(getRecordInt(record, _contacts_person.id));
                contacts_record_destroy(record, true);
        }
-       m_Count += m_ContactIdList.size();
+       m_Count = m_Members.size();
        contacts_disconnect_on_thread();
 }
 
index 70d6dc8..38df989 100644 (file)
 #include "Contacts/Groups/InputView.h"
 
 #include "Contacts/Groups/AddMembersItem.h"
+#include "Contacts/Groups/Model/Queries.h"
 #include "Contacts/Groups/NameItem.h"
 #include "Contacts/Groups/RingtoneItem.h"
 #include "GroupItemLayout.h"
 
 #include "App/Path.h"
+#include "Common/Database/Queries.h"
+#include "Common/Database/RecordIterator.h"
 #include "Common/Database/RecordUtils.h"
 #include "Ui/Genlist.h"
 #include "Utils/Callback.h"
 
+#include <algorithm>
 #include <app_i18n.h>
 #include <notification.h>
 
@@ -60,7 +64,8 @@ Evas_Object *InputView::onCreate(Evas_Object *parent)
        nameItem->setFilledCallback(std::bind(&InputView::onNameFilled, this, std::placeholders::_1));
        m_Genlist->insert(nameItem);
 
-       m_AddMembersItem = new AddMembersItem(m_Id);
+       getGroupMembers();
+       m_AddMembersItem = new AddMembersItem(m_GroupMembers);
        m_Genlist->insert(m_AddMembersItem);
 
        m_Genlist->insert(new RingtoneItem(m_Record));
@@ -143,9 +148,55 @@ void InputView::save()
        if (!m_Id) {
                contacts_db_insert_record(m_Record, &m_Id);
        }
-       for (auto &&contactId : m_AddMembersItem->getMemberIdList()) {
-               contacts_group_add_contact(m_Id, contactId);
+
+       for (auto &&personId : m_AddMembersItem->getMembers()) {
+               auto it = std::find_if(m_GroupMembers.begin(), m_GroupMembers.end(), [personId](int id) {
+                       return personId == id;
+               });
+
+               if (it != m_GroupMembers.end()) {
+                       m_GroupMembers.erase(it);
+               } else {
+                       contacts_list_h contacts = getPersonContacts(personId);
+                       for (auto &&record : makeRange(contacts)) {
+                               contacts_group_add_contact(m_Id, getRecordInt(record, _contacts_contact.id));
+                       }
+                       contacts_list_destroy(contacts, true);
+               }
+       }
+
+       for (auto &&personId : m_GroupMembers) {
+               contacts_list_h contacts = getPersonContacts(personId);
+               for (auto &&record : makeRange(contacts)) {
+                       contacts_group_remove_contact(m_Id, getRecordInt(record, _contacts_contact.id));
+               }
+               contacts_list_destroy(contacts, true);
        }
 
        contacts_db_update_record(m_Record);
 }
+
+void InputView::getGroupMembers()
+{
+       if (!m_Id) {
+               return;
+       }
+       m_GroupMembers.clear();
+
+       contacts_list_h list = nullptr;
+       contacts_query_h query = getMembersQuery(m_Id);
+       contacts_db_get_records_with_query(query, 0, 0, &list);
+
+       for (auto &&record : makeRange(list)) {
+               int personId = getRecordInt(record, _contacts_person_group_assigned.person_id);
+               auto it = std::find_if(m_GroupMembers.begin(), m_GroupMembers.end(), [personId](int id) {
+                       return personId == id;
+               });
+               if (it == m_GroupMembers.end()) {
+                       m_GroupMembers.push_back(personId);
+               }
+       }
+
+       contacts_list_destroy(list, true);
+       contacts_query_destroy(query);
+}
index 26808b7..2ff5111 100644 (file)
@@ -68,11 +68,6 @@ contacts_filter_h MembersProvider::getFilter() const
                contacts_filter_create(_contacts_person._uri, &filter);
        }
 
-       if (m_Mode == ModeExclude) {
-               contacts_filter_add_bool(filter, _contacts_person.is_favorite, false);
-               contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
-       }
-
        contacts_filter_h membersFilter = nullptr;
        contacts_filter_create(_contacts_person._uri, &membersFilter);
        for (auto &&record : makeRange(membersList)) {
index 377040e..62125d8 100644 (file)
@@ -140,12 +140,20 @@ void ListView::onCreated()
                        item->scrollTo();
                }
                elm_index_level_go(m_Index, 0);
+               if (m_OnFillFinished) {
+                       m_OnFillFinished();
+               }
        });
 
        m_SearchProvider.setInsertCallback(std::bind(&ListView::onPersonInserted, this, _1));
        m_PersonProvider->setUpdateFinishedCallback(std::bind(&ListView::onUpdateFinished, this));
 }
 
+void ListView::setFillFinishCallback(FillFinishCallback callback)
+{
+       m_OnFillFinished = std::move(callback);
+}
+
 void ListView::onDestroy()
 {
        for (auto &&section : m_Sections) {