~aleteoryx/muditaos

cd34ad5ff37819fbcb8ba3078a827d4be533b899 — tomaszkrosnowski 4 years ago 25ba341
[EGD-6453] Warning when adding incorrect event

When adding to Calendar an event which is incorrect  (e.g. has empty
title or end which is sooner than start) warning window appears.
M image/assets/lang/English.json => image/assets/lang/English.json +2 -0
@@ 144,6 144,8 @@
  "app_calendar_all_day": "All day",
  "app_calendar_new_edit_event_start": "Start",
  "app_calendar_new_edit_event_end": "End",
  "app_calendar_event_error_dates": "The start date must be before\nthe end date",
  "app_calendar_event_error_empty_name": "Event name must not be empty",
  "app_calculator_title_main": "Calculator",
  "app_calculator_equals": "EQUALS",
  "app_calculator_decimal_separator": ".",

M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +15 -10
@@ 3,23 3,25 @@

#include "ApplicationCalendar.hpp"
#include "DialogMetadataMessage.hpp"
#include "windows/CalendarMainWindow.hpp"
#include "windows/DayEventsWindow.hpp"
#include "windows/CalendarEventsOptionsWindow.hpp"
#include "windows/AllEventsWindow.hpp"
#include "windows/EventDetailWindow.hpp"
#include "windows/NewEditEventWindow.hpp"
#include "windows/CustomRepeatWindow.hpp"
#include "windows/EventReminderWindow.hpp"
#include "NoEvents.hpp"
#include "Dialog.hpp"
#include <time/time_conversion.hpp>
#include <module-db/queries/calendar/QueryEventsAdd.hpp>

#include <application-calendar/windows/CalendarMainWindow.hpp>
#include <application-calendar/windows/DayEventsWindow.hpp>
#include <application-calendar/windows/CalendarEventsOptionsWindow.hpp>
#include <application-calendar/windows/AllEventsWindow.hpp>
#include <application-calendar/windows/EventDetailWindow.hpp>
#include <application-calendar/windows/NewEditEventWindow.hpp>
#include <application-calendar/windows/CustomRepeatWindow.hpp>
#include <application-calendar/windows/EventReminderWindow.hpp>
#include <module-apps/messages/DialogMetadataMessage.hpp>
#include <module-db/queries/calendar/QueryEventsAdd.hpp>
#include <service-db/DBServiceAPI.hpp>
#include <service-db/QueryMessage.hpp>
#include <service-db/DBNotificationMessage.hpp>

#include <time/time_conversion.hpp>

namespace app
{
    const std::map<Reminder, const char *> ApplicationCalendar::reminderOptions = {


@@ 143,6 145,9 @@ namespace app
        windowsFactory.attach(event_reminder_window, [](Application *app, const std::string &name) {
            return std::make_unique<gui::EventReminderWindow>(app, event_reminder_window);
        });
        windowsFactory.attach(gui::window::name::dialog_confirm, [](Application *app, const std::string &name) {
            return std::make_unique<gui::DialogConfirm>(app, name);
        });

        attachPopups(
            {gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes, gui::popup::ID::PhoneLock});

M module-apps/application-calendar/models/NewEditEventModel.cpp => module-apps/application-calendar/models/NewEditEventModel.cpp +88 -50
@@ 2,20 2,22 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "NewEditEventModel.hpp"
#include "application-calendar/widgets/NewEventCheckBoxWithLabel.hpp"
#include "application-calendar/widgets/TextWithLabelItem.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
#include "AppWindow.hpp"
#include <application-calendar/widgets/NewEventCheckBoxWithLabel.hpp>
#include <application-calendar/widgets/TextWithLabelItem.hpp>
#include <application-calendar/widgets/CalendarStyle.hpp>
#include <application-calendar/widgets/CalendarDateItem.hpp>
#include <application-calendar/widgets/CalendarTimeItem.hpp>
#include <application-calendar/widgets/SeveralOptionsItem.hpp>
#include "application-calendar/data/CalendarData.hpp"
#include "application-calendar/ApplicationCalendar.hpp"
#include "AppWindow.hpp"
#include <ListView.hpp>
#include <application-calendar/data/CalendarData.hpp>
#include <application-calendar/ApplicationCalendar.hpp>
#include <module-db/queries/calendar/QueryEventsAdd.hpp>
#include <module-db/queries/calendar/QueryEventsEdit.hpp>
#include <module-apps/messages/DialogMetadataMessage.hpp>

#include <service-db/DBServiceAPI.hpp>
#include <time/time_conversion.hpp>
#include <ListView.hpp>

NewEditEventModel::NewEditEventModel(app::Application *app) : application(app)
{}


@@ 126,55 128,91 @@ void NewEditEventModel::saveData(std::shared_ptr<EventsRecord> event, EventActio
        }
    }

    std::string errorMessage;
    if (!isDataCorrect(event, errorMessage)) {

        std::string windowTitle = (action == EventAction::Edit) ? utils::translate("app_calendar_edit_event_title")
                                                                : utils::translate("app_calendar_new_event_title");

        application->switchWindow(
            gui::window::name::dialog_confirm,
            gui::ShowMode::GUI_SHOW_INIT,
            std::make_unique<gui::DialogMetadataMessage>(gui::DialogMetadata{
                std::move(windowTitle), "emergency_W_G", std::move(errorMessage), "", [=]() -> bool {
                    application->returnToPreviousWindow();
                    return true;
                }}));

        return;
    }

    if (action == EventAction::Edit) {
        auto record = event.get();
        record->reminder_fired = TIME_POINT_INVALID;
        if (!record->title.empty()) {
            DBServiceAPI::GetQuery(
                application, db::Interface::Name::Events, std::make_unique<db::query::events::Edit>(*record));
        }
        auto rec  = std::make_unique<EventsRecord>(*record);
        auto data = std::make_unique<EventRecordData>(std::move(rec));
        application->switchWindow(style::window::calendar::name::details_window, std::move(data));
        saveEditData(event);
    }
    else {
        auto record = event.get();
        if (!record->title.empty()) {
            DBServiceAPI::GetQuery(
                application, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(*record));

            auto data       = std::make_unique<DayMonthData>();
            auto startDate  = TimePointToYearMonthDay(record->date_from);
            auto filterDate = TimePointFromYearMonthDay(startDate);
            std::string monthStr =
                utils::time::Locale::get_month(utils::time::Locale::Month(unsigned(startDate.month()) - 1));
            data->setData(std::to_string(unsigned(startDate.day())) + " " + monthStr, filterDate);

            if (application->getPrevWindow() == style::window::calendar::name::no_events_window) {
                auto app = dynamic_cast<app::ApplicationCalendar *>(application);
                assert(app != nullptr);
                if (app->getEquivalentToEmptyWindow() == EquivalentWindow::DayEventsWindow) {
                    app->popToWindow(gui::name::window::main_window);
                    app->switchWindow(style::window::calendar::name::day_events_window, std::move(data));
                }
                else if (app->getEquivalentToEmptyWindow() == EquivalentWindow::AllEventsWindow) {
                    app->popToWindow(gui::name::window::main_window);
                    app->switchWindow(style::window::calendar::name::all_events_window, std::move(data));
                }
            }
            else {
                if (application->getPrevWindow() == style::window::calendar::name::day_events_window) {
                    application->switchWindow(style::window::calendar::name::day_events_window, std::move(data));
                }
                application->returnToPreviousWindow();
            }
        saveNewData(event);
    }

    clearData();
}

void NewEditEventModel::saveNewData(std::shared_ptr<EventsRecord> event)
{
    DBServiceAPI::GetQuery(application, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(*event));

    auto data            = std::make_unique<DayMonthData>();
    auto startDate       = TimePointToYearMonthDay(event->date_from);
    auto filterDate      = TimePointFromYearMonthDay(startDate);
    std::string monthStr = utils::time::Locale::get_month(utils::time::Locale::Month(unsigned(startDate.month()) - 1));
    data->setData(std::to_string(unsigned(startDate.day())) + " " + monthStr, filterDate);

    if (application->getPrevWindow() == style::window::calendar::name::no_events_window) {
        auto app = dynamic_cast<app::ApplicationCalendar *>(application);
        assert(app != nullptr);
        if (app->getEquivalentToEmptyWindow() == EquivalentWindow::DayEventsWindow) {
            app->popToWindow(gui::name::window::main_window);
            app->switchWindow(style::window::calendar::name::day_events_window, std::move(data));
        }
        else {
            LOG_WARN("Title event is empty! Returning to previous window.");
            application->returnToPreviousWindow();
        else if (app->getEquivalentToEmptyWindow() == EquivalentWindow::AllEventsWindow) {
            app->popToWindow(gui::name::window::main_window);
            app->switchWindow(style::window::calendar::name::all_events_window, std::move(data));
        }
    }
    clearData();
    else {
        if (application->getPrevWindow() == style::window::calendar::name::day_events_window) {
            application->switchWindow(style::window::calendar::name::day_events_window, std::move(data));
        }
        application->returnToPreviousWindow();
    }
}

void NewEditEventModel::saveEditData(std::shared_ptr<EventsRecord> event)
{
    event->reminder_fired = TIME_POINT_INVALID;
    if (!event->title.empty()) {
        DBServiceAPI::GetQuery(
            application, db::Interface::Name::Events, std::make_unique<db::query::events::Edit>(*event));
    }
    auto rec  = std::make_unique<EventsRecord>(*event);
    auto data = std::make_unique<EventRecordData>(std::move(rec));
    application->switchWindow(style::window::calendar::name::details_window, std::move(data));
}

bool NewEditEventModel::isDataCorrect(std::shared_ptr<EventsRecord> event, std::string &message)
{
    if (event->title.empty()) {
        LOG_WARN("Event data has empty title!");
        message = utils::translate("app_calendar_event_error_empty_name");
        return false;
    }

    if (event->date_from > event->date_till) {
        LOG_WARN("Event data has wrong dates!");
        message = utils::translate("app_calendar_event_error_dates");
        return false;
    }

    return true;
}

void NewEditEventModel::createTimeItems()

M module-apps/application-calendar/models/NewEditEventModel.hpp => module-apps/application-calendar/models/NewEditEventModel.hpp +10 -0
@@ 44,8 44,18 @@ class NewEditEventModel : public app::InternalModel<gui::CalendarListItem *>, pu
    void loadRepeat(const std::shared_ptr<EventsRecord> &record);
    void saveData(std::shared_ptr<EventsRecord> event, EventAction action);

    /// Check if the event data is correct.
    /// @param event event to be checked
    /// @param message string to write the error message in case event data is incorrect
    /// @return true if event data is correct or false elseway
    bool isDataCorrect(std::shared_ptr<EventsRecord> event, std::string &message);

    [[nodiscard]] unsigned int getMinimalItemHeight() const override;
    [[nodiscard]] unsigned int requestRecordsCount() override;
    gui::ListItem *getItem(gui::Order order) override;
    void requestRecords(const uint32_t offset, const uint32_t limit) override;

  protected:
    void saveNewData(std::shared_ptr<EventsRecord> event);
    void saveEditData(std::shared_ptr<EventsRecord> event);
};