mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-07-18 12:04:03 -04:00
Added two new scroll bar types. Fixed for ListView with equal height elements and PreRendered which require whole list render - not recommended for big lists but works with not equal heights elements. Applied new types to all lists in Pure. Various cleanups and refactors inside models and listView.
263 lines
9.6 KiB
C++
263 lines
9.6 KiB
C++
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "PhonebookNewContact.hpp"
|
|
|
|
#include "DialogMetadata.hpp"
|
|
#include "application-phonebook/ApplicationPhonebook.hpp"
|
|
#include "application-phonebook/data/PhonebookUtils.hpp"
|
|
|
|
#include <Dialog.hpp>
|
|
#include <service-db/DBServiceAPI.hpp>
|
|
#include <messages/DialogMetadataMessage.hpp>
|
|
|
|
namespace gui
|
|
{
|
|
|
|
PhonebookNewContact::PhonebookNewContact(app::Application *app)
|
|
: AppWindow(app, gui::window::name::new_contact), newContactModel{std::make_shared<NewContactModel>(app)}
|
|
{
|
|
buildInterface();
|
|
}
|
|
|
|
void PhonebookNewContact::rebuild()
|
|
{
|
|
destroyInterface();
|
|
buildInterface();
|
|
}
|
|
|
|
void PhonebookNewContact::buildInterface()
|
|
{
|
|
AppWindow::buildInterface();
|
|
|
|
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::save));
|
|
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
|
|
|
|
setTitle(utils::localize.get("app_phonebook_contact_title"));
|
|
|
|
list = new gui::ListView(this,
|
|
phonebookStyle::newContactWindow::newContactsList::x,
|
|
phonebookStyle::newContactWindow::newContactsList::y,
|
|
phonebookStyle::newContactWindow::newContactsList::w,
|
|
phonebookStyle::newContactWindow::newContactsList::h,
|
|
newContactModel,
|
|
style::listview::ScrollBarType::PreRendered);
|
|
setFocusItem(list);
|
|
}
|
|
|
|
void PhonebookNewContact::destroyInterface()
|
|
{
|
|
erase();
|
|
}
|
|
|
|
void PhonebookNewContact::onBeforeShow(ShowMode mode, SwitchData *data)
|
|
{
|
|
if (mode != ShowMode::GUI_SHOW_RETURN) {
|
|
newContactModel->clearData();
|
|
}
|
|
|
|
if (mode == ShowMode::GUI_SHOW_INIT) {
|
|
list->rebuildList();
|
|
}
|
|
|
|
switch (contactAction) {
|
|
case ContactAction::None:
|
|
break;
|
|
case ContactAction::Add:
|
|
case ContactAction::EditTemporary:
|
|
setTitle(utils::localize.get("app_phonebook_contact_title"));
|
|
break;
|
|
case ContactAction::Edit:
|
|
setTitle(utils::localize.get("app_phonebook_options_edit"));
|
|
break;
|
|
}
|
|
|
|
newContactModel->loadData(contact);
|
|
}
|
|
|
|
auto PhonebookNewContact::handleSwitchData(SwitchData *data) -> bool
|
|
{
|
|
if (data == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
auto *item = dynamic_cast<PhonebookItemData *>(data);
|
|
if (item == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
contact = item->getContact();
|
|
if (contact == nullptr) {
|
|
contactAction = ContactAction::Add;
|
|
contact = std::make_shared<ContactRecord>();
|
|
setSaveButtonVisible(false);
|
|
return true;
|
|
}
|
|
|
|
if (contact->ID == DB_ID_NONE) {
|
|
contactAction = ContactAction::Add;
|
|
setSaveButtonVisible(false);
|
|
}
|
|
else if (contact->isTemporary()) {
|
|
contactAction = ContactAction::EditTemporary;
|
|
}
|
|
else {
|
|
contactAction = ContactAction::Edit;
|
|
setSaveButtonVisible(true);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void PhonebookNewContact::setSaveButtonVisible(bool visible)
|
|
{
|
|
bottomBar->setActive(BottomBar::Side::CENTER, visible);
|
|
}
|
|
|
|
auto PhonebookNewContact::onInput(const InputEvent &inputEvent) -> bool
|
|
{
|
|
if (AppWindow::onInput(inputEvent)) {
|
|
return true;
|
|
}
|
|
|
|
if (inputEvent.state != InputEvent::State::keyReleasedShort) {
|
|
return false;
|
|
}
|
|
|
|
if (inputEvent.keyCode == gui::KeyCode::KEY_ENTER) {
|
|
auto tmpId = contact->ID;
|
|
contact = std::make_shared<ContactRecord>();
|
|
contact->ID = tmpId;
|
|
|
|
newContactModel->saveData(contact);
|
|
verifyAndSave();
|
|
|
|
return true;
|
|
}
|
|
|
|
application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
|
|
|
|
return false;
|
|
}
|
|
|
|
auto PhonebookNewContact::verifyAndSave() -> bool
|
|
{
|
|
LOG_DEBUG("%s", __FUNCTION__);
|
|
if (!contact->isTemporary()) {
|
|
auto result = DBServiceAPI::verifyContact(application, *contact);
|
|
switch (result) {
|
|
case DBServiceAPI::ContactVerificationResult::success:
|
|
break;
|
|
case DBServiceAPI::ContactVerificationResult::emptyContact:
|
|
return false;
|
|
case DBServiceAPI::ContactVerificationResult::primaryNumberDuplicate:
|
|
showDialogDuplicatedNumber(contact->numbers[0].number);
|
|
return false;
|
|
case DBServiceAPI::ContactVerificationResult::secondaryNumberDuplicate:
|
|
showDialogDuplicatedNumber(contact->numbers[1].number);
|
|
return false;
|
|
case DBServiceAPI::ContactVerificationResult::speedDialDuplicate:
|
|
showDialogDuplicatedSpeedDialNumber();
|
|
return false;
|
|
case DBServiceAPI::ContactVerificationResult::temporaryContactExists:
|
|
std::unique_ptr<ContactRecord> tempContact;
|
|
assert(!contact->numbers.empty());
|
|
for (auto number : contact->numbers) {
|
|
if (number.number.getEntered().size() > 0) {
|
|
tempContact = DBServiceAPI::MatchContactByPhoneNumber(application, number.number);
|
|
if (tempContact != nullptr) {
|
|
contact->ID = tempContact->ID;
|
|
contactAction = ContactAction::EditTemporary;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
contact->removeFromGroup(ContactsDB::temporaryGroupId());
|
|
}
|
|
|
|
// perform actual add/update operation
|
|
if (contactAction == ContactAction::Add) {
|
|
if (DBServiceAPI::ContactAdd(application, *contact) == false) {
|
|
LOG_ERROR("verifyAndSave failed to ADD contact");
|
|
return false;
|
|
}
|
|
}
|
|
else if (contactAction == ContactAction::Edit || contactAction == ContactAction::EditTemporary) {
|
|
std::unique_ptr<gui::SwitchData> data = std::make_unique<PhonebookItemData>(contact);
|
|
data->ignoreCurrentWindowOnStack = true;
|
|
|
|
contact->groups.erase(ContactsDB::temporaryGroupId());
|
|
|
|
if (DBServiceAPI::ContactUpdate(application, *contact) == false) {
|
|
LOG_ERROR("verifyAndSave failed to UPDATE contact");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
application->switchWindow(gui::name::window::main_window);
|
|
return true;
|
|
} // namespace gui
|
|
|
|
void PhonebookNewContact::showDialogDuplicatedNumber(const utils::PhoneNumber::View &duplicatedNumber)
|
|
{
|
|
DialogMetadata meta;
|
|
auto matchedContact = DBServiceAPI::MatchContactByPhoneNumber(application, duplicatedNumber);
|
|
auto oldContactRecord = (matchedContact != nullptr) ? *matchedContact : ContactRecord{};
|
|
|
|
if (contactAction == ContactAction::Add) {
|
|
contact->ID = oldContactRecord.ID;
|
|
}
|
|
|
|
meta.action = [=]() -> bool {
|
|
if (!DBServiceAPI::ContactUpdate(application, *contact)) {
|
|
LOG_ERROR("Contact id=%" PRIu32 " update failed", contact->ID);
|
|
return false;
|
|
}
|
|
application->switchWindow(gui::name::window::main_window);
|
|
return true;
|
|
};
|
|
std::string duplicatedNumberPhrase = utils::localize.get("app_phonebook_duplicate_numbers");
|
|
phonebookUtils::fillContactData(duplicatedNumberPhrase, oldContactRecord);
|
|
meta.text = duplicatedNumberPhrase;
|
|
meta.title = duplicatedNumber.getFormatted();
|
|
meta.icon = "info_big_circle_W_G";
|
|
application->switchWindow(gui::window::name::dialog_yes_no, std::make_unique<gui::DialogMetadataMessage>(meta));
|
|
}
|
|
|
|
void PhonebookNewContact::showDialogDuplicatedSpeedDialNumber()
|
|
{
|
|
auto contactRecordsPtr = DBServiceAPI::ContactGetBySpeeddial(application, contact->speeddial);
|
|
auto oldContactRecord = !contactRecordsPtr->empty() ? contactRecordsPtr->front() : ContactRecord{};
|
|
|
|
if (contactAction == ContactAction::Add) {
|
|
contact->ID = oldContactRecord.ID;
|
|
}
|
|
|
|
DialogMetadata metadata;
|
|
metadata.action = [=]() -> bool {
|
|
if (!DBServiceAPI::ContactUpdate(application, *contact)) {
|
|
LOG_ERROR("Contact id=%" PRIu32 " update failed", contact->ID);
|
|
return false;
|
|
}
|
|
application->switchWindow(gui::name::window::main_window);
|
|
return true;
|
|
};
|
|
std::string duplicatedSpeedDialPhrase = utils::localize.get("app_phonebook_duplicate_numbers");
|
|
phonebookUtils::fillContactData(duplicatedSpeedDialPhrase, oldContactRecord);
|
|
std::string duplicatedSpeedDialTitle = utils::localize.get("app_phonebook_duplicate_speed_dial_title");
|
|
phonebookUtils::fillContactData(duplicatedSpeedDialTitle, oldContactRecord);
|
|
metadata.text = duplicatedSpeedDialPhrase;
|
|
metadata.title = duplicatedSpeedDialTitle;
|
|
metadata.icon = "phonebook_empty_grey_circle_speed_dial";
|
|
metadata.iconText = contact->speeddial;
|
|
|
|
application->switchWindow(gui::window::name::dialog_yes_no_icon_txt,
|
|
std::make_unique<gui::DialogMetadataMessage>(metadata));
|
|
}
|
|
|
|
} // namespace gui
|