#define CONTACTS_LIST_LIST_VIEW_H
#include "Contacts/List/Model/PersonProvider.h"
+#include "Contacts/List/PersonItem.h"
#include "Ui/View.h"
#include "Utils/UniString.h"
#include <map>
class EXPORT_API ListView : public Ui::View
{
public:
- ListView();
+ /**
+ * @brief Represents view mode
+ */
+ enum Mode
+ {
+ ModeDefault,
+ ModeMultipick,
+ ModeMax
+ };
+
+ /**
+ * @brief Create new person list view
+ * @param]in] personFilter Defines how to filter person list
+ */
+ ListView(Model::PersonProvider::FilterType personFilter =
+ Model::PersonProvider::FilterNone);
virtual ~ListView() override;
+ /**
+ * @brief Set view mode
+ * @details View can be in Default, SinglePick or Multipick mode
+ * @param[in] mode View mode
+ */
+ void setMode(Mode mode);
+
private:
- virtual Evas_Object *onCreate(Evas_Object *parent) override;
- Evas_Object *createIndex(Evas_Object *parent);
+ enum SectionId
+ {
+ SectionFirst,
+ SectionSearch = SectionFirst,
+ SectionSelectAll,
+ SectionMyProfile,
+ SectionFavorites,
+ SectionMfc,
+ SectionPerson,
+ SectionMax
+ };
+ virtual Evas_Object *onCreate(Evas_Object *parent) override;
virtual void onPageAttached() override;
virtual void onCreated() override;
+ virtual void onMenuPressed() override;
void fillList();
+ void fillSearchItem();
+ void fillSelectAllItem();
void fillMyProfile();
+ void fillFavorites();
+ void fillMfc();
+ void fillPersonList();
- void insertMyProfileGroupItem();
- Ui::GenlistGroupItem *getNextMyProfileGroupItem();
+ void setFavouriteItemsMode(PersonItem::Mode mode);
+ void setPersonItemsMode(PersonItem::Mode mode);
+
+ void addSection(SectionId sectionId);
+ void removeSection(SectionId sectionId);
+ Ui::GenlistGroupItem *getNextSectionItem(SectionId currentSection);
+ bool getSectionVisibility(Mode mode, SectionId sectionId);
+
+ PersonItem::Mode getItemMode(Mode viewMode);
+
+ void updateTitle();
+ void createNewContactButton();
+ void deleteNewContactButton();
+
+ void insertMyProfileGroupItem();
void updateMyProfileItem(const char *view_uri);
+ Evas_Object *createIndex(Evas_Object *parent);
Elm_Index_Item *insertIndexItem(const char *indexLetter,
Elm_Index_Item *nextItem = nullptr);
- PersonGroupItem *insertGroupItem(Utils::UniString indexLetter,
+ PersonGroupItem *insertPersonGroupItem(Utils::UniString indexLetter,
PersonGroupItem *nextGroup = nullptr);
- void deleteGroupItem(PersonGroupItem *group);
- PersonGroupItem *getNextGroupItem(const Utils::UniString &indexLetter);
+ void deletePersonGroupItem(PersonGroupItem *group);
+ PersonGroupItem *getNextPersonGroupItem(const Utils::UniString &indexLetter);
PersonItem *createPersonItem(Model::PersonPtr person);
void insertPersonItem(PersonItem *item);
void deletePersonItem(PersonItem *item);
PersonItem *getNextPersonItem(PersonGroupItem *group, const Model::Person &person);
+ void launchPersonDetail(PersonItem *item);
+
void onIndexChanged(Evas_Object *index, Elm_Object_Item *indexItem);
void onIndexSelected(Evas_Object *index, Elm_Object_Item *indexItem);
void onCreatePressed();
- virtual void onMenuPressed() override;
void onPersonInserted(Model::PersonPtr person);
void onPersonChanged(Model::PersonPtr person, contacts_changed_e changeType, PersonItem *item);
+ void onItemChecked(PersonItem *item);
+
Ui::Genlist *m_Genlist;
Evas_Object *m_Index;
- GroupItem *m_MyProfileGroup;
- std::map<Utils::UniString, PersonGroupItem *> m_Groups;
+ Ui::GenlistGroupItem *m_Sections[SectionMax];
+ std::map<Utils::UniString, PersonGroupItem *> m_PersonGroups;
Model::PersonProvider m_Provider;
+
+ Mode m_ViewMode;
+
+ size_t m_PersonCount;
+ size_t m_CheckedCount;
};
}
}
#include "Contacts/List/ListView.h"
#include "Contacts/List/GroupItem.h"
#include "Contacts/List/MyProfileItem.h"
-#include "Contacts/List/PersonItem.h"
#include "Contacts/List/PersonGroupItem.h"
#include "Contacts/Input/InputView.h"
#include "Contacts/Settings/MainView.h"
#include "Ui/Menu.h"
#include "Ui/Navigator.h"
#include "Utils/Callback.h"
-#include "Utils/Logger.h"
+
+#include <app_i18n.h>
+#include <functional>
+
+#define TITLE_SIZE 32
using namespace Contacts;
using namespace Contacts::List;
using namespace Contacts::List::Model;
using namespace Utils;
-ListView::ListView()
+ListView::ListView(PersonProvider::FilterType personFilter)
: m_Genlist(nullptr), m_Index(nullptr),
- m_Provider(PersonProvider(PersonProvider::FilterNone))
+ m_Sections{ nullptr },
+ m_Provider(PersonProvider(personFilter)),
+ m_ViewMode(ModeDefault),
+ m_PersonCount(0), m_CheckedCount(0)
{
}
makeCallbackWithLastParam(&ListView::updateMyProfileItem), this);
}
+void ListView::setMode(Mode mode)
+{
+ if (m_ViewMode != mode) {
+ m_ViewMode = mode;
+
+ updateTitle();
+
+ for (size_t i = SectionFirst; i < SectionMax; ++i) {
+ if (getSectionVisibility(mode, static_cast<SectionId>(i))) {
+ addSection(static_cast<SectionId>(i));
+ } else {
+ removeSection(static_cast<SectionId>(i));
+ }
+ }
+
+ if (mode == ModeDefault) {
+ createNewContactButton();
+ } else {
+ deleteNewContactButton();
+ }
+ }
+}
+
Evas_Object *ListView::onCreate(Evas_Object *parent)
{
Evas_Object *layout = elm_layout_add(parent);
return layout;
}
-Evas_Object *ListView::createIndex(Evas_Object *parent)
-{
- m_Index = elm_index_add(parent);
- elm_index_autohide_disabled_set(m_Index, EINA_TRUE);
- elm_index_omit_enabled_set(m_Index, EINA_TRUE);
-
- evas_object_smart_callback_add(m_Index, "changed",
- (Evas_Smart_Cb) makeCallback(&ListView::onIndexChanged), this);
- evas_object_smart_callback_add(m_Index, "selected",
- (Evas_Smart_Cb) makeCallback(&ListView::onIndexSelected), this);
-
- return m_Index;
-}
-
void ListView::onPageAttached()
{
- Evas_Object *button = elm_button_add(getEvasObject());
- elm_object_style_set(button, "bottom");
- elm_object_translatable_text_set(button, "IDS_PB_OPT_CREATE");
- evas_object_smart_callback_add(button, "clicked",
- (Evas_Smart_Cb) makeCallback(&ListView::onCreatePressed), this);
-
- getPage()->setTitle("IDS_PB_TAB_CONTACTS");
- getPage()->setContent("toolbar", button);
+ updateTitle();
+ createNewContactButton();
}
void ListView::onCreated()
makeCallbackWithLastParam(&ListView::updateMyProfileItem), this);
}
-void ListView::fillList()
+void ListView::onMenuPressed()
{
- fillMyProfile();
-
- PersonList list = m_Provider.getPersonList();
- PersonGroupItem *group = nullptr;
+ Ui::Menu *menu = new Ui::Menu();
+ menu->create(getEvasObject());
- for (auto &&person : list) {
- const UniString &nextLetter = person->getIndexLetter();
+ menu->addItem("IDS_LOGS_OPT_DELETE", [this] {
+ ListView *deleteView = new ListView();
+ getNavigator()->navigateTo(deleteView);
+ deleteView->setMode(ModeMultipick);
+ });
- if (!group || group->getTitle() != nextLetter) {
- group = insertGroupItem(nextLetter);
- }
+ menu->addItem("IDS_PB_OPT_SETTINGS", [this] {
+ getNavigator()->navigateTo(new Settings::MainView());
+ });
+ menu->show();
+}
- m_Genlist->insert(createPersonItem(std::move(person)), group);
+void ListView::fillList()
+{
+ for (size_t i = SectionMyProfile; i < SectionMax; ++i) {
+ addSection(static_cast<SectionId>(i));
}
}
+void ListView::fillSearchItem()
+{
+ //Todo
+}
+
+void ListView::fillSelectAllItem()
+{
+ //Todo
+}
+
void ListView::fillMyProfile()
{
- if (!m_MyProfileGroup) {
+ if (!m_Sections[SectionMyProfile]) {
insertMyProfileGroupItem();
}
updateMyProfileItem(nullptr);
}
-void ListView::insertMyProfileGroupItem()
+void ListView::fillFavorites()
+{
+ if (!m_Sections[SectionFavorites]) {
+ //Todo Create here Favorite group
+ } else {
+ setFavouriteItemsMode(getItemMode(m_ViewMode));
+ }
+}
+
+void ListView::fillMfc()
+{
+ //Todo
+}
+
+void ListView::fillPersonList()
+{
+ if (m_PersonGroups.empty()) {
+ PersonList list = m_Provider.getPersonList();
+ PersonGroupItem *group = nullptr;
+
+ for (auto &&person : list) {
+ const UniString &nextLetter = person->getIndexLetter();
+
+ if (!group || group->getTitle() != nextLetter) {
+ group = insertPersonGroupItem(nextLetter);
+ }
+
+ m_Genlist->insert(createPersonItem(std::move(person)), group);
+
+ ++m_PersonCount;
+ }
+ } else {
+ setPersonItemsMode(getItemMode(m_ViewMode));
+ }
+}
+
+void ListView::setFavouriteItemsMode(PersonItem::Mode mode)
+{
+ if (m_Sections[SectionFavorites]) {
+ for (auto &&favoriteItem : *m_Sections[SectionFavorites]) {
+ static_cast<PersonItem*>(favoriteItem)->setMode(mode);
+ }
+ }
+}
+
+void ListView::setPersonItemsMode(PersonItem::Mode mode)
{
- m_MyProfileGroup = new GroupItem("IDS_PB_HEADER_ME");
- m_Genlist->insert(m_MyProfileGroup, nullptr, getNextMyProfileGroupItem());
- elm_genlist_item_select_mode_set(m_MyProfileGroup->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
+ for (auto &&group : m_PersonGroups) {
+ for (auto &&personItem : *group.second) {
+ static_cast<PersonItem*>(personItem)->setMode(mode);
+ }
+ }
}
-Ui::GenlistGroupItem *ListView::getNextMyProfileGroupItem()
+void ListView::addSection(SectionId sectionId)
{
- //Todo: Here will be search of next group item for My profile group item
+ switch (sectionId) {
+ case SectionSearch: fillSearchItem(); break;
+ case SectionSelectAll: fillSelectAllItem(); break;
+ case SectionMyProfile: fillMyProfile(); break;
+ case SectionFavorites: fillFavorites(); break;
+ case SectionMfc: fillMfc(); break;
+ case SectionPerson: fillPersonList(); break;
+ default: break;
+ }
+}
+
+void ListView::removeSection(SectionId sectionId)
+{
+ delete m_Sections[sectionId];
+ m_Sections[sectionId] = nullptr;
+}
+
+Ui::GenlistGroupItem *ListView::getNextSectionItem(SectionId currentSection)
+{
+ for (size_t nextSection = currentSection + 1; nextSection < SectionMax; ++nextSection) {
+ if (m_Sections[nextSection]) {
+ return m_Sections[nextSection];
+ }
+ }
+
return nullptr;
}
+bool ListView::getSectionVisibility(Mode mode, SectionId sectionId)
+{
+ static bool sectionVisibility[ListView::ModeMax][ListView::SectionMax] = {
+ /* ModeDefault = */ {
+ /* SectionSearch = */ true,
+ /* SectionSelectAll = */ false,
+ /* SectionMyProfile = */ true,
+ /* SectionFavorites = */ true,
+ /* SectionMfc = */ true,
+ /* SectionPerson = */ true
+ },
+ /* ModeMultipick = */ {
+ /* SectionSearch = */ true,
+ /* SectionSelectAll = */ true,
+ /* SectionMyProfile = */ false,
+ /* SectionFavorites = */ true,
+ /* SectionMfc = */ false,
+ /* SectionPerson = */ true
+ }
+ };
+
+ return sectionVisibility[mode][sectionId];
+}
+
+PersonItem::Mode ListView::getItemMode(Mode viewMode)
+{
+ if (viewMode == ModeMultipick) {
+ return PersonItem::ModePick;
+ } else {
+ return PersonItem::ModeDefault;
+ }
+}
+
+void ListView::updateTitle()
+{
+ switch (m_ViewMode) {
+ case ModeDefault: getPage()->setTitle("IDS_PB_TAB_CONTACTS"); break;
+ case ModeMultipick: {
+ char title[TITLE_SIZE];
+ snprintf(title, TITLE_SIZE, _("IDS_PB_HEADER_PD_SELECTED_ABB"), m_CheckedCount);
+
+ getPage()->setTitle(title);
+ break;
+ }
+ default: break;
+ }
+}
+
+void ListView::createNewContactButton()
+{
+ Evas_Object *button = elm_button_add(getEvasObject());
+ elm_object_style_set(button, "bottom");
+ elm_object_translatable_text_set(button, "IDS_PB_OPT_CREATE");
+ evas_object_smart_callback_add(button, "clicked",
+ (Evas_Smart_Cb) makeCallback(&ListView::onCreatePressed), this);
+
+ getPage()->setContent("toolbar", button);
+}
+
+void ListView::deleteNewContactButton()
+{
+ //Todo
+}
+
+void ListView::insertMyProfileGroupItem()
+{
+ auto group = new GroupItem("IDS_PB_HEADER_ME");
+ m_Genlist->insert(group, nullptr, getNextSectionItem(SectionMyProfile));
+ elm_genlist_item_select_mode_set(group->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
+
+ m_Sections[SectionMyProfile] = group;
+}
+
void ListView::updateMyProfileItem(const char *view_uri)
{
- elm_genlist_item_subitems_clear(m_MyProfileGroup->getObjectItem());
+ elm_genlist_item_subitems_clear(m_Sections[SectionMyProfile]->getObjectItem());
MyProfileItem *item = new MyProfileItem(MyProfilePtr(new MyProfile()));
- m_Genlist->insert(item, m_MyProfileGroup);
+ m_Genlist->insert(item, m_Sections[SectionMyProfile]);
item->setSelectedCallback([this, item]() {
int id = item->getMyProfile().getId();
});
}
+Evas_Object *ListView::createIndex(Evas_Object *parent)
+{
+ m_Index = elm_index_add(parent);
+ elm_index_autohide_disabled_set(m_Index, EINA_TRUE);
+ elm_index_omit_enabled_set(m_Index, EINA_TRUE);
+
+ evas_object_smart_callback_add(m_Index, "changed",
+ (Evas_Smart_Cb) makeCallback(&ListView::onIndexChanged), this);
+ evas_object_smart_callback_add(m_Index, "selected",
+ (Evas_Smart_Cb) makeCallback(&ListView::onIndexSelected), this);
+
+ return m_Index;
+}
+
Elm_Object_Item *ListView::insertIndexItem(const char *indexLetter, Elm_Object_Item *nextItem)
{
Elm_Object_Item *indexItem = nullptr;
return indexItem;
}
-PersonGroupItem *ListView::insertGroupItem(UniString indexLetter, PersonGroupItem *nextGroup)
+PersonGroupItem *ListView::insertPersonGroupItem(UniString indexLetter, PersonGroupItem *nextGroup)
{
Elm_Object_Item *indexItem = insertIndexItem(indexLetter.getUtf8Str().c_str(),
nextGroup ? nextGroup->getIndexItem() : nullptr);
elm_genlist_item_select_mode_set(item->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
elm_object_item_data_set(indexItem, item->getObjectItem());
- m_Groups.insert({ item->getTitle(), item });
+ m_PersonGroups.insert({ item->getTitle(), item });
+ m_Sections[SectionPerson] = m_PersonGroups.begin()->second;
return item;
}
-void ListView::deleteGroupItem(PersonGroupItem *group)
+void ListView::deletePersonGroupItem(PersonGroupItem *group)
{
elm_object_item_del(group->getIndexItem());
elm_index_level_go(m_Index, 0);
- m_Groups.erase(group->getTitle());
+ m_PersonGroups.erase(group->getTitle());
+ m_Sections[SectionPerson] = !m_PersonGroups.empty() ? m_PersonGroups.begin()->second : nullptr;
delete group;
}
-PersonGroupItem *ListView::getNextGroupItem(const Utils::UniString &indexLetter)
+PersonGroupItem *ListView::getNextPersonGroupItem(const Utils::UniString &indexLetter)
{
- auto it = m_Groups.lower_bound(indexLetter);
- if (it != m_Groups.end()) {
+ auto it = m_PersonGroups.lower_bound(indexLetter);
+ if (it != m_PersonGroups.end()) {
return it->second;
}
{
using namespace std::placeholders;
- PersonItem *item = new PersonItem(std::move(person));
+ PersonItem *item = new PersonItem(std::move(person), getItemMode(m_ViewMode));
m_Provider.setChangeCallback(item->getPerson(),
std::bind(&ListView::onPersonChanged, this, _1, _2, item));
item->setSelectedCallback([this, item]() {
- int id = 0;
- contacts_record_get_int(item->getPerson().getRecord(), _contacts_person.display_contact_id, &id);
-
- getNavigator()->navigateTo(new Input::InputView(id));
+ switch (m_ViewMode) {
+ case ModeDefault: launchPersonDetail(item); break;
+ case ModeMultipick: onItemChecked(item); break;
+ default: break;
+ }
});
return item;
PersonItem *nextItem = nullptr;
const UniString &indexLetter = item->getPerson().getIndexLetter();
- auto it = m_Groups.find(indexLetter);
- if (it != m_Groups.end()) {
+ auto it = m_PersonGroups.find(indexLetter);
+ if (it != m_PersonGroups.end()) {
group = it->second;
nextItem = getNextPersonItem(it->second, item->getPerson());
} else {
- PersonGroupItem *nextGroup = getNextGroupItem(indexLetter);
- group = insertGroupItem(indexLetter, nextGroup);
+ PersonGroupItem *nextGroup = getNextPersonGroupItem(indexLetter);
+ group = insertPersonGroupItem(indexLetter, nextGroup);
}
m_Genlist->insert(item, group, nextItem);
+
+ ++m_PersonCount;
}
void ListView::updatePersonItem(PersonItem *item, Model::PersonPtr person)
insertPersonItem(item);
if (oldGroup->empty()) {
- deleteGroupItem(oldGroup);
+ deletePersonGroupItem(oldGroup);
}
} else {
const char *oldImagePath = item->getPerson().getImagePath();
m_Provider.unsetChangeCallback(item->getPerson());
delete item;
+ --m_PersonCount;
+
if (oldGroup->empty()) {
- deleteGroupItem(oldGroup);
+ deletePersonGroupItem(oldGroup);
}
}
return nullptr;
}
+void ListView::launchPersonDetail(PersonItem *item)
+{
+ int id = 0;
+ contacts_record_get_int(item->getPerson().getRecord(), _contacts_person.display_contact_id, &id);
+
+ getNavigator()->navigateTo(new Input::InputView(id));
+}
+
void ListView::onIndexChanged(Evas_Object *index, Elm_Object_Item *indexItem)
{
Elm_Object_Item *genlistItem = (Elm_Object_Item *) elm_object_item_data_get(indexItem);
getNavigator()->navigateTo(new Input::InputView());
}
-void ListView::onMenuPressed()
-{
- Ui::Menu *menu = new Ui::Menu();
- menu->create(getEvasObject());
-
- menu->addItem("IDS_PB_OPT_SETTINGS", [this] {
- getNavigator()->navigateTo(new Settings::MainView());
- });
- menu->show();
-}
-
void ListView::onPersonInserted(PersonPtr person)
{
insertPersonItem(createPersonItem(std::move(person)));
updatePersonItem(item, std::move(person));
}
}
+
+void ListView::onItemChecked(PersonItem *item)
+{
+ item->isChecked() ? ++m_CheckedCount : --m_CheckedCount;
+ updateTitle();
+
+ //Todo: Make "Select all" calculations
+}