From dd5c18587d06546e951d8241c3f0d7cf8f099930 Mon Sep 17 00:00:00 2001 From: Nataliia Sydorchuk Date: Thu, 18 Aug 2016 09:43:35 +0300 Subject: [PATCH] TizenRefApp-6824 Implement selecting of group members in the "Select memberlist" view. Change-Id: I407f55451de13adace43c00d14eb15daf551dc3a Signed-off-by: Nataliia Sydorchuk --- lib-apps-common/inc/Ux/SelectView.h | 7 +++ lib-apps-common/src/Ux/SelectView.cpp | 16 ++++-- lib-contacts/inc/Contacts/Groups/AddMembersItem.h | 11 ++--- lib-contacts/inc/Contacts/Groups/InputView.h | 5 ++ lib-contacts/inc/Contacts/List/ListView.h | 13 +++++ .../src/Contacts/Groups/AddMembersItem.cpp | 45 ++++++++++------- lib-contacts/src/Contacts/Groups/InputView.cpp | 57 ++++++++++++++++++++-- .../src/Contacts/Groups/Model/MembersProvider.cpp | 5 -- lib-contacts/src/Contacts/List/ListView.cpp | 8 +++ 9 files changed, 133 insertions(+), 34 deletions(-) diff --git a/lib-apps-common/inc/Ux/SelectView.h b/lib-apps-common/inc/Ux/SelectView.h index b612146..ebed347 100644 --- a/lib-apps-common/inc/Ux/SelectView.h +++ b/lib-apps-common/inc/Ux/SelectView.h @@ -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; diff --git a/lib-apps-common/src/Ux/SelectView.cpp b/lib-apps-common/src/Ux/SelectView.cpp index 07dccf8..f3c0f86 100644 --- a/lib-apps-common/src/Ux/SelectView.cpp +++ b/lib-apps-common/src/Ux/SelectView.cpp @@ -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(); } } diff --git a/lib-contacts/inc/Contacts/Groups/AddMembersItem.h b/lib-contacts/inc/Contacts/Groups/AddMembersItem.h index e158cd8..3908006 100644 --- a/lib-contacts/inc/Contacts/Groups/AddMembersItem.h +++ b/lib-contacts/inc/Contacts/Groups/AddMembersItem.h @@ -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 groupMembers); /** - * @return the list of contact id added by user + * @return the list of person id added by user */ - const std::vector &getMemberIdList() const; + const std::vector &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 m_ContactIdList; + std::vector m_Members; }; } } diff --git a/lib-contacts/inc/Contacts/Groups/InputView.h b/lib-contacts/inc/Contacts/Groups/InputView.h index e13bda2..888b1c6 100644 --- a/lib-contacts/inc/Contacts/Groups/InputView.h +++ b/lib-contacts/inc/Contacts/Groups/InputView.h @@ -21,6 +21,7 @@ #include "Ui/View.h" #include +#include namespace Ui { @@ -64,8 +65,12 @@ namespace Contacts bool isAlreadyExists(); void save(); + void getGroupMembers(); + int m_Id; contacts_record_h m_Record; + std::vector m_GroupMembers; + Evas_Object *m_CancelButton; Evas_Object *m_DoneButton; Ui::Genlist *m_Genlist; diff --git a/lib-contacts/inc/Contacts/List/ListView.h b/lib-contacts/inc/Contacts/List/ListView.h index 40dd00a..69d11ba 100644 --- a/lib-contacts/inc/Contacts/List/ListView.h +++ b/lib-contacts/inc/Contacts/List/ListView.h @@ -50,6 +50,11 @@ namespace Contacts { public: /** + * @brief Called when fill of list view is finished + */ + typedef std::function 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 m_PersonGroups; Model::PersonProvider *m_PersonProvider; Model::PersonSearchProvider m_SearchProvider; + + FillFinishCallback m_OnFillFinished; }; } } diff --git a/lib-contacts/src/Contacts/Groups/AddMembersItem.cpp b/lib-contacts/src/Contacts/Groups/AddMembersItem.cpp index 447d96f..6dd35d3 100644 --- a/lib-contacts/src/Contacts/Groups/AddMembersItem.cpp +++ b/lib-contacts/src/Contacts/Groups/AddMembersItem.cpp @@ -18,16 +18,17 @@ #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 #include #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 groupMembers) + : m_Members(std::move(groupMembers)) { - m_Count = getMembersCount(m_GroupId); + m_Count = m_Members.size(); } -const std::vector &AddMembersItem::getMemberIdList() const +const std::vector &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(*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(); } diff --git a/lib-contacts/src/Contacts/Groups/InputView.cpp b/lib-contacts/src/Contacts/Groups/InputView.cpp index 70d6dc8..38df989 100644 --- a/lib-contacts/src/Contacts/Groups/InputView.cpp +++ b/lib-contacts/src/Contacts/Groups/InputView.cpp @@ -18,15 +18,19 @@ #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 #include #include @@ -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); +} diff --git a/lib-contacts/src/Contacts/Groups/Model/MembersProvider.cpp b/lib-contacts/src/Contacts/Groups/Model/MembersProvider.cpp index 26808b7..2ff5111 100644 --- a/lib-contacts/src/Contacts/Groups/Model/MembersProvider.cpp +++ b/lib-contacts/src/Contacts/Groups/Model/MembersProvider.cpp @@ -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)) { diff --git a/lib-contacts/src/Contacts/List/ListView.cpp b/lib-contacts/src/Contacts/List/ListView.cpp index 377040e..62125d8 100644 --- a/lib-contacts/src/Contacts/List/ListView.cpp +++ b/lib-contacts/src/Contacts/List/ListView.cpp @@ -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 &§ion : m_Sections) { -- 2.7.4